stm32CAN通信代码

发布者:平静宁静最新更新时间:2024-08-26 来源: cnblogs关键字:stm32  CAN通信 手机看文章 扫描二维码
随时随地手机看文章

最近做项目需要用到can通信,这里分享一下自己的can通信学习代码,我使用的是正点原子的精英开发板,参考的资料也是正点原子的库函数指南,此外我也看完了can入门手册(21ic电子网可以下载到),对can通信原理了解了不少,can的内容还是很多的,这里我也不说原理,毕竟内容太多,只分享一下自己的代码,本来是跟着正点原子的例程走的,结果我的tft屏幕坏了(特容易坏),而且自己也只有一块开发板,没有办法,就仿真吧,(插一条:仿真来找小虫子简直不要太爽,我后面分享一下自己用仿真的一些小经验吧),学习32后面基本上要用到按键和LED,建议大家只看原理图自己写一遍,有自己的代码,方便以后调用,显示屏也是OLED和TFT两个在后面的代码调试中结合仿真器可以很快解决一些看起来无从下手的代码。

不说太多,直接上can的代码。


配置的基本流程很容易理解,第一步配置IO口,二、can初始化。三、filter(过滤器初始化)。这三个配置好之后,再封装两个函数发送和接收函数就可以了,接收的话也可以使用接收终端来接收,当FIFO里面有数据时产生标志,进入中断处理数据。


配置IO口:


RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);

RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1,ENABLE);


gpio.GPIO_Mode=GPIO_Mode_IPU;

gpio.GPIO_Pin=GPIO_Pin_11;

GPIO_Init(GPIOA,&gpio);


gpio.GPIO_Mode=GPIO_Mode_AF_PP;

gpio.GPIO_Pin=GPIO_Pin_12;

gpio.GPIO_Speed=GPIO_Speed_50MHz;

GPIO_Init(GPIOA,&gpio);

can初始化:


//can初始化

can.CAN_TTCM=DISABLE;//以下为枚举类型

can.CAN_ABOM=DISABLE;

can.CAN_AWUM=DISABLE;

can.CAN_RFLM=DISABLE;

can.CAN_NART=ENABLE;

can.CAN_TXFP=DISABLE;


can.CAN_Mode=CAN_Mode_LoopBack;//模式选择

//波特率配置,该计算公式在can入门手册里面有不多说(21ic电子网可以下载到)

can.CAN_BS1=CAN_BS1_8tq;

can.CAN_BS2=CAN_BS2_7tq;

can.CAN_Prescaler=5;

can.CAN_SJW=CAN_SJW_1tq;

CAN_Init(CAN1,&can);

filter配置:


//过滤器配置

filter.CAN_FilterIdHigh=0x0000;//id配置

filter.CAN_FilterIdLow=0x0000;

filter.CAN_FilterMaskIdHigh=0x0000;

filter.CAN_FilterMaskIdLow=0x0000;


filter.CAN_FilterFIFOAssignment=CAN_Filter_FIFO0; //关联到FIFOo

filter.CAN_FilterNumber=0;

filter.CAN_FilterMode=CAN_FilterMode_IdMask; //模式选择

filter.CAN_FilterScale=CAN_FilterScale_32bit;//单32位还是双16位选择

filter.CAN_FilterActivation=ENABLE;

CAN_FilterInit(&filter);

发送信息函数:


u8 can_send(u8 *msg,u8 len){

u8 mbox;

u16 i=0;

CanTxMsg TX;//发送ID

TX.StdId=0X12;

TX.ExtId=0x12;

TX.DLC=len;//发送长度

TX.IDE=CAN_Id_Standard; 

TX.RTR=CAN_RTR_Data;

for(i=0;iTX.Data[i]=msg[i];//数据参数传递

mbox=CAN_Transmit(CAN1,&TX);

i=0;

while((CAN_TransmitStatus(CAN1,mbox)!=CAN_TxStatus_Ok)&&(i<0xfff))i++;

if(i>=0xfff)

return 1;

return 0;

}

接收信息函数:


u8 can_rec(u8 *buf)

{

u32 i;

CanRxMsg RxMessage;

if( CAN_MessagePending(CAN1,CAN_FIFO0)==0)return 0; //没有接收到数据,直接退出 

CAN_Receive(CAN1, CAN_FIFO0, &RxMessage);//读取数据

for(i=0;i<8;i++)

buf[i]=RxMessage.Data[i];  

return RxMessage.DLC;

}

//接受中断配置:

我没有使能,使参考时要注意一下


CAN_ITConfig(CAN1,CAN_IT_FMP0,ENABLE);

nvic.NVIC_IRQChannel=USB_LP_CAN1_RX0_IRQn;

nvic.NVIC_IRQChannelCmd=DISABLE;

nvic.NVIC_IRQChannelPreemptionPriority=1;

nvic.NVIC_IRQChannelSubPriority=0;

NVIC_Init(&nvic);

当然还有接收中断:


void USB_LP_CAN1_RX0_IRQHandler(void)

{

CanRxMsg RxMessage;

int i=0;

CAN_Receive(CAN1, 0, &RxMessage);

for(i=0;i<8;i++)

printf('rxbuf[%d]:%drn',i,RxMessage.Data[i]);

}

主函数

现象:KEY0按下发送数据第一位为‘1’,发送成功红灯亮,接收成功且判断第一位为‘1’则亮绿灯,key1灭掉所以灯。


 int main(void)

{

 u8 key,res;

 u8 canbuf[8],buf[8];

 led_init();

 key_init();

 delay_init();

 can_init();

 canbuf[0]='1';

while(1)

 {

key=key_scan(1);

if(key==1)

{

res=can_send(canbuf,8);

if(!res)

LED_RED_ON;

}

if(key==2)

{

LED_RED_OFF;

LED_GREEN_OFF;

}

can_rec(buf);

if(buf[0]=='1')

{

LED_GREEN_ON;

buf[0]='0';

}

  }

}


关键字:stm32  CAN通信 引用地址:stm32CAN通信代码

上一篇:STM32仿真器ST-Link仿真
下一篇:STM32F1_ 外部NorFlash存储程序代码

小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved