当前位置: 首页 > news >正文

怎么登录住房城乡建设部网站郑州微网站

怎么登录住房城乡建设部网站,郑州微网站,东莞网络,明星网站怎么设计目录 一、工程配置 1、时钟、DEBUG、USART6、GPIO、CodeGenerator 2、CAN1 3、NVIC 二、软件设计 1、KEYLED 2、can.h 3、can.c (1)CAN1中断初始化 (2)RNG初始化和随机数产生 (3) 筛选器组设置…

目录

一、工程配置

1、时钟、DEBUG、USART6、GPIO、CodeGenerator

2、CAN1 

3、NVIC

二、软件设计

1、KEYLED

2、can.h

3、can.c

(1)CAN1中断初始化

(2)RNG初始化和随机数产生

(3) 筛选器组设置

(4)发送消息

(5)中断方式接收消息

4、main.c

三、下载与运行


        在实际的CAN通信中,使用轮询方式发送消息,使用中断方式接收消息更加实用和普遍。本实例设计一个CAN通信,使用中断方式接收消息,并且测试在两个FIFO上使用不同的筛选器。

        本实例仍然使用使用旺宝红龙开发板STM32F407ZGT6 KIT V1.0。需要参考本文作者的其他文章:

        参考文章1: 细说STM32F407单片机轮询方式CAN通信_stm32f407can波特率配置表-CSDN博客  https://wenchm.blog.csdn.net/article/details/144852504

        参考文章2:细说STM32F407单片机CAN基础知识及其HAL驱动程序-CSDN博客  https://wenchm.blog.csdn.net/article/details/144769950

        示例仍然引用KEYLED文件夹中的文件。

        示例的功能和使用流程如下:

        示例工程中,使用开发板上的S2键,按下S2键后,发送一个随机数的数据帧。并用LED1显示工作状态,输出到串口助手上。按下S6键,开发板复位。示例的功能还包括:

  • 使用CAN1的回环模式自发自收。
  • 开启FIFO0的接收中断,开启FIFO1的接收中断。
  • 为FIFO0设置筛选器,只接收标识符ID为奇数的消息;为FIFO1设置筛选器,接收所有消息。
  • 使用随机数生成器(Random Number Generator,RNG),在发送消息时,用随机数作为帧的数据。
[S2]KeyUp  = Send a Data Frame    LED1 ON

一、工程配置

        CAN接口原理图同参考文件1。 

1、时钟、DEBUG、USART6、GPIO、CodeGenerator

        与参考 文件1的设置相同或近似。

        这里,设置HCLK=168MHz,PCLK1=42MHz,PCLK2=84MHz。

2、CAN1 

         CAN1模块的参数设置与参考文件1相似。

 

3、NVIC

        使用CAN1模块的接收中断,打开CAN1 RX0中断和CAN1 RX1中断,两个中断的抢占优先级都设置为1,一个CAN模块有4个中断,RX0中断是FIFO0的中断,RX1中断是FIFO1的中断,每个中断有几个中断事件和对应的回调函数,详见参考文章2。

 

二、软件设计

1、KEYLED

        本例的项目中要使用KEYLED,其中的keyled.c和keyled.h的使用方法与参考文章1相同。

2、can.h

/* USER CODE BEGIN Prototypes */
HAL_StatusTypeDef CAN_SetFilters();
void CAN_TestPoll(uint8_t msgID,uint8_t frameType);
/* USER CODE END Prototypes */

3、can.c

