0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

STM32入門學(xué)習(xí)筆記之CAN通信實驗4

jf_78858299 ? 來源:滑小稽筆記 ? 作者:電子技術(shù)園地 ? 2023-02-16 14:37 ? 次閱讀

18.3 實驗例程

實驗內(nèi)容:利用CAN的回環(huán)模式進(jìn)行數(shù)據(jù)收發(fā)測試,通信速率500Kbps。

(1)創(chuàng)建can.h文件,并輸入以下代碼。

/*********************************************************************************************************
            CAN    通    信    驅(qū)    動    文    件
*********************************************************************************************************/
#ifndef _CAN_H_
#define _CAN_H_


#include "sys.h"                
/*********************************************************************************************************
                  函    數(shù)    列    表
*********************************************************************************************************/
u8 CAN_Init( u8 tsjw, u8 tbs2, u8 tbs1, u16 brp, u8 mode ) ;                      //CAN初始化
u8 CAN_Tx_Msg( u32 id, u8 ide, u8 rtr, u8 len, u8 *dat ) ;                        //CAN發(fā)送數(shù)據(jù)
void CAN_Rx_Msg( u8 fifox, u32 *id, u8 *ide, u8 *rtr, u8 *len, u8 *dat ) ;                //CAN接收數(shù)據(jù)


#endif

(2)創(chuàng)建can.c文件,并輸入以下代碼。

