重學STM32 (十)之CAN通訊 二

2021-09-30 01:15:07 字數 4958 閱讀 2809

目錄

can協議是非常難的,但是在stm32中卻是簡單的,只需要我們配置暫存器即可,,,即使這樣,我在學習的時候也遇到了許多困難

1、開時鐘,不用說

2、設定gpio口,,can_tx復用推挽輸出,can_rx上拉或浮空輸入

3、can初始化了,分三步

/*對can初始化*/

can1->mcr |= 1 << 15; //軟復位

can1->mcr &= ~(1 << 1);    //退出睡眠模式 (鬱悶,忘退出睡眠模式了,折騰了半天)

can1->mcr |= 1 << 0; //設定初始化模式 必須

while(!(can1->msr & 1 << 0)); //等待確認初始化

can1->mcr |= 0 << 7; //禁止時間觸發模式

can1->mcr |= 0 << 6; //禁止自動離線

can1->mcr |= 0 << 5; //禁止自動喚醒

can1->mcr |= 1 << 4; //報文只傳送一次,禁止自動重傳

can1->mcr |= 0 << 2; //優先順序由報文的識別符號決定

/* 設定can位時序*/

can1->btr &= 0x00000000; //

can1->btr |= mode << 30; //正常模式(0)或環迴模式(1)可見can_btr暫存器

can1->btr |= sjw << 24; //設定sjw

can1->btr |= ts2 << 20; //

can1->btr |= ts1 << 16; //

can1->btr |= brp << 0;

can1->mcr &= ~(1 << 0); //退出初始化

while(can1->msr & 1 << 0); //確認退出初始化

/* 設定過濾器組 */

can1->fmr |= 1 << 0; //過濾器組設定在初始化模式(記得必須設定初始化模式)

can1->fa1r &= ~(1 << 0); //過濾器禁用

can1->fm1r &= ~(1<< 0); //過濾器組工作在識別符號遮蔽位模式

can1->fs1r |= 1<<0; //過濾器組位寬為32位

can1->ffa1r &= ~(1 << 0); //關聯到fifo0

can1->sfilterregister[0].fr1 = 0x00000000; //全都為0 ,什麼資料都接受

can1->sfilterregister[0].fr2 = 0x00000000;

can1->fa1r |= 1 << 0; //啟用過濾器

//退出濾波器初始化模式 (記得要退出,否則傳送成功卻接受不到,不要問我為什麼這麼清楚。。。)

can1->fmr &= 0 << 0;

4、傳送訊息函式和得到傳送狀態函式

見下寫程式

u8 can_tx_msg(u8 ide, u32 id, u8 rtr, u8 len, u8 *data)

u8 can_tx_statt(u8 mbox)

5、接收函式

// 引數要用指標,開始我ide沒用指標,在其他函式呼叫這個函式ide的值是不確定的

void can_rx_msg(u8 *ide, u32* id, u8* rtr, u8* len, u8 *data, u8 fifox)

else

*rtr = (can1->sfifomailbox[fifox].rir & 1<<1)>>1;

*len = can1->sfifomailbox[fifox].rdtr & 0x0f;

//接收資料

data[0]=can1->sfifomailbox[fifox].rdlr&0xff;

data[1]=(can1->sfifomailbox[fifox].rdlr>>8)&0xff;

data[2]=(can1->sfifomailbox[fifox].rdlr>>16)&0xff;

data[3]=(can1->sfifomailbox[fifox].rdlr>>24)&0xff;

data[4]=can1->sfifomailbox[fifox].rdhr&0xff;

data[5]=(can1->sfifomailbox[fifox].rdhr>>8)&0xff;

data[6]=(can1->sfifomailbox[fifox].rdhr>>16)&0xff;

data[7]=(can1->sfifomailbox[fifox].rdhr>>24)&0xff;

if(fifox==0)can1->rf0r|=0x20;//釋放fifo0郵箱

else if(fifox==1)can1->rf1r|=0x20;//釋放fifo1郵箱

}

只有一塊開發板,只能測試回環模式

main.c

主函式

u8 txbuff[8] ;

int main()}}

time++;

delay_ms(100);

if(time>10)

}

}

