stm32CAN通信代码

发布时间:2024-08-26  

最近做项目需要用到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';

}

  }

}


文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>