/*********************************************************************************************************
            CAN    通    信    驅(qū)    動    程    序
*********************************************************************************************************/
#include "can.h"
/*******************************************************
Name    :CAN_Mode_Init
Function  :CAN初始化
Paramater  :
      tsjw:重新同步跳躍時間單元.范圍:1~3
      tbs2:時間段2的時間單元.范圍:1~8
      tbs1:時間段1的時間單元.范圍:1~16
      brp:波特率分頻器.范圍:1~1024
      mode:工作模式
        0:普通模式
        1:回環(huán)模式
Return    :
      0:成功
      其他:失敗
*******************************************************/
u8 CAN_Init( u8 tsjw, u8 tbs2, u8 tbs1, u16 brp, u8 mode )
{
  u16 i=0;
   if( ( tsjw==0 )||( tbs2==0 )||( tbs1==0 )||( brp==0 ) )
    return 1 ;
  //先減去1.再用于設(shè)置
  tsjw -= 1 ;
  tbs2 -= 1 ;
  tbs1 -= 1 ;
  brp -= 1 ;


  RCC->APB2ENR |= 1<<2 ;                                        //使能PA時鐘
  GPIOA->CRH &= 0xFFF00FFF ;
  GPIOA->CRH |= 0x000B8000 ;
    GPIOA->ODR |= 3<<11 ;
  RCC->APB1ENR |= 1<<25 ;                                        //使能CAN時鐘
  CAN1->MCR = 0x0000 ;                                        //退出睡眠模式
  CAN1->MCR |= 1<<0 ;                                          //請求CAN進(jìn)入初始化模式
  while( ( CAN1->MSR&0x01 )==0 )
  {
    i ++ ;
    if( i>100 )
      return 2 ;                                          //進(jìn)入初始化模式失敗
  }
  CAN1->MCR |= 0<<7 ;                                          //非時間觸發(fā)通信模式
  CAN1->MCR |= 0<<6 ;                                          //軟件自動離線管理
  CAN1->MCR |= 0<<5 ;                                          //睡眠模式通過軟件喚醒
  CAN1->MCR |= 1<<4 ;                                          //禁止報文自動傳送
  CAN1->MCR |= 0<<3 ;                                          //報文不鎖定,新的覆蓋舊的
  CAN1->MCR |= 0<<2 ;                                          //優(yōu)先級由報文標(biāo)識符決定
  CAN1->BTR = 0x00000000 ;                                      //清除原來的設(shè)置
  CAN1->BTR |= mode<<30 ;                                        //模式設(shè)置
  CAN1->BTR |= tsjw<<24 ;                                        //重新同步跳躍寬度(Tsjw)為tsjw+1個時間單位
  CAN1->BTR |= tbs2<<20 ;                                        //Tbs2=tbs2+1個時間單位
  CAN1->BTR |= tbs1<<16 ;                                        //Tbs1=tbs1+1個時間單位
  CAN1->BTR |= brp<<0 ;                                        //分頻系數(shù)(Fdiv)為brp+1
  CAN1->MCR &= ~( 1<<0 ) ;                                      //請求CAN退出初始化模式
  while( ( CAN1->MSR&0x01 )!=0 )
  {
    i ++ ;
    if( i>0xFFF0 )
      return 3 ;                                          //退出初始化模式失敗
  }
  //過濾器初始化
  CAN1->FMR |= 1<<0 ;                                          //過濾器組工作在初始化模式
  CAN1->FA1R &= ~( 1<<0 ) ;                                      //過濾器0不激活
  CAN1->FS1R |= 1<<0 ;                                        //過濾器位寬為32位
  CAN1->FM1R |= 0<<0 ;                                        //過濾器0工作在標(biāo)識符屏蔽位模式
  CAN1->FFA1R |= 0<<0 ;                                        //過濾器0關(guān)聯(lián)到FIFO0
  CAN1->sFilterRegister[ 0 ].FR1 = 0x00000000 ;                            //32位ID
  CAN1->sFilterRegister[ 0 ].FR2 = 0x00000000 ;                            //32位MASK
  CAN1->FA1R |= 1<<0 ;                                        //激活過濾器0
  CAN1->FMR &= 0<<0 ;                                          //過濾器組進(jìn)入正常模式
  return 0 ;
}
/*******************************************************
Name    :CAN_Tx_Msg
Function  :CAN發(fā)送數(shù)據(jù)
Paramater  :
      id:標(biāo)準(zhǔn)ID(11位)/擴(kuò)展ID(11位+18位)
      ide:ID類型
        0:標(biāo)準(zhǔn)幀
        1:擴(kuò)展幀
      rtr:數(shù)據(jù)類型
        0:數(shù)據(jù)幀
        1:遠(yuǎn)程幀
      len:要發(fā)送的數(shù)據(jù)長度
      *dat:數(shù)據(jù)指針
Return    :
      0~3:郵箱編號
      0xFF:無有效郵箱
*******************************************************/
u8 CAN_Tx_Msg( u32 id, u8 ide, u8 rtr, u8 len, u8 *dat )
{
  u16 i;
  u8 mbox, sta=0 ;
  //郵箱0為空
  if( CAN1->TSR&( 1<<26 ) )
    mbox = 0 ;
  //郵箱1為空
  else if( CAN1->TSR&( 1<<27 ) )
    mbox = 1 ;
  //郵箱2為空
  else if( CAN1->TSR&( 1<<28 ) )
    mbox = 2 ;
  //無空郵箱,無法發(fā)送
  else
    return 0xFF ;
  CAN1->sTxMailBox[ mbox ].TIR = 0 ;                                  //清除之前的設(shè)置
  //標(biāo)準(zhǔn)幀
  if( ide==0 )
  {
    id &= 0x7FF ;                                          //取低11位stdid
    id <<= 21 ;
  }
  //擴(kuò)展幀
  else
  {
    id &= 0x1FFFFFFF ;                                        //取低32位extid
    id <<= 3 ;
  }
  CAN1->sTxMailBox[ mbox ].TIR |= id ;
  CAN1->sTxMailBox[ mbox ].TIR |= ide<<2 ;
  CAN1->sTxMailBox[ mbox ].TIR |= rtr<<1 ;
  len &= 0x0F ;                                            //得到低四位
  CAN1->sTxMailBox[ mbox ].TDTR &= 0xFFFFFFF0 ;
  CAN1->sTxMailBox[ mbox ].TDTR |= len ;                                //設(shè)置DLC
  //待發(fā)送數(shù)據(jù)存入郵箱
  CAN1->sTxMailBox[ mbox ].TDHR = ( ( (u32)dat[7]<<24 )|( (u32)dat[6]<<16 )|( (u32)dat[5]<<8 )|( (u32)dat[4] ) ) ;
  CAN1->sTxMailBox[ mbox ].TDLR = ( ( (u32)dat[3]<<24 )|( (u32)dat[2]<<16 )|( (u32)dat[1]<<8 )|( (u32)dat[0] ) ) ;
  CAN1->sTxMailBox[ mbox ].TIR |= 1<<0 ;                                //請求發(fā)送郵箱數(shù)據(jù)
  //獲取發(fā)送狀態(tài)
  while( ( sta!=0x07 )&&( i<0xFFF ) )
  {
    i ++ ;
    switch( mbox )
    {
      //郵箱0
      case 0:
        sta |= CAN1->TSR&( 1<<0 ) ;                                //RQCP0
        sta |= CAN1->TSR&( 1<<1 ) ;                                //TXOK0
        sta |= CAN1->TSR&( 1<<26 )>>24 ;                            //TME0
        break;
      //郵箱1
      case 1:
        sta |= CAN1->TSR&( 1<<8 )>>8 ;                              //RQCP1
        sta |= CAN1->TSR&( 1<<9 )>>8 ;                              //TXOK1
        sta |= CAN1->TSR&( 1<<27 )>>25 ;                            //TME1
        break;
      //郵箱2
      case 2:
        sta |= CAN1->TSR&( 1<<16 )>>16 ;                            //RQCP2
        sta |= CAN1->TSR&( 1<<17 )>>16 ;                            //TXOK2
        sta |= CAN1->TSR&( 1<<28 )>>26 ;                            //TME2
        break;
      //郵箱號不對
      default:
        sta = 0x05 ;
      break ;
    }
  }
  if( i==0xFFF )
    mbox = 0xFF ;
  return mbox ;
}
/*******************************************************
Name    :CAN_Rx_Msg
Function  :CAN接收數(shù)據(jù)
Paramater  :
      fifox:郵箱號
      id:標(biāo)準(zhǔn)ID(11位)/擴(kuò)展ID(11位+18位)
      ide:ID類型
        0:標(biāo)準(zhǔn)幀
        1:擴(kuò)展幀
      rtr:數(shù)據(jù)類型
        0:數(shù)據(jù)幀
        1:遠(yuǎn)程幀
      len:要發(fā)送的數(shù)據(jù)長度
      *dat:數(shù)據(jù)指針
Return    :None
*******************************************************/
void CAN_Rx_Msg( u8 fifox, u32 *id, u8 *ide, u8 *rtr, u8 *len, u8 *dat )
{
  if( ( fifox==0 )&&( ( CAN1->RF0R&0x03 )==0 ) )
    len = 0 ;
  else if( ( fifox==1 )&&( ( CAN1->RF1R&0x03 )==0 ) )
    len = 0 ;
  else
  {
    //接收數(shù)據(jù)
    *ide = CAN1->sFIFOMailBox[ fifox ].RIR&0x04 ;                          //得到標(biāo)識符選擇位的值
    if( *ide==0 )
      *id = CAN1->sFIFOMailBox[ fifox ].RIR>>21 ;                          //標(biāo)準(zhǔn)標(biāo)識符
    else
      *id = CAN1->sFIFOMailBox[ fifox ].RIR>>3 ;                          //擴(kuò)展標(biāo)識符
    *rtr = CAN1->sFIFOMailBox[ fifox ].RIR&0x02 ;                          //得到遠(yuǎn)程發(fā)送請求值
    *len = CAN1->sFIFOMailBox[ fifox ].RDTR&0x0F ;                          //得到DLC
    dat[ 0 ] = CAN1->sFIFOMailBox[ fifox ].RDLR&0xFF ;
    dat[ 1 ] = ( CAN1->sFIFOMailBox[ fifox ].RDLR>>8 )&0xFF ;
    dat[ 2 ] = ( CAN1->sFIFOMailBox[ fifox ].RDLR>>16 )&0xFF ;
    dat[ 3 ] = ( CAN1->sFIFOMailBox[ fifox ].RDLR>>24 )&0xFF ;
    dat[ 4 ] = CAN1->sFIFOMailBox[ fifox ].RDHR&0xFF ;
    dat[ 5 ] = ( CAN1->sFIFOMailBox[ fifox ].RDHR>>8 )&0xFF ;
    dat[ 6 ] = ( CAN1->sFIFOMailBox[ fifox ].RDHR>>16 )&0xFF ;
    dat[ 7 ] = ( CAN1->sFIFOMailBox[ fifox ].RDHR>>24 )&0xFF ;
    if( fifox==0 )
      CAN1->RF0R |= 0x20 ;                                    //釋放FIFO0郵箱
    else if( fifox==1 )
      CAN1->RF1R |= 0x20 ;                                    //釋放FIFO1郵箱
  }
}

