STM32_MDK_bxCAN

发布者:智慧启迪最新更新时间:2016-10-06 来源: eefocus关键字:STM32  MDK  bxCAN 手机看文章 扫描二维码
随时随地手机看文章
今天整理下CAN方面的资料,首先使用的是stm32f103vet6,只有一个CAN(2.0A & 2.0B)。CAN本身是工作的数据链路层的总线,有很多优势就不再一一介绍了,随便买本书看看都有。

基础的CAN的知识就不赘述了,这些是必要的可以自己去买书了解,现在来看下STM32下对CAN的驱动,STM32本身包括了CAN的数据链路层,然后物理层就是CAN收发器用的是TJA1050,是非容错CAN。终端电阻用120欧姆。

说道CAN最主要的是CAN的初始化,他包括两个主要的部分,一个是基本属性的声明,另一部分就是过滤器的设置。见如下代码:


/*******************************************************************************
* Function Name  : bxCAN_Port_Configuration
* Description    : CAN端口设置
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void bxCAN_Port_Configuration(void)
{
 GPIO_InitTypeDef GPIO_InitStructure_bxCAN;

 GPIO_PinRemapConfig(GPIO_Remap1_CAN1 , ENABLE);           //端口复用为CAN1
 
 GPIO_InitStructure_bxCAN.GPIO_Pin = GPIO_Pin_8;              //PB8:CAN-RX
    GPIO_InitStructure_bxCAN.GPIO_Mode = GPIO_Mode_IPU;    //输入上拉
 GPIO_InitStructure_bxCAN.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure_bxCAN);
 
   GPIO_InitStructure_bxCAN.GPIO_Pin = GPIO_Pin_9;        //PB9:CAN-TX
   GPIO_InitStructure_bxCAN.GPIO_Mode = GPIO_Mode_AF_PP;      //复用模式
   GPIO_InitStructure_bxCAN.GPIO_Speed = GPIO_Speed_50MHz;
   GPIO_Init(GPIOB, &GPIO_InitStructure_bxCAN);
}

/*******************************************************************************
* Function Name  : bxCAN_Property_Configuration
* Description    : CAN配置具体属性
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void bxCAN_Property_Configuration(void)
{
 CAN_InitTypeDef        CAN_InitStructure;
   CAN_FilterInitTypeDef  CAN_FilterInitStructure;

  /* CAN register init */
   CAN_DeInit(CAN1);
   CAN_StructInit(&CAN_InitStructure);

  /* CAN cell init */
   CAN_InitStructure.CAN_TTCM=DISABLE;         //MCR-TTCM   禁止时间触发通信模式 
   CAN_InitStructure.CAN_ABOM=DISABLE;   //MCR-ABOM   禁止自动离线管理
   CAN_InitStructure.CAN_AWUM=DISABLE;   //MCR-AWUM   通过清除CAN_MCR_SLEEP位进入自动唤醒模式
   CAN_InitStructure.CAN_NART=DISABLE;   //MCR-NART   禁止报文自动重传   0-自动重传   1-报文只传一次
   CAN_InitStructure.CAN_RFLM=DISABLE;   //MCR-RFLM   接收FIFO 锁定模式  0-溢出时新报文会覆盖原有报文  1-溢出时,新报文丢弃
   CAN_InitStructure.CAN_TXFP=DISABLE;   //MCR-TXFP   发送FIFO优先级 0-优先级取决于报文标示符 1-优先级取决于发送请求的顺序
   CAN_InitStructure.CAN_Mode=CAN_Mode_LoopBack; //BTR-SILM/LBKM   CAN环回模式  