/* USER CODE BEGIN 0 */
#include "rng.h"
#include <stdio.h>
/* USER CODE END 0 */
/* USER CODE BEGIN 1 */
//设置筛选器,需要在完成CAN初始化之后调用此函数
HAL_StatusTypeDef CAN_SetFilters()
{CAN_FilterTypeDef canFilter;//1. 设置FIFO0的筛选器canFilter.FilterBank = 0;						//筛选器组编号canFilter.FilterMode = CAN_FILTERMODE_IDMASK;	//ID掩码模式canFilter.FilterScale = CAN_FILTERSCALE_32BIT;	//32位长度//只接收stdID为奇数的帧canFilter.FilterIdHigh = 0x0020;				//CAN_FxR1寄存器的高16位canFilter.FilterIdLow = 0x0000;					//CAN_FxR1寄存器的低16位canFilter.FilterMaskIdHigh = 0x0020;			//CAN_FxR2寄存器的高16位canFilter.FilterMaskIdLow = 0x0000;				//CAN_FxR2寄存器的低16位canFilter.FilterFIFOAssignment = CAN_RX_FIFO0;	//应用于FIFO0canFilter.FilterActivation = ENABLE;			//使用筛选器canFilter.SlaveStartFilterBank = 14;			//从CAN控制器筛选器起始的BankHAL_StatusTypeDef result=HAL_CAN_ConfigFilter(&hcan1, &canFilter);//2. 设置FIFO1的筛选器canFilter.FilterBank = 1;						//筛选器组编号//接收所有帧canFilter.FilterIdHigh = 0x0000;				//CAN_FxR1寄存器的高16位canFilter.FilterIdLow = 0x0000;					//CAN_FxR1寄存器的低16位canFilter.FilterMaskIdHigh = 0x0000;			//CAN_FxR2寄存器的高16位,所有位任意canFilter.FilterMaskIdLow = 0x0000;				//CAN_FxR2寄存器的低16位,所有位任意canFilter.FilterFIFOAssignment = CAN_RX_FIFO1;	//应用于FIFO 1result=HAL_CAN_ConfigFilter(&hcan1, &canFilter);return result;
}void CAN_SendMsg(uint8_t msgID,uint8_t frameType)
{CAN_TxHeaderTypeDef TxHeader;TxHeader.StdId = msgID;			//stdIDTxHeader.RTR = frameType;		//数据帧,CAN_RTR_DATATxHeader.IDE = CAN_ID_STD;		//标准格式TxHeader.DLC =4;   				//数据长度TxHeader.TransmitGlobalTime = DISABLE;uint32_t rand;HAL_RNG_GenerateRandomNumber(&hrng, &rand);	//产生32位随机数uint8_t TxData[8];				//最多8个字节TxData[3] = rand & 0x000000FF;TxData[2] = (rand & 0x0000FF00)>>8;TxData[1] = (rand & 0x00FF0000)>>16;TxData[0] = (rand & 0xFF000000)>>24;while(HAL_CAN_GetTxMailboxesFreeLevel(&hcan1) < 1) {} //等待有可用的发送邮箱printf("Send MsgID= %X\r\n",msgID);uint32_t TxMailbox;		//临时变量,用于返回使用的邮箱编号/* 发送到邮箱,由CAN模块负责发送到CAN总线 */if(HAL_CAN_AddTxMessage(&hcan1,&TxHeader,TxData,&TxMailbox) != HAL_OK)printf("Send to mailbox error.\r\n");
}//读取和显示FIFO0或FIFO1的消息
//参数FIFO_num是FIFO编号,CAN_RX_FIFO0或CAN_RX_FIFO1
void CAN_ReadMsg(uint32_t FIFO_num)
{CAN_RxHeaderTypeDef RxHeader;uint8_t RxData[8];	//接收数据缓存区,8个字节if(FIFO_num==CAN_RX_FIFO0){printf("Msg received by FIFO0.\r\n");if(HAL_CAN_GetRxMessage(&hcan1,CAN_RX_FIFO0,&RxHeader,RxData) != HAL_OK){printf("Read FIFO0 error.\r\n");return;}}else{printf("Msg received by FIFO1.\r\n");if(HAL_CAN_GetRxMessage(&hcan1, CAN_RX_FIFO1, &RxHeader, RxData) != HAL_OK){printf("Read FIFO1 error.\r\n");return;}}//显示接收到的消息printf("StdID= %lX\r\n",RxHeader.StdId);printf("RTR(0=Data,2=Remote)= %lX\r\n",RxHeader.RTR);printf("IDE(0=Std,4=Ext)= %lX\r\n",RxHeader.IDE);printf("FilterMatchIndex= %lX\r\n",RxHeader.FilterMatchIndex);printf("DLC(Data length)= %lX\r\n",RxHeader.DLC);for (uint8_t i=0; i<4; i++){printf("Data[0]= %X\r\n",RxData[0]);printf("Data[1]= %X\r\n",RxData[1]);printf("Data[2]= %X\r\n",RxData[2]);printf("Data[3]= %X\r\n",RxData[3]);}printf("** Reselect menu or reset **\r\n");
}
//FIFO0接收到新消息事件中断回调函数
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
{CAN_ReadMsg(CAN_RX_FIFO0);
}//FIFO1接收到新消息事件中断回调函数
void HAL_CAN_RxFifo1MsgPendingCallback(CAN_HandleTypeDef *hcan)
{CAN_ReadMsg(CAN_RX_FIFO1);
}
/* USER CODE END 1 */

(1)CAN1中断初始化

        函数MX_CAN1_Init()的代码与参考文章1完全相同,函数HAL_CAN_MspInit()中与参考文章1比较,增加了两个中断的初始化设置,开启了CAN1_RX0和CAN1_RX1中断:

    /* CAN1 interrupt Init */HAL_NVIC_SetPriority(CAN1_RX0_IRQn, 1, 0);HAL_NVIC_EnableIRQ(CAN1_RX0_IRQn);HAL_NVIC_SetPriority(CAN1_RX1_IRQn, 1, 0);HAL_NVIC_EnableIRQ(CAN1_RX1_IRQn);