(3)創(chuàng)建1.c文件,并輸入以下代碼。

#include "sys.h"
#include "delay.h"
#include "usart1.h"
#include "can.h"


int main()
{
  u32 id;
  u8 ide, rtr, len, canbuf[ 8 ] ;
  STM32_Clock_Init( 9 ) ;                                        //STM32時鐘初始化
  SysTick_Init( 72 ) ;                                        //SysTick初始化
  USART1_Init( 72, 115200 ) ;                                      //初始化串口1波特率115200
  CAN_Init( 1, 8, 9, 4, 1 ) ;                                      //CAN初始化
  CAN_Tx_Msg( 0x12, 0, 0, 8, "CAN Test" ) ;                              //發(fā)送8個字節(jié)
  while( 1 )
  {
    CAN_Rx_Msg( 0, &id, &ide, &rtr, &len, canbuf ) ;                        //讀取數(shù)據(jù)
  }
}
聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 通信協(xié)議
    +關(guān)注

    關(guān)注

    28

    文章

    900

    瀏覽量

    40351
  • 數(shù)據(jù)傳輸
    +關(guān)注

    關(guān)注

    9

    文章

    1928

    瀏覽量

    64723
  • CAN
    CAN
    +關(guān)注

    關(guān)注

    57

    文章

    2762

    瀏覽量

    464014