//  CAN_InitStructure.CAN_Mode=CAN_Mode_Normal; //         CAN正常模式
   CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;      //BTR-SJW 重新同步跳跃宽度 1个时间单元
   CAN_InitStructure.CAN_BS1=CAN_BS1_2tq;   //BTR-TS1 时间段1 占用了2个时间单元
   CAN_InitStructure.CAN_BS2=CAN_BS2_3tq;   //BTR-TS1 时间段2 占用了3个时间单元

 #if   CAN_BAUDRATE == 1000 /* 1MBps   */  //BTR-BRP 波特率分频器  定义了时间单元的时间长度 36/(1+2+3)/6=1Mbps
    CAN_InitStructure.CAN_Prescaler = 6;     
  #elif CAN_BAUDRATE == 500  /* 500KBps */
    CAN_InitStructure.CAN_Prescaler = 12;
  #elif CAN_BAUDRATE == 250  /* 250KBps */
   CAN_InitStructure.CAN_Prescaler = 24;
  #elif CAN_BAUDRATE == 125  /* 125KBps */
   CAN_InitStructure.CAN_Prescaler = 48;
 #elif CAN_BAUDRATE == 100  /* 100KBps */
     CAN_InitStructure.CAN_Prescaler = 60;
 #elif CAN_BAUDRATE == 50   /* 50KBps  */
     CAN_InitStructure.CAN_Prescaler = 120;
   #elif CAN_BAUDRATE == 20   /* 20KBps  */
    CAN_InitStructure.CAN_Prescaler = 300;
   #elif CAN_BAUDRATE == 10   /* 10KBps  */
    CAN_InitStructure.CAN_Prescaler = 600;
   #endif
   CAN_Init(CAN1, &CAN_InitStructure);       //初始化CAN寄存器

  /* CAN filter init */
   CAN_FilterInitStructure.CAN_FilterNumber=1;         // 选择过滤器编号
   CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask; // 选择过滤器类型为屏蔽位模式
   CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;  // 选择过滤器位宽为一个32位过滤器
   CAN_FilterInitStructure.CAN_FilterIdHigh=0x0000;    // 标识符匹配
   CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;
   CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;   // 标识符屏蔽位,1:必须匹配,0:不用关心
   CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;
   CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_FIFO0;     // 选择存放在关联的FIFO为FIFO0
   CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;   // 激活过滤器
   CAN_FilterInit(&CAN_FilterInitStructure);      // 初始化过滤器

  /* CAN FIFO0 message pending interrupt enable */
   CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);      // 设置CAN1,FIFO0接收中断使能
//  CAN_ITConfig(CAN1, CAN_IT_FMP0, DISABLE);
}