can.c

#include "can.h"

//#include "stm32f10x.h"

#include "sys.h"

#define can_int_enable 0

void can_init(u8 sjw, u8 ts2, u8 ts1,u16 brp, u8 mode)

// ide 0:標準幀 1:擴充套件幀

// id 標識id

// rtr 0:資料幀 1:遠端幀

// len 資料長度

// *data 指向要傳送資料的指標

u8 can_tx_msg(u8 ide, u32 id, u8 rtr, u8 len, u8 *data)

/*為擴充套件id時*/

if(ide == 1)

can1->stxmailbox[mbox].tir = 0;

can1->stxmailbox[mbox].tir |= ide << 2; //

can1->stxmailbox[mbox].tir |= id ; //

can1->stxmailbox[mbox].tir &= ~(1<<1); //

can1->stxmailbox[mbox].tdtr |= len&0xf; //

can1->stxmailbox[mbox].tdlr =((u32)data[0]) | ((u32)data[1]<<8) | ((u32)data[2]<<16) | ((u32)data[3]<<24);

can1->stxmailbox[mbox].tdhr =((u32)data[4]) | ((u32)data[5]<<8) | ((u32)data[6]<<16) | ((u32)data[7]<<24);

can1->stxmailbox[mbox].tir |= 1 << 0;

return mbox ;}

//判斷傳送是成功

//state = 7成功

u8 can_tx_statt(u8 mbox)

return state ;

}//得到在fifo0/fifo1中接收到的報文個數.

//fifox:0/1.fifo編號;

//返回值:fifo0/fifo1中的報文個數.

u8 can_msg_pend(u8 fifox)

// 引數同上

void can_rx_msg(u8 *ide, u32* id, u8* rtr, u8* len, u8 *data, u8 fifox)

else

*rtr = (can1->sfifomailbox[fifox].rir & 1<<1)>>1;

*len = can1->sfifomailbox[fifox].rdtr & 0x0f;

//接收資料

data[0]=can1->sfifomailbox[fifox].rdlr&0xff;

data[1]=(can1->sfifomailbox[fifox].rdlr>>8)&0xff;

data[2]=(can1->sfifomailbox[fifox].rdlr>>16)&0xff;

data[3]=(can1->sfifomailbox[fifox].rdlr>>24)&0xff;

data[4]=can1->sfifomailbox[fifox].rdhr&0xff;

data[5]=(can1->sfifomailbox[fifox].rdhr>>8)&0xff;

data[6]=(can1->sfifomailbox[fifox].rdhr>>16)&0xff;

data[7]=(can1->sfifomailbox[fifox].rdhr>>24)&0xff;

if(fifox==0)can1->rf0r|=0x20;//釋放fifo0郵箱

else if(fifox==1)can1->rf1r|=0x20;//釋放fifo1郵箱 }//

u8 can_send_msg(u8* data, u8 len)

//返回0 接收失敗

u8 can_receive_msg(u8* data)

已在本地測試ok。

重學STM32 (九)之CAN通訊(一)

目錄can 是 controller area network的縮寫 以下稱為 can 是 iso 國際標準化的序列通訊協議。1 主動錯誤狀態 主動錯誤狀態是可以正常參加匯流排通訊的狀態。處於主動錯誤狀態的單元檢測出錯誤時,輸出主動錯誤標誌。2 被動錯誤狀態 被動錯誤狀態是易引起錯誤的狀態。處於被動...

STM32之USART串列埠通訊《二》

一 簡單demo 通過232串列埠,與上位機進行通訊。首先保證微控制器232串列埠與電腦的串列埠介面相連,當然電腦是usb介面,其實usb介面的實質也是串列埠。我們實現上位機傳送乙個16進製制的資料,微控制器接受到資料後顯示,並且2倍傳送給上位機。1 usart init 串列埠初始化 void u...

STM32之串列埠通訊

一 rs232通訊協議 1 概念 個人計算機上的通訊介面之一,由電子工業協會 electronic industries association,eia 所制定的非同步傳輸標準介面。2 電氣特性 邏輯1 mark 3v 15v 邏輯0 space 3 15v 3 介面 實現全雙工非同步通訊只需要三根...