(2)RNG初始化和随机数产生

        RNG是MCU的一个内部单元,其初始化很简单,就是定义了RNG模块的外设对象变量,开启其时钟。相关代码如下:

#include "rng.h"
RNG_HandleTypeDef hrng;void MX_RNG_Init(void)
{hrng.Instance = RNG;if (HAL_RNG_Init(&hrng) != HAL_OK){Error_Handler();}
}void HAL_RNG_MspInit(RNG_HandleTypeDef* rngHandle)
{if(rngHandle->Instance==RNG){/* RNG clock enable */__HAL_RCC_RNG_CLK_ENABLE();}
}void HAL_RNG_MspDeInit(RNG_HandleTypeDef* rngHandle)
{if(rngHandle->Instance==RNG){/* Peripheral clock disable */__HAL_RCC_RNG_CLK_DISABLE();}
}

         可以使用轮询方式或中断方式产生32位的随机数,分别对应两个函数。

HAL_RNG_GenerateRandomNumber()    //轮询方式产生随机数。
HAL_RNG_GetRandomNumber_IT()      //中断方式产生随机数。

        HAL_RNG_GenerateRandomNumber()的函数原型如下:

HAL_StatusTypeDef HAL_RNG_GenerateRandomNumber(RNG_HandleTypeDef *hrng,uint32_t*random32bit)

        RNG由时钟树中的时钟信号由PCLK1 42MHz驱动,典型值是42MHz,这个时钟频率不能太低,在本例中,这个时钟频率是42MHz。产生两个连续随机数的最小间隔是42个PLL42CLK周期。

(3) 筛选器组设置

        在文件can.h中,自定义的函数CAN_SetFilters()用于对FIFO0和FIFO1进行筛选器设置。详细代码在can.c中实现。

        为FIFO0设置的筛选器是只接收标识符ID为奇数的消息,为FIFO1设置的筛选器是可以接收任何消息。注意,可以为一个FIFO设置多个筛选器,但是一个筛选器只能用于一个FIFO,所以,这两个筛选器的FilterBank必须不同。结构体CAN_FilterTypeDef各成员变量的意义以及筛选器的设置原理详见参考文章1。

(4)发送消息

        在main.c中调用函数CAN_SendMsg()发送数据帧,这个自定义函数的实现代码与参考文章1不同,并在can.c中实现这个函数的代码。

        在其实现的程序中还调用函数HAL_RNG_GenerateRandomNumber(),产生一个32位随机数,然后分解为4字节存入发送数据缓冲区。程序仍然是用函数HAL_CAN_AddTxMessage()将需要发送的消息写入发送邮箱,由CAN模块自动将消息发送到CAN总线上。函数CAN_SendMsg()只管发送消息,接收消息由中断去处理。

(5)中断方式接收消息

        由于开启了CAN1的RX0中断和RX1中断,在文件stm32f4xx_it.c中自动生成了这两个中断的ISR框架。

        CAN1_RX0是FIFO0接收消息、满或上溢时产生的中断,接收消息中断事件对应的回调函数是HAL_CAN_RxFifo0MsgPendingCallback()。同样的,FIFO1接收消息中断事件对应的回调函数是HAL_CAN_RxFifo1MsgPendingCallback()。CAN1_RX0和CAN1_RX1中断事件与回调函数的对应关系详见参考文章1。所以,要使用中断方式处理FIFO0和FIFO1接收的消息,只需重新实现这两个回调函数即可。在文件can.c中重新实现这两个回调函数。

//FIFO0接收到新消息事件中断回调函数
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
{CAN_ReadMsg(CAN_RX_FIFO0);
}//FIFO1接收到新消息事件中断回调函数
void HAL_CAN_RxFifo1MsgPendingCallback(CAN_HandleTypeDef *hcan)
{CAN_ReadMsg(CAN_RX_FIFO1);
}

        两个回调函数都调用了同一个函数CAN_ReadMsg(),只是传递了相应的FIFO编号。函数CAN_ReadMsg()负责读取FIFO0或FIFO1的消息并显示。读取FIFO里面收到的消息仍然使用函数HAL_CAN_GetRxMessage(),消息头结构体CAN_RxHeaderTypeDef的意义见参考文章1。这里显示了一个成员变量FilterMatchIndex的值,这是接收消息的FIFO内接收了消息的筛选器的序号,是在一个FIFO内的筛选器的序号,而不是筛选器的FilterBank属性值。

4、main.c