/*******************************************************************************
* Function Name  : bxCAN_Configuration
* Description    : CAN初始化
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void bxCAN_Configuration(void)
{
 bxCAN_Port_Configuration();
 bxCAN_Property_Configuration();
}

/*******************************************************************************
* Function Name  : Interrupt_Handle_bxCAN
* Description    : 中断服务函数
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void Interrupt_Handle_bxCAN(void)
{
 CanRxMsg RxMessage;

   RxMessage.StdId=0x00;
  RxMessage.ExtId=0x00;
 RxMessage.IDE=0;
  RxMessage.DLC=0;
  RxMessage.FMI=0;
  RxMessage.Data[0]=0x00;
  RxMessage.Data[1]=0x00;

   CAN_Receive(CAN1, CAN_FIFO0, &RxMessage);
}

初始化第一部分基本属性设置,要看下datasheet中,CAN的发送流程和接受流程,然后看下他相关的状态寄存器就知道其意义了。在过滤器设置部分,要理解他两种模式的不同之处,屏蔽位模式就是给出 一个参考值然后用屏蔽属性去匹配,列表模式就是直接根据寄存器的参考值进行全匹配。这里对屏蔽位我也没有做特殊的设置,就设置全部接受。
本历程只实现了发送标准帧,扩展帧,接受帧数据。
接收程序使用中断方式,见上面代码函数Interrupt_Handle_bxCAN(),发送代码如下:


void Send_Std_KLS_KL15(unsigned char value)
{
CanTxMsg TxMessage;

TxMessage.StdId=0x570;
TxMessage.IDE=CAN_ID_STD;
TxMessage.RTR=CAN_RTR_DATA;
TxMessage.DLC=8;
TxMessage.Data[0]=value;
TxMessage.Data[1]=0x00;
TxMessage.Data[2]=0x00;
TxMessage.Data[3]=0x00;
TxMessage.Data[4]=0x00;
TxMessage.Data[5]=0x00;
TxMessage.Data[6]=0x00;
TxMessage.Data[7]=0x00;

CAN_Transmit(CAN1, &TxMessage);
}

这个是发送一个标准帧,如果发送扩展帧 如下:


void Send_Exd_message(void)
{
CanTxMsg TxMessage;

TxMessage.StdId=0x0000;
TxMessage.ExtId=0x1234;
TxMessage.IDE=CAN_ID_EXT;
TxMessage.RTR=CAN_RTR_DATA;
TxMessage.DLC=2;
TxMessage.Data[0]=0xDE;
TxMessage.Data[1]=0xCA;
CAN_Transmit(CAN1, &TxMessage);
}

由于CAN透明化了数据链路层,所以在实际应用中只要用好屏蔽位就能够高效的使用CAN网络。
关键字:STM32  MDK  bxCAN 引用地址:STM32_MDK_bxCAN

上一篇:关于STM32 Systick 延时函数 变量全局引用的问题
下一篇:STM32 uCOS_II 实践 之 外部中断事件 及 系统运行过程

推荐阅读最新更新时间:2024-03-16 15:13

STM32学习笔记--------外部中断
外部中断 中断就是主程序在正常执行时,CPU发出一个中断请求,然后程序就会跳到中断子程序去执行,执行完后会返回主程序。 一、概述 组成结构 1-15中断号用于系统异常 16开始是外部中断 font color=#999AAA GPIO与中断线的映射关系 1、GPIO引脚0对应的是外部中断0 2、一个中断对应了9个IO口(PA0~PA9) 3、同一时刻一个中断只能对应一个IO口,不能PA0链接了外部中断0,PB0再链接外部中断0 二、使用步骤 1.GPIO端口设置为外部中断输入----参考stm32f10x_gpio.c 代码如下(示例): void GPIO_Init(GPIO_TypeDef* GPI
[单片机]
<font color='red'>STM32</font>学习笔记--------外部中断
浅谈STM32 模数转换器 (ADC)(下)
温度传感器和VRENFINT通道框图 要使用传感器,请执行以下操作: 选择 ADC1_IN16 或 ADC1_IN18 输入通道。 选择一个采样时间,该采样时间要大于数据手册中所指定的最低采样时间。 在 ADC_CCR 寄存器中将 TSVREFE 位置 1,以便将温度传感器从掉电模式中唤醒。 通过将 SWSTART 位置 1(或通过外部触发)开始 ADC 转换 读取 ADC 数据寄存器中生成的 V SENSE 数据 使用以下公式计算温度: 温度(单位为 °C)= {(V SENSE — V 25 ) / Avg_Slope} + 25 其中: — V 25 = 25 °C 时的 V SENSE 值 — Avg
[单片机]
浅谈<font color='red'>STM32</font> 模数转换器 (ADC)(下)
HC-SR04超声波模块驱动(STM32
一、前期准备 单片机:STM32F103C8T6 开发环境:MDK5.14 库函数:标准库V3.5 HC-SR04模块:淘宝有售 二、实验效果 三、驱动原理 触发信号Tirig维持10Us以上的高电平即可等待Echo的返回,这里是用EXTI检测俩个跳变信号,去打开和关闭定时器,最后一次测量计算结果后清除定时器计时,并等待下一个循环开始。需要完整工程或者有问题的请加QQ:1002521871,验证:呵呵。 四、驱动代码 US-020.h #ifndef __US_020_H__ #define __US_020_H__ #include stm32f10x.h #include gpio.h #include
[单片机]
HC-SR04超声波模块驱动(<font color='red'>STM32</font>)
如何将STM32单片机的JTAG口作为GPIO使用
使用STM32F系列,会遇到将JTAG口复用为SPI1或直接用做普通IO。 针对于F1系列,需要先禁止使能 JTAG,然后将其复用为其他口或者普通IO。 针对F4系列,STM32F4库函数中,已经取消了GPIO_*PinRemapConfig()函数,对于复用功能使用GPIO*_PinAFConfig()函数了! 但是在GPIO_PinAFConfig()函数已经没有禁止JTAG/SW等选项了,而是复用到AF0~AF15线上,其中AF0是系统功能(也是复位初始功能)。 其中调试接口就是系统功能,这样需要禁用JTAG功能只需把引脚复用到AF1~AF15中的一个就行了。 直接复用就可使用相应的复用功能,不用想着失能
[单片机]
STM32 IAP+APP应用
一、在进入主题之前我们先了解一些必要的基础知识----stm32系列芯片的种类和型号: startup_stm32f10x_cl.s 互联型的器件,STM32F105xx,STM32F107xx startup_stm32f10x_hd.s 大容量的STM32F101xx,STM32F102xx,STM32F103xx startup_stm32f10x_hd_vl.s 大容量的STM32F100xx startup_stm32f10x_ld.s 小容量的STM32F101xx,STM32F102xx,STM32F103xx startup_stm32f10x_ld_vl.s 小容量的STM32F100xx startup_s
[单片机]
<font color='red'>STM32</font> IAP+APP应用
无线传感器网络底层平台的深层研究
引言 目前,对WSN(Wireless Sensor Netwoek)的研究主要集中在协议栈、定位算法、能耗管理以及体系结构设计上,而针对无线传感网络操作系统的研究却相对较少,尤其是对其底层平台的研究更少,所以针对无线传感网络操作系统底层平台的研究有十分广阔的空间。本论文针对意法半导体STM32系列MCU和TI公司的CC2520无线模块进行介绍。主要描述了操作系统底层平台的构建,以及硬件驱动程序的实现。本论文的底层硬件抽象层是针对CC2520无线射频模块的,包括了平台构建、相关寄存器,以及外围接口等各个部分。而硬件驱动程序主要是为完成无线通信所需的硬件驱动设计,这主要包括:相应异步事件的中断机制;和PC通信的USART驱动;连
[单片机]
无线传感器网络底层平台的深层研究
STM32 定时器实现红外遥控数据接收
一、原理 1、红外发射协议 红外通信的协议有很多种。这个实验使用的是NEC协议。这个协议采用PWM的方法进行调制,利用脉冲宽度来表示 0 和 1 。 NEC 遥控指令的数据格式为:同步码头、地址码、地址反码、控制码、控制反码。同步码由一个 9ms 的低电平和一个 4.5ms 的高电平组成,地址码、地址反码、控制码、控制反码均是 8 位数据格式。按照低位在前,高位在后的顺序发送。采用反码是为了增加传输的可靠性。因此,每帧的数据为 32 位,包括地址码,地址反码,控制码,控制反码。反码可用于解码时进行校验比对。 NEC码的位定义:一个脉冲对应 560us 的连续载波,一个逻辑 1 传输需要 2.25ms(560us 脉冲+16
[单片机]
STM32的ADC输入通道配置
STM32中最多有3个ADC模块,每个模块对应的通道不完全重叠。   下图是STM32F103CDE数据手册中的总框图的左下角,图中可以看出有8个外部ADC管脚分别接到了3个ADC模块,有8个外部ADC管脚只分别接到了2个ADC模块,还有5个外部ADC管脚只接到了ADC3模块,这样总共是21个通道。      下表是这些ADC管脚与每个ADC模块的对应关系,表中可以看出ADC1还有2个内部通道,分别接到内部的温度传感器和内部的参照电压:   
[模拟电子]
<font color='red'>STM32</font>的ADC输入通道配置
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

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

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

换一换 更多 相关热搜器件
随便看看
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved