嵌入式单片机实战开发:STM32F103 CAN总线功能开发与物联技术
CAN模块测试
1、功能描述
bxCAN是基本扩展CAN(Basic Extended CAN)的缩写,它支持CAN协议2.0A和2.0B。它的设计目标是以最小的CPU负荷来高效处理大量收到的报文。它也支持报文发送的优先级要求(优先级特性可软件配置)。
2、主要特性
- 支持CAN协议2.0A和2.0B主动模式
- 波特率最高可达1兆位/秒
- 支持时间触发通信功能
发送
- 3个发送邮箱
- 发送报文的优先级特性可软件配置
- 记录发送SOF时刻的时间
接收
- 3级深度的2个FIFO
- 14个位宽可变的过滤器组-由整个CAN共享
- 标识符列表
- FIFO溢出处理方式可配置
- 记录接收 SOF时刻的时间
可支持时间触发通信模式
- 禁止自动重传模式
- 16位自由运行定时器
- 定时器分辨率可配置
- 可在最后2个数据字节发送时间
管理
- 中断可屏蔽
- 邮箱占用单独1块地址空间,便于提高软件效率
发送邮箱
- 共有3个发送邮箱供软件来发送报文。发送调度器根据优先级决定哪个邮箱的报文先被发送。
接收过滤器
- 共有14个位宽可变/可配置的标识符过滤器组,软件通过对它们编程,从而在引脚收到的报文中选择它需要的报文,而把其他报文丢弃掉。
接收FIFO
- 共有2个接收FIFO,每个FIFO都可以存放3个完整的报文。它们完全由硬件来管理
3、工作模式
- 软件代码
#include"stm32f10x_lib.h"
#define GPIO_CAN GPIOB
#define GPIO_Pin_CAN_RX GPIO_Pin_8
#define GPIO_Pin_CAN_TX GPIO_Pin_9
#define GPIO_Remap_CAN GPIO_Remap1_CAN
typedef enum {FAILED = 0, PASSED = !FAILED} TestStatus;
/******************************************************************
* 函数名称:TestStatus CAN_Polling_Configuration(void)
* 功能描述:采用查询的方式来测试CAN总线
* 入口参数:无
* 出口参数: TestStatus
测试的状态码,若发送与接收的数据一致返回1
否则,返回0
******************************************************************/
TestStatus CAN_Polling_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
CAN_InitTypeDef CAN_InitStructure;
CAN_FilterInitTypeDef CAN_FilterInitStructure;
CanTxMsg TxMessage;
CanRxMsg RxMessage;
u8 TransmitMailbox = 0;
u32 i;
/********************** *************************************
CAN 总线的引脚配置
************************************************************/
/* Configure CAN pin: RX */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_CAN_RX;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIO_CAN, &GPIO_InitStructure);
/* Configure CAN pin: TX */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_CAN_TX;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIO_CAN, &GPIO_InitStructure);
GPIO_PinRemapConfig(GPIO_Remap_CAN , ENABLE);
/********************** *************************************
CAN 总线的配置
************************************************************/
/* CAN register init */
CAN_DeInit();
CAN_StructInit(&CAN_InitStructure);
CAN_InitStructure.CAN_TTCM = DISABLE; //时间触发通讯模式
CAN_InitStructure.CAN_ABOM = DISABLE; //自动离线管理模式
CAN_InitStructure.CAN_AWUM = DISABLE; //自动唤醒模式
CAN_InitStructure.CAN_NART = DISABLE; //非自动重传输模式
CAN_InitStructure.CAN_RFLM = DISABLE; //接收FIFO锁定模式
CAN_InitStructure.CAN_TXFP = DISABLE; //发送FIFO优先级
CAN_InitStructure.CAN_Mode = CAN_Mode_LoopBack; //回环模式,自发自收
CAN_InitStructure.CAN_SJW = CAN_SJW_1tq; //同步跳跃1个时间单元
CAN_InitStructure.CAN_BS1 = CAN_BS1_8tq; //时间段1为8个时间单元
CAN_InitStructure.CAN_BS2 = CAN_BS2_7tq; //时间段2为7个时间单元
CAN_InitStructure.CAN_Prescaler = 5; //分频值
CAN_Init(&CAN_InitStructure);
/********************** *************************************
CAN 总线的过滤设置
************************************************************/
CAN_FilterInitStructure.CAN_FilterNumber = 0; //指定初始化的过滤器编号为0 (0~13)
CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;//标识符屏蔽位模式
CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;//1个32位的过滤器
CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000; //设定过滤器的标识符(32位为其高段,16位为第一个)范围是0x0000~0xffff
CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000; //设定过滤器的标识符(32位为其低段,16位为第二个)范围是0x0000~0xffff
CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000;//设定过滤器屏蔽标识符或者过滤标识符
CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;//设定过滤器屏蔽标识符或者过滤标识符
CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_FilterFIFO0; //过滤器FIFO指向过滤器0
CAN_FilterInitStructure.CAN_FilterActivation = ENABLE; //使能过滤器
CAN_FilterInit(&CAN_FilterInitStructure);
/********************** *************************************
CAN 总线的发送设置
************************************************************/
TxMessage.StdId = 0x11; //标准标识符
// TxMessage.ExtId = //扩展标识符
TxMessage.IDE = CAN_ID_STD; //使用标准标识符
TxMessage.RTR = CAN_RTR_DATA; //数据帧
TxMessage.DLC = 2; //设定传输消息的帧长度为2
TxMessage.Data[0] = 0xCA; //数据1
TxMessage.Data[1] = 0xFE; //数据2
TransmitMailbox = CAN_Transmit(&TxMessage);
i=0;
while((CAN_TransmitStatus(TransmitMailbox) != CANTXOK) && (i != 0xFF))
{
i++;
}
i=0;
while((CAN_MessagePending(CAN_FIFO0) < 1) && (i != 0xFF))
{
i++;
}
/********************** *************************************
CAN 总线的接收设置
************************************************************/
RxMessage.StdId = 0x00; //设定标准标识符
RxMessage.IDE = CAN_ID_STD; //使用标准标识符
RxMessage.DLC = 0; //用来设定待传输的帧长度
RxMessage.Data[0]=0x00; //数据1
RxMessage.Data[1]=0x00; //数据2
CAN_Receive(CAN_FIFO0,&RxMessage);
if (RxMessage.StdId!=0x11) //发送和接收不一致,返回FAILED
{
return FAILED;
}
if (RxMessage.IDE!=CAN_ID_STD) //发送和接收不一致,返回FAILED
{
return FAILED;
}
if (RxMessage.DLC!=2) //发送和接收不一致,返回FAILED
{
return FAILED;
}
if ((RxMessage.Data[0]<<8|RxMessage.Data[1])!=0xCAFE) //发送和接收不一致,返回FAILED
{
return FAILED;
}
return PASSED; /* Test Passed */ //否则返回PASSED
}
源码下载:
作者:物联技术666