/* USER CODE BEGIN Includes */
#include "keyled.h"
#include <stdio.h>
/* USER CODE END Includes */
/* USER CODE BEGIN 2 */printf("Demo18_2_CAN:CAN Interrupt.\r\n");printf("Test mode:Loopback.\r\n");if (CAN_SetFilters() == HAL_OK)   	//设置筛选器printf("ID Filter: Only Odd IDs.\r\n");if (HAL_CAN_Start(&hcan1) == HAL_OK)  //启动CAN1模块printf("CAN is started.\r\n");printf("[S2]KeyUp  = Send a Data Frame.\r\n");//必须开启FIFO接收到消息中断事件,否则不会响应中断事件__HAL_CAN_ENABLE_IT(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING);__HAL_CAN_ENABLE_IT(&hcan1, CAN_IT_RX_FIFO1_MSG_PENDING);//HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING);//HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO1_MSG_PENDING);// MCU output low level LED light is onLED1_OFF();/* USER CODE END 2 */

        在外设初始化部分,函数MX_RNG_Init()用于RNG的初始化,函数MX_CAN1_Init()用于CAN1模块的初始化。

        函数CAN_SetFilters()用于设置FIFO0和FIFO1的筛选器组,与参考文章1的同名函数代码不同。这里要使用中断方式进行消息接收,还需要开启FIFO0和FIFO1的接收新消息的中断事件,即

__HAL_CAN_ENABLE_IT(&hcan1,CAN_IT_RX_FIFO0_MSG_PENDING);
__HAL_CAN_ENABLE_IT(&hcan1,CAN_IT_RX_FIFO1_MSG_PENDING);

        其中的两个宏分别是FIFO0和FIFO1接收新消息的中断事件使能控制位的宏定义,也作为中断事件类型宏定义,详见参考文章2。

        主程序的while()循环中调用自定义函数CAN_SendMsg()以轮询方式发送一个数据帧,接收数据帧在中断里处理。

  /* USER CODE BEGIN WHILE */uint8_t msgID=1;while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */KEYS curKey = ScanPressedKey(KEY_WAIT_ALWAYS);if (curKey==KEY_UP){CAN_SendMsg(msgID++, CAN_RTR_DATA);LED1_ON();}elseLED1_OFF();HAL_Delay(500);	//延时,消除按键抖动}/* USER CODE END 3 */
/* USER CODE BEGIN 4 */
//串口打印
int __io_putchar(int ch)
{HAL_UART_Transmit(&huart6,(uint8_t*)&ch,1,0xFFFF);return ch;
}
/* USER CODE END 4 */

三、下载与运行

        下载后在串口助手上先显示菜单,或者按下S6复位键也显示菜单。

        每次按下KeyUp键可以发送一个标准格式数据帧,msgID加1,msgID作为数据帧的标识符ID。

        运行时会发现,msgID为奇数时,是由FIFO0接收消息,msgID为偶数时,是由FIFO1接收消息。因为在设置筛选器组时,设置FIFO0只能接收标识符ID为奇数的消息,FIFO1可以接收任意标识符ID的消息。当标识符ID为偶数时,只能由FIFO1接收,当标识符ID为奇数时,两个FIFO都可以接收,但是由FIFO0优先接收。

        不管是哪个FIFO接收的消息,显示的FilterMatchIndex的值都是0,因为它们都只有一个筛选器。

 

http://www.yayakq.cn/news/928816/

相关文章:

  • 合肥市做网站多少钱微信文章 wordpress
  • 给个网站你们知道的小说网站开发流程具体
  • seo做的好的网站宣传海报设计
  • 应届生在淮北招的网站建设类型岗位梧州网站设计理念
  • 珠海医疗网站建设公司排名永久免费不收费的软件app
  • 湖南响应式网站建设哪家有Wordpress企业主题XShuan
  • 简易网站建设广东高端网站设计公司
  • 网站开发主管岗位职责网站制作窍门
  • 宜春seo网站推广舆情系统有哪些
  • 网站标题关键词怎么做app网站开发成本
  • 成交型网站建设公司深圳大型互联网公司有哪些
  • 内容型网站的运营做网站怎样做
  • 网站建设 售后服务手机如何制作网页
  • 河北邢台做网站商务型网站建设
  • 网站开发环境和运行环境做网站是那个语言写的
  • 做淘客网站要备案网站开发研发合同
  • 快速搭建展示型网站茶叶网站建设网页设计制作
  • 做盗版网站 国外服务器吗成都旅游十大必去景区
  • 做网站前后端的发布流程刷粉网站推广便宜
  • 安平百度做网站小县城做网站
  • 最好的购物网站好听的公司名字大全
  • 南阳建设重要区域中心城市网站零基础学设计
  • 荣耀手机官方网站南昌商城网站设计
  • 临沂市住房和城乡建设局网站重庆项目经理在建项目查询
  • 企业网站推广平台手机中国第一专业门户
  • 无锡 网站制作 大公司做鞋的网站
  • 个人网站可以做商业吗sticky wordpress html
  • 海南做网站找谁继续加强网站建设
  • 无锡网站制作的公司有哪些卖域名赚钱吗
  • 南京网站建设开发河南公司网站制作咨询