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存储程序代码

推荐阅读最新更新时间:2024-11-12 15:09

STM32-DMA学习笔记
DMA,全称为:Direct Memory Access,即直接存储器访问。DMA传输方式无需CPU 直接控制传输,也没有中断处理方式那样保留现场和恢复现场的过程,通过硬件为RAM 与I/O设备开辟一条直接传送数据的通路,能使CPU 的效率大为提高。 STM32中 DMA1有7个通道,DMA2有5个通道(DMA2 仅存在大容量产品中)。DMA挂载的时钟为AHB总线,其时钟为72Mhz,所以可以实现高速数据搬运。 STM32F103RBT6 只有1 个DMA控制器,DMA1 ,下面我们就针对DMA1 进行介绍。 从外设(TIMx、ADC、SPIx 、I2Cx 和USARTx )产生的DMA请求,通过逻辑
[单片机]
STM32单片机的学习经验
随便写写,关于stm32 最近在学习stm32,写点东西,虽然简单,但都是原创啊 开发板是前辈画的,好像是用来测试一个3G功能的,不过对于我来说太远;我要来了3个,自己焊了一个最小系统,好在公司资源还是不错的,器件芯片有,还可以问问前辈--对公司还是比较满意的,虽然工资少了点,但学东西第一位O( _ )O~。 最开始当然是建工程了,这个真不太会,前前后后竟用了一周(时间真长,别见笑啊),上网查资料, 问前辈,自己琢磨。。。总算搞定,然后从GPIO开始学,开始还真没什么头绪(虽然在大学学点51,但完全没有真正应用,顶多是跑马灯实验),开始纠结是从寄存器开始学还是从库函数开始学,后来看到一句 用库函数入门,用寄存器提高 于是
[单片机]
STM32之SPI库函数介绍
首先SPI的一些基本介绍参照相关芯片的库函数或者使用手册,以下介绍SPI库函数的基本用法和参数的定义。 1.SPI_DeInit函数的功能是将外设SPIx寄存器重设为默认值。输入参数SPIx可以是1和2,是用来选择SPI外设的。 2.SPI_Init函数的功能是根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器。SPI_InitDefType的结构体是定义在文件stm32f10x_spi.h里。 typedef struct { u16 SPI_Direction;//用于设置SPI单向或者双向数据模式。 u16 SPI_Mode;//用于设置SPI的工作模式; u16 SPI_Dat
[单片机]
STM32的计数器的使用
因为用stm32f103c8作主控制器,来控制小车,小车的转速由两路光电编码盘输入(左右各一路).因此想到外部时钟触发模式(TIM——ETRClockMode2Config)。 可以试好好久,发现TIM1不能计数,到网上查了很久,也没有找到相关的文章,开始怀疑TIM1是不是需要特殊设置。经过很久的纠结,终于找到了问题——其实是我自己在GPIO设置的时候,后面的不小心覆盖了前面的了——没想到自己也会犯这么SB的事情。 现总结程序如下: 第一步,设置GPIO GPIO_InitTypeDefGPIO_InitStructure; /*PA0,PA12- 左右脉冲输入 */ GPIO_InitStructure.GPIO_Pin
[单片机]
关于STM32正交编码器边沿的理解
STM32中的TIM_EncoderInterfaceConfig()函数。其配置的定时器有编码器接口等功能,一般是定时器的通道1和通道2才能作为编码器的输入口,对应编码器输出的两项。 TIMx参数就是使用哪个定时器作为编码器接口的捕捉定时器。 一般一个编码器占用一个定时器。 TIM_EncoderMode参数是模式,是单相计数(只能反映速度)还是两相计数(速度和方向)。 TIM_IC1Polarity和TIM_IC2Polarity参数就是通道1、2的捕捉极性。 但是一般来说,STM32对应的都是两相计数,一项计数容易误判,也就是说,你可以按一路计数,但是接线时好像两相的编码线A,B都是需要接上的,否则容易误判。
[单片机]
关于<font color='red'>STM32</font>正交编码器边沿的理解
STM32如何高效接收串口数据
硬件:stm32f103cbt6 软件:STM32F10x_StdPeriph_Lib_V3.5.0 DMA,直接内存存取,可以用它的双手释放CPU的灵魂,所以,本文通过USART3进行串口收发,接受使用DMA的方式,无需CPU进行干预,当接受完成之后,数据可以直接从内存的缓冲区读取,从而减少了CPU的压力。 具体的代码实现如下: usart_driver.h 封装了接口,数据接收回调函数类型,基本数据结构等; usart_driver.c 函数原型实现,中断服务函数实现等; 拷贝这两个文件即可,可以根据目录下的参考用例,进行初始化。 头文件usart_driver.h已经声明了外部函数可能用到的接口; USART3_DR的
[单片机]
<font color='red'>STM32</font>如何高效接收串口数据
其实,STM32有隐藏的定时器~
DWT 在Cortex-M里面有一个外设叫DWT(DataWatchpoint andTrace),是用于系统调试及跟踪,DWT的中文名字应该是:数据观察点触发。在STM32用户手册的第32章节Debugsupport (DBG)有如下框图。 明显DWT属于DBG部分的功能,从上图的标题可以看出DWT属于CortexM3内核的,理论上M3内核的MCU都支持的,这个下文会说明。在这里我将其称之为“隐藏的定时器”,因为他可以代替定时器外设实现上文提到延时功能和测量代码运行时间的功能,DWT不能代替定时器的其他功能。 之所以DWT可以实现延时功能,因为它有一个32的计数器CYCCNT,这是一个向上计数的计数器,当它溢出时会自动清零并
[单片机]
STM32简单的LED流水灯程序
//0x4002 1000 - 0x4002 13FF 复位和时钟控制(RCC) #define RCC_BASE 0x40021000 #define RCC_APB2ENR (RCC_BASE+0x18) //LED接在GPIOF上,是APB2上的外设,是RCC_APB2ENR寄存器的第7位 //APB20x4001 1c00 GPIO端口F #define GPIOF_BASE 0x40011c00 #define GPIOF_CHL (0x000+GPIOF_BASE) #define GPIOF_CHR (0x004+GPIOF_BASE) #defin
[单片机]
小广播
设计资源 培训 开发板 精华推荐

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

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

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

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