收藏 人收藏

    評論

    相關(guān)推薦

    介紹一下stm32F103C8T6的can總線通信實驗

    本篇文章介紹一下stm32F103C8T6的can總線通信實驗需要兩塊stm32F103C8T6板子can
    發(fā)表于 08-19 06:29

    串口通信實驗分享

    實驗四、串口通信實驗? 自律學(xué)習(xí)堅強(qiáng) ,拒絕迷茫。作者:行走的皮卡丘時間:2021/4/4喜歡就去追,這個紅燈等不到,說不定下一個紅燈等到了
    發(fā)表于 01-14 09:08

    CAN通信實驗報文對象的FIFO緩沖器應(yīng)用

    關(guān)鍵詞 CAN報文對象的FIFO模式應(yīng)用摘 要 CAN通信實驗
    發(fā)表于 11-07 14:18 ?33次下載

    ALIENTEK_MINISTM32_實驗19_無線通信實驗

    ALIENTEK MINISTM32 實驗19 無線通信實驗,很好的資料,快來下載吧
    發(fā)表于 02-19 11:40 ?12次下載

    CAN通信實驗

    CAN通信實驗
    發(fā)表于 03-30 16:48 ?0次下載

    STM32各模塊學(xué)習(xí)筆記

    ..........................................................4 STM32筆記STM3
    發(fā)表于 11-30 03:32 ?3172次閱讀

    STM32學(xué)習(xí)筆記--CAN

    目錄:一、CAN通信原理1.CAN通信簡介2.CAN通信優(yōu)點3.
    發(fā)表于 11-19 12:21 ?86次下載
    <b class='flag-5'>STM32</b><b class='flag-5'>學(xué)習(xí)</b><b class='flag-5'>筆記</b>--<b class='flag-5'>CAN</b>

    STM32CubMX自學(xué)筆記(七)—CAN通信實驗

    STM32CubMX自學(xué)筆記(七)—CAN通信實驗主要介紹由于項目需求要用到CAN通信協(xié)議,因此
    發(fā)表于 12-04 18:21 ?11次下載
    <b class='flag-5'>STM32</b>CubMX自學(xué)<b class='flag-5'>筆記</b>(七)—<b class='flag-5'>CAN</b><b class='flag-5'>通信實驗</b>

    Can通信接口學(xué)習(xí)筆記

    Can通信接口學(xué)習(xí)筆記
    發(fā)表于 12-08 16:36 ?26次下載
    <b class='flag-5'>Can</b><b class='flag-5'>通信</b>接口<b class='flag-5'>學(xué)習(xí)</b><b class='flag-5'>筆記</b>

    16 . USART 串口通信實驗

    USART 串口通信實驗我們知道STM32F1 內(nèi)部含有非常多的通信接口,我們就來學(xué)習(xí)下USART 串口通信。要實現(xiàn)的功能是:
    發(fā)表于 12-20 19:22 ?20次下載
    16 . USART 串口<b class='flag-5'>通信實驗</b>

    STM32 串口通信實驗

    stm32串口通信實驗UART通信實驗(通用異步收發(fā)器)UART串口通信原理:UART的通信過程實驗
    發(fā)表于 12-20 19:26 ?15次下載
    <b class='flag-5'>STM32</b> 串口<b class='flag-5'>通信實驗</b>

    實驗四、串口通信實驗

    實驗四、串口通信實驗? 自律 學(xué)習(xí)
    發(fā)表于 01-14 10:09 ?2次下載
    <b class='flag-5'>實驗</b>四、串口<b class='flag-5'>通信實驗</b>

    STM32入門學(xué)習(xí)筆記CAN通信實驗1

    CAN是Controller Area Network的縮寫,最初是專門用于汽車網(wǎng)絡(luò)的通信協(xié)議,與485協(xié)議相似,CAN也是一種2線制,采用兩根線的電壓差進(jìn)行數(shù)據(jù)傳輸?shù)膮f(xié)議,隨著CAN
    的頭像 發(fā)表于 02-16 14:37 ?1802次閱讀
    <b class='flag-5'>STM32</b><b class='flag-5'>入門</b><b class='flag-5'>學(xué)習(xí)</b><b class='flag-5'>筆記</b><b class='flag-5'>之</b><b class='flag-5'>CAN</b><b class='flag-5'>通信實驗</b>1

    STM32入門學(xué)習(xí)筆記CAN通信實驗2

    CAN是Controller Area Network的縮寫,最初是專門用于汽車網(wǎng)絡(luò)的通信協(xié)議,與485協(xié)議相似,CAN也是一種2線制,采用兩根線的電壓差進(jìn)行數(shù)據(jù)傳輸?shù)膮f(xié)議,隨著CAN
    的頭像 發(fā)表于 02-16 14:37 ?1774次閱讀

    STM32入門學(xué)習(xí)筆記CAN通信實驗3

    CAN是Controller Area Network的縮寫,最初是專門用于汽車網(wǎng)絡(luò)的通信協(xié)議,與485協(xié)議相似,CAN也是一種2線制,采用兩根線的電壓差進(jìn)行數(shù)據(jù)傳輸?shù)膮f(xié)議,隨著CAN
    的頭像 發(fā)表于 02-16 14:37 ?971次閱讀