历史上的今天
返回首页

历史上的今天

今天是: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情况下,就会有一些常用的波特率无法准确得到。 

推荐阅读

史海拾趣

Coors Components Inc公司的发展小趣事

在面对激烈的市场竞争时,Coors Components Inc公司果断调整市场策略,将目标市场从高端用户转向中端市场。通过优化产品线、提升服务质量以及加强品牌营销,公司成功吸引了大量中端市场的消费者。这一策略调整不仅使公司的销售额大幅提升,还为其未来的发展奠定了坚实的基础。

Acutechnology公司的发展小趣事

在市场竞争日益激烈的背景下,Acutechnology公司深知品质是企业生存和发展的关键。因此,公司建立了严格的质量管理体系,从原材料采购到产品出厂的每一个环节都进行严格把控。同时,公司还注重品牌建设,通过广告宣传、参加展会等方式提升品牌知名度和美誉度。这些举措有效地提升了公司的市场竞争力,赢得了客户的广泛认可。

Gigarams Semiconductor Device Corp公司的发展小趣事
这可能是由于定位力量不够或初始力矩过大导致的。解决方案包括调整定位参数、优化启动策略或增加缓冲装置以减少振动。
台湾义隆电子(ELAN)公司的发展小趣事

在产品多元化的基础上,义隆电子开始积极拓展国际市场。公司以台湾新竹科学园区为营运总部,在亚洲、美洲等多个国家和地区设立了分支机构和设计中心。通过与全球合作伙伴的紧密合作,义隆电子的产品逐渐进入欧洲、亚洲和美洲等市场,实现了全球布局。

Ferraz Shawmut(Mersen)公司的发展小趣事

Ferraz Shawmut一直致力于技术创新和产品研发。通过不断的技术创新,公司推出了多款具有竞争力的电气保护产品,如熔断器、保险丝等。同时,公司也积极拓展全球市场,目前在全球拥有60个下属企业,6200名雇员,产品远销世界各地。

DLG Hanbit公司的发展小趣事

随着环保意识的提高,DLG Hanbit公司开始注重环保和可持续发展。公司引进了一系列环保设备和技术,减少了生产过程中的污染物排放。同时,公司还积极推广绿色电子产品,帮助客户实现节能减排。这种环保理念不仅提升了公司的社会形象,也为公司的可持续发展奠定了基础。

问答坊 | AI 解惑

晒板子28335

28335电力电子与电力传动专用控制板 …

查看全部问答>

1-wire系统中TM卡的单片机等效替换

1 TM卡简介   TM(Touch Memory)卡是美国Dallas公司的专利产品。它采用单线协议通信,通过瞬间碰触完成数据读写,既具有非接触式IC卡的易操作性,又具有接触式IC 卡的廉价性,是当前性价比最优秀的IC卡之一。它的外形类似于一个钮扣(button) ...…

查看全部问答>

获取芯币的另一个小诀窍

快速获得芯币的另一种方法,就是与博客紧密结合。规则如下,请大家详细阅读啊! 1、注册博客 + 20 芯币 2、在论坛签名中注明自己博客地址  +5 芯币    3、博客个人信息注册完全,其中上传电子相片  +5芯币 4、 ...…

查看全部问答>

浙江大学RF设计(前端系统)(pdf)

第10个附件是一个超外差高频头的实例,很宝贵的资料…

查看全部问答>

LED行业竞争白热化,各大厂商拿什么取胜呢?打扰了。

LED行业竞争白热化,各大厂商拿什么取胜呢?打扰了。…

查看全部问答>

基于Win32 API函数和多线程技术的串行通信编程.pdf

基于Win32 API函数和多线程技术的串行通信编程.pdf…

查看全部问答>

u-boot 的 配置问题.(从NAND启动)

提示的是 bad crc or nand 在网上查了下,应该是env的问题!麻烦各位有经验的朋友,说一下具体怎么改! 我用的是mini2440,page size应该是2048的,但是u-boot启动输出的还是512~已经进行过CONFIG_了…

查看全部问答>

请教高手:如何在扫描输入完成后,光标自动跳到下一个TEXTBOX

我想让程序在扫描输入完成后,光标自动跳到下一个TEXTBOX 可是我在WINCE上捕捉不到扫描键,也不知道如何区分 输入 是由键盘上输入的还是扫描读入的 哪位高手知道的帮帮我,谢谢 啦 …

查看全部问答>

请问这几句汇编具体的意思是什么?

GBLS        MainEntry MainEntry        SETS        \"Main\"         IMPORT        $MainEntry MainEntry不是已经在第一行就已经定 ...…

查看全部问答>

引脚使用

一个引脚写成这样PA1/USART2_RTS/ADC_IN1/TIM5_CH2/TIM2_CH2是什么意思…

查看全部问答>