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
+關(guān)注
關(guān)注
57文章
2762瀏覽量
464014
發(fā)布評論請先 登錄
相關(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
ALIENTEK_MINISTM32_實驗19_無線通信實驗
ALIENTEK MINISTM32 實驗19 無線通信實驗,很好的資料,快來下載吧
發(fā)表于 02-19 11:40
?12次下載
STM32各模塊學(xué)習(xí)筆記
..........................................................4 STM32筆記之四 STM3
發(fā)表于 11-30 03:32
?3172次閱讀
STM32CubMX自學(xué)筆記(七)—CAN通信實驗
STM32CubMX自學(xué)筆記(七)—CAN通信實驗主要介紹由于項目需求要用到CAN通信協(xié)議,因此
發(fā)表于 12-04 18:21
?11次下載
16 . USART 串口通信實驗
USART 串口通信實驗我們知道STM32F1 內(nèi)部含有非常多的通信接口,我們就來學(xué)習(xí)下USART 串口通信。要實現(xiàn)的功能是:
發(fā)表于 12-20 19:22
?20次下載
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
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
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
評論