历史上的今天
今天是:2025年08月09日(星期六)
2019年08月09日 | stm32 can基础测试例程
2019-08-09 来源:eefocus
include “stm32f10x_lib.h”
include “stdio.h”
/* 自定义同义关键字 ——————————————————–*/
/* 自定义参数宏 ——————————————————–*/
/* 自定义函数宏 ——————————————————–*/
/* 自定义全局变量 ——————————————————–*/
/* 自定义函数声明 ——————————————————–*/
void RCC_Configuration(void);
void GPIO_Configuration(void);
void CAN_Configuration(void);
void USART_Configuration(void);
/*********************************************************************
* 函数名 : main
* 函数描述 : main 函数
* 输入参数 : 无
* 输出结果 : 无
* 返回值 : 无
*********************************************************************/
int main(void)
{
u8 TransmitMailbox = 0; /* 定义消息发送状态变量 */
CanTxMsg TxMessage; /* 定义消息发送结构体 */
CanRxMsg RxMessage; /* 定义消息接收结构体 */
/* 设置系统时钟 */
RCC_Configuration();
/* 设置 GPIO 端口 */
GPIO_Configuration();
/* 设置 USART */
USART_Configuration();
/* 设置 CAN 控制器 */
CAN_Configuration();
/* 配置发送数据结构体 ,标准ID格式 ,ID为0xAA,数据帧 ,数据长度为8个字节 */
TxMessage.ExtId = 0x00AA0000;
TxMessage.RTR = CAN_RTR_DATA;
TxMessage.IDE = CAN_ID_EXT;
TxMessage.DLC = 8;
TxMessage.Data[0] = 0x00;
TxMessage.Data[1] = 0x12;
TxMessage.Data[2] = 0x34;
TxMessage.Data[3] = 0x56;
TxMessage.Data[4] = 0x78;
TxMessage.Data[5] = 0xAB;
TxMessage.Data[6] = 0xCD;
TxMessage.Data[7] = 0xEF;
/* 发送数据 */
TransmitMailbox = CAN_Transmit(&TxMessage);
/* 等待发送完成 */
while((CAN_TransmitStatus(TransmitMailbox) != CANTXOK));
printf("rnThe CAN has send data: 0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%xrn",
TxMessage.Data[0], TxMessage.Data[1], TxMessage.Data[2],
TxMessage.Data[3], TxMessage.Data[4], TxMessage.Data[5],
TxMessage.Data[6], TxMessage.Data[7]);
/* 等待接收完成 */
while((CAN_MessagePending(CAN_FIFO0) == 0));
/* 初始化接收数据结构体 */
RxMessage.ExtId = 0x00;
RxMessage.IDE = CAN_ID_EXT;
RxMessage.DLC = 0;
RxMessage.Data[0] = 0x00;
RxMessage.Data[1] = 0x00;
RxMessage.Data[2] = 0x00;
RxMessage.Data[3] = 0x00;
RxMessage.Data[4] = 0x00;
RxMessage.Data[5] = 0x00;
RxMessage.Data[6] = 0x00;
RxMessage.Data[7] = 0x00;
/* 接收数据 */
CAN_Receive(CAN_FIFO0 , &RxMessage);
printf("rnThe CAN has receive data: 0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%xrn",
RxMessage.Data[0], RxMessage.Data[1], RxMessage.Data[2],
RxMessage.Data[3], RxMessage.Data[4], RxMessage.Data[5],
RxMessage.Data[6], RxMessage.Data[7]);
while(1);
}
/*********************************************************************
* 函数名 : RCC_Configuration
* 函数描述 : 设置系统各部分时钟
* 输入参数 : 无
* 输出结果 : 无
* 返回值 : 无
*********************************************************************/
void RCC_Configuration(void)
{
/* 定义枚举类型变量 HSEStartUpStatus */
ErrorStatus HSEStartUpStatus;
/* 复位系统时钟设置 */
RCC_DeInit();
/* 开启 HSE */
RCC_HSEConfig(RCC_HSE_ON);
/* 等待 HSE 起振并稳定 */
HSEStartUpStatus = RCC_WaitForHSEStartUp();
/* 判断 HSE 起是否振成功,是则进入if()内部 */
if(HSEStartUpStatus == SUCCESS)
{
/* 选择 HCLK(AHB)时钟源为SYSCLK 1分频 */
RCC_HCLKConfig(RCC_SYSCLK_Div1);
/* 选择 PCLK2 时钟源为 HCLK(AHB) 1分频 */
RCC_PCLK2Config(RCC_HCLK_Div1);
/* 选择 PCLK1 时钟源为 HCLK(AHB) 2分频 */
RCC_PCLK1Config(RCC_HCLK_Div2);
/* 设置 FLASH 延时周期数为2 */
FLASH_SetLatency(FLASH_Latency_2);
/* 使能 FLASH 预取缓存 */
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
/* 选择锁相环(PLL)时钟源为HSE 1分频,倍频数为9,则PLL输出频率为 8MHz * 9 = 72MHz */
RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
/* 使能 PLL */
RCC_PLLCmd(ENABLE);
/* 等待 PLL 输出稳定 */
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);
/* 选择 SYSCLK 时钟源为 PLL */
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
/* 等待 PLL 成为 SYSCLK 时钟源 */
while(RCC_GetSYSCLKSource() != 0x08);
}
/* 打开 GPIOA,USART1 时钟 */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1 , ENABLE);
/* 打开 CAN 时钟 */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN, ENABLE);
}
/*********************************************************************
* 函数名 : GPIO_Configuration
* 函数描述 : 设置各GPIO端口功能
* 输入参数 : 无
* 输出结果 : 无
* 返回值 : 无
*********************************************************************/
void GPIO_Configuration(void)
{
/* 定义 GPIO 初始化结构体 GPIO_InitStructure */
GPIO_InitTypeDef GPIO_InitStructure;
/* 设置 CAN 的 Rx(PA.11) 引脚 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* 设置 CAN 的 Tx(PA.12) 引脚 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* 设置 USART1 的Tx脚(PA.9)为第二功能推挽输出功能 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA , &GPIO_InitStructure);
/* 设置 USART1 的Rx脚(PA.10)为浮空输入脚 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA , &GPIO_InitStructure);
}
/*********************************************************************
* 函数名 : CAN_Polling
* 函数描述 : 设置CAN为环回收发模式
* 输入参数 : 无
* 输出结果 : 无
* 返回值 : 无
*********************************************************************/
void CAN_Configuration(void)
{
/* 定义 CAN 控制器和过滤器初始化结构体 */
CAN_InitTypeDef CAN_InitStructure;
CAN_FilterInitTypeDef CAN_FilterInitStructure;
/* CAN 寄存器复位 */
CAN_DeInit();
CAN_StructInit(&CAN_InitStructure);
/*
* CAN 控制器初始化:
*
* 失能时间触发通讯模式
* 失能自动离线管理
* 失能自动唤醒模式
* 失能非自动重传输模式
* 失能接收 FIFO 锁定模式
* 失能发送 FIFO 优先级
* CAN 硬件工作在环回模式
* 重新同步跳跃宽度 1 个时间单位
* 时间段 1 为 8 个时间单位
* 时间段 2 为 7 个时间单位
* 分频数为5
*/
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硬件工作在环回模式
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; //分频数为5
CAN_Init(&CAN_InitStructure);
/*
* CAN 过滤器初始化:
*
* 初始化过滤器 2
* 标识符屏蔽位模式
* 使用 1 个 32 位过滤器
* 过滤器标识符为 (0x00AA << 5)
* 过滤器屏蔽标识符 0xFFFF
* 过滤器 FIFO0 指向过滤器 0
* 使能过滤器
*/
CAN_FilterInitStructure.CAN_FilterNumber = 0; //初始化过滤器 0
CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask; //标识符屏蔽位模式
CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit; //使用1个32过滤器
CAN_FilterInitStructure.CAN_FilterIdHigh = 0x00AA << 3; //过滤器标识符高位
CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000; //过滤器标识符低位
CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x00FF << 3; //过滤器屏蔽标识符高位
CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000; //过滤器屏蔽标识符低位
CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 0; //过滤器FIFO0指向过滤器0
CAN_FilterInitStructure.CAN_FilterActivation = ENABLE; //使能过滤器
CAN_FilterInit(&CAN_FilterInitStructure);
}
/*********************************************************************
* 函数名 : USART_Configuration
* 函数描述 : 设置USART1
* 输入参数 : 无
* 输出结果 : 无
* 返回值 : 无
*********************************************************************/
void USART_Configuration(void)
{
/* 定义 USART 初始化结构体 USART_InitStructure */
USART_InitTypeDef USART_InitStructure;
/* 波特率为115200bps;
* 8位数据长度;
* 1个停止位,无校验;
* 禁用硬件流控制;
* 禁止USART时钟;
* 时钟极性低;
* 在第2个边沿捕获数据
* 最后一位数据的时钟脉冲不从 SCLK 输出;
*/
USART_InitStructure.USART_BaudRate = 115200;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No ;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART1 , &USART_InitStructure);
/* 使能 USART1 */
USART_Cmd(USART1 , ENABLE);
}
/*********************************************************************
* 函数名 : fputc
* 函数描述 : 将printf函数重定位到USATR1
* 输入参数 : 无
* 输出结果 : 无
* 返回值 : 无
*********************************************************************/
int fputc(int ch, FILE *f)
{
USART_SendData(USART1, (u8) ch);
while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
return ch;
}
注意事项:
1、通过设置不同的APB1总线工作频率,CAN分频数和位时序组合可以得到不同的波特率。但若APB1总线工作频率固定在最大的36MHZ情况下,就会有一些常用的波特率无法准确得到。
上一篇:stm32 I2C自收发测试例程
下一篇:stm32 启动文件解析
史海拾趣
|
1 TM卡简介 TM(Touch Memory)卡是美国Dallas公司的专利产品。它采用单线协议通信,通过瞬间碰触完成数据读写,既具有非接触式IC卡的易操作性,又具有接触式IC 卡的廉价性,是当前性价比最优秀的IC卡之一。它的外形类似于一个钮扣(button) ...… 查看全部问答> |
|
快速获得芯币的另一种方法,就是与博客紧密结合。规则如下,请大家详细阅读啊! 1、注册博客 + 20 芯币 2、在论坛签名中注明自己博客地址 +5 芯币 3、博客个人信息注册完全,其中上传电子相片 +5芯币 4、 ...… 查看全部问答> |
|
提示的是 bad crc or nand 在网上查了下,应该是env的问题!麻烦各位有经验的朋友,说一下具体怎么改! 我用的是mini2440,page size应该是2048的,但是u-boot启动输出的还是512~已经进行过CONFIG_了… 查看全部问答> |
|
请教高手:如何在扫描输入完成后,光标自动跳到下一个TEXTBOX 我想让程序在扫描输入完成后,光标自动跳到下一个TEXTBOX 可是我在WINCE上捕捉不到扫描键,也不知道如何区分 输入 是由键盘上输入的还是扫描读入的 哪位高手知道的帮帮我,谢谢 啦 … 查看全部问答> |
|
GBLS MainEntry MainEntry SETS \"Main\" IMPORT $MainEntry MainEntry不是已经在第一行就已经定 ...… 查看全部问答> |




