(直播)利用stm32cubemx实现USBDFU对芯片程序的更新升级(板卡stm32f4discovery)

软件教程wansaiyon 回复了问题 • 37 人关注 • 20 个回复 • 13914 次浏览 • 2019-01-12 06:40 • 来自相关话题

关于外部中断 干扰

问题困惑Dreamer 回复了问题 • 3 人关注 • 3 个回复 • 2495 次浏览 • 2019-01-10 14:13 • 来自相关话题

利用stm32cubemx移植freemodbus代码分享,片子是stm32F407,记录整个调试过程,供大家参考

软件教程flyshaw 回复了问题 • 85 人关注 • 33 个回复 • 24229 次浏览 • 2019-01-10 10:22 • 来自相关话题

IAP升级,boot和app分别是用标准库和HAL库写的,跳转不成功。

问题困惑yup1983 回复了问题 • 2 人关注 • 1 个回复 • 167 次浏览 • 2019-01-09 17:33 • 来自相关话题

I2S全双工主发送模式DMA方式问题

问题困惑流风回雪 回复了问题 • 4 人关注 • 3 个回复 • 2777 次浏览 • 2019-01-08 10:17 • 来自相关话题

FSMC读写外部SRAM问题,求救

回复

问题困惑乌龟也会飞 回复了问题 • 1 人关注 • 1 个回复 • 55 次浏览 • 2019-01-07 12:10 • 来自相关话题

一步步实现stm32cube的usb之CUSTOM_HID当串口使用 (stm32F407discoery板)

软件教程hklevejkl 回复了问题 • 39 人关注 • 27 个回复 • 7552 次浏览 • 2018-12-31 03:15 • 来自相关话题

新版STM32 CubeMX 生成的代码无法通过编译

问题困惑BG4RFF 回复了问题 • 3 人关注 • 3 个回复 • 345 次浏览 • 2018-12-29 15:58 • 来自相关话题

初见STM32Cube MX

经验分享I_mURfather 发表了文章 • 2 个评论 • 759 次浏览 • 2018-12-26 23:28 • 来自相关话题

本人刚入坑STM32Cube MX不到一个月,这里留下自己的一些心得体会,帮助更多的新人入坑。由于本人水平有限,难免会有出错的地方,望大佬指点改正。初见STM32Cube MXNotice:这里使用的版本为MX5.0,最新版本,界面较老版本发生了很多改变,不过功能基本一致(大部分教程都是老版本的这也是为什么我要开坑这个教程的原因)STM32Cube MX是意法半导体(ST)公司开发的一款针对STM32系列芯片进行图形化配置的一个工具。也可以说是有一个GUI界面的配置工具。为什么要用Cube MX呢,难道直接在Keil MDK5上编程和Cube MX不一样吗?答案自然是否定的。在Cube MX上能完成的功能,可以直接在MDK5上完成。以前传统的编程方式有寄存器版和库函数版,而Cube MX是全新的一种方式,使用图形化界面配置底层硬件,用库函数,不过不是标准库,而是集成度更高,更简单的HAL库。还记得原子哥讲的STM32库函数版本,一开始就是教初学者新建Temple模板文件,但是使用Cube MX就完全不需要这么多繁琐的步骤,配置好你需要的资源之后,直接生成代码。看到这里是不是心动了,相信有了Cube MX这样一款利器能供让初学者们能够轻松入门STM32。以下内容来自机翻:“STM32CubeMX是一个图形工具,可以通过逐步过程轻松配置STM32微控制器并生成相应的初始化C代码。第一步是选择符合所需外设集的STMicroelectronics STM32微控制器。然后,用户必须配置每个所需的嵌入式软件,这要归功于引脚冲突解算器,时钟树设置帮助器,功耗计算器以及执行MCU外设配置(如GPIO或USART)和中间件堆栈(如USB或TCP / IP)。最后,用户基于所选择的配置启动初始化C代码的生成。此代码已准备好在多个开发环境中使用。用户代码保留在下一代代码中。”值得一提的是这个软件没有汉化版,只有英文版,所以英文不好的小伙伴只能一个个对着词典查了,反正这玩意说来说去就那几个单词,死记硬背下来难度比中学阅读理解还简单(滑稽)。打开Cube MX,最上面一排我们可以看到三个菜单栏:FLIE、WINDOW、HELP。第一个FLIE菜单用于打开或者新建工程;第二个WINDOW菜单用于打开或者关闭OUTPUT(目前为止我还没用到过);第三个菜单用于管理软件版本(就是检查更新啦),以及支持包的安装/更新(建议保持软件版本最新,支持包根据需要安装,有的工程可能用的是老板的支持包)。那么让我们新建一个工程吧,在FILE中点击NEW PROJECT,然后会进到一个列表里面去,这个列表用于选择主控芯片,我用的是STM32F427IIH6,所以我直接在搜索框中输入:“STM32F427”,选择后面出来的“STM32F427IIHx”。这时你将进入到如下界面:                                              在三个菜单选项下方出现了你的Cube MX资源管理器的路径,显示你现在使用的芯片以及工程名字。路径下方就是你的工作区辣~接着,让我们仔细来看看工作区:工作区有四个选项卡:Pinout & Configuration、Clock Configuration、Project Manager、Tools。Pinout&Configuration:这个选项卡是用来快速配置系统核心,GPIO分配,定时器配置,通讯方式等单片机资源的。通过工作区的图像我们可以看到左侧是一个可以拉动的菜单,右侧则是引脚图形化的一个快速预览,通过点击左侧菜单进行配置,右侧的引脚也会随之变化。当然你也可以提前布局好你的引脚,再去分配资源。以下是引脚颜色意义的说明:1已经分配好资源,并且启用的引脚会用绿色标出;带有大头针的引脚则是用户自己写有标签(USER LABER)类似于注释的作用;2黄色的引脚则是系统工作必需引脚,用户无法对其定义,比如:VDD、BOOT等;3橘黄色的引脚则是你已经对其模式进行了选择,比如ADC(模数转换),TIM4_CH2(定时器4通道2),但是没有在相应的地方配置系统资源,比如ADC中未配置打开ADC,TIM4没有打开CH2。经过细心的观察会发现在引脚的图形化界面上方有两个选项,一个是Pinout View(引脚显示),另外一个是System view(系统显示)。默认情况下都是显示的引脚情况。有些时候会忘记自己的资源怎么配置的,GPIO怎么分配的,那么不用一个个去左侧的菜单中寻找,选择System View即可快速对你已配置的资源进行查看。让我们进入第二个选项卡:Clock configuration。这是系统时钟配置界面:认识STM32Cube MX.pdf这个界面东西比较复杂,要了解的东西比较多,我会在后面配置工程的时候详细说明。最基本的看法就是从左往右,顺着箭头看。接下来就是第三个选项卡了:Project Manager。在这个选项卡中是用于管理生成我们工程文件的设置。如下图:值得一提的是在桌面建立工程的时候一定要注意自己的计算机名称是否含有中文,如果含有的话那么会在生成工程的时候失败。    第四个选项卡,Tools。内容如下:暂时还未用到,如果用到以后会做详细说明。这一章节就这样结束了,撒哟啦啦~PS:由于图片在我这里不能正常显示,所以我上传了一份PDF文件(其实图片看不看无所谓啦~) 查看全部

本人刚入坑STM32Cube MX不到一个月,这里留下自己的一些心得体会,帮助更多的新人入坑。

由于本人水平有限,难免会有出错的地方,望大佬指点改正。

初见STM32Cube MX

Notice:这里使用的版本为MX5.0,最新版本,界面较老版本发生了很多改变,不过功能基本一致(大部分教程都是老版本的这也是为什么我要开坑这个教程的原因)

STM32Cube MX是意法半导体(ST)公司开发的一款针对STM32系列芯片进行图形化配置的一个工具。也可以说是有一个GUI界面的配置工具。

为什么要用Cube MX呢,难道直接在Keil MDK5上编程和Cube MX不一样吗?答案自然是否定的。在Cube MX上能完成的功能,可以直接在MDK5上完成。以前传统的编程方式有寄存器版和库函数版,而Cube MX是全新的一种方式,使用图形化界面配置底层硬件,用库函数,不过不是标准库,而是集成度更高,更简单的HAL库。还记得原子哥讲的STM32库函数版本,一开始就是教初学者新建Temple模板文件,但是使用Cube MX就完全不需要这么多繁琐的步骤,配置好你需要的资源之后,直接生成代码。看到这里是不是心动了,相信有了Cube MX这样一款利器能供让初学者们能够轻松入门STM32。以下内容来自机翻:

STM32CubeMX是一个图形工具,可以通过逐步过程轻松配置STM32微控制器并生成相应的初始化C代码。

第一步是选择符合所需外设集的STMicroelectronics STM32微控制器。

然后,用户必须配置每个所需的嵌入式软件,这要归功于引脚冲突解算器,时钟树设置帮助器,功耗计算器以及执行MCU外设配置(如GPIO或USART)和中间件堆栈(如USB或TCP / IP)。

最后,用户基于所选择的配置启动初始化C代码的生成。此代码已准备好在多个开发环境中使用。用户代码保留在下一代代码中。

值得一提的是这个软件没有汉化版,只有英文版,所以英文不好的小伙伴只能一个个对着词典查了,反正这玩意说来说去就那几个单词,死记硬背下来难度比中学阅读理解还简单(滑稽)。

打开Cube MX,最上面一排我们可以看到三个菜单栏:FLIEWINDOWHELP

第一个FLIE菜单用于打开或者新建工程;第二个WINDOW菜单用于打开或者关闭OUTPUT(目前为止我还没用到过);第三个菜单用于管理软件版本(就是检查更新啦),以及支持包的安装/更新(建议保持软件版本最新,支持包根据需要安装,有的工程可能用的是老板的支持包)。

那么让我们新建一个工程吧,在FILE中点击NEW PROJECT,然后会进到一个列表里面去,这个列表用于选择主控芯片,我用的是STM32F427IIH6,所以我直接在搜索框中输入:“STM32F427”,选择后面出来的“STM32F427IIHx”。这时你将进入到如下界面:

                                             

在三个菜单选项下方出现了你的Cube MX资源管理器的路径,显示你现在使用的芯片以及工程名字。

路径下方就是你的工作区辣~

接着,让我们仔细来看看工作区:工作区有四个选项卡:Pinout & ConfigurationClock ConfigurationProject ManagerTools

Pinout&Configuration:这个选项卡是用来快速配置系统核心,GPIO分配,定时器配置,通讯方式等单片机资源的。通过工作区的图像我们可以看到左侧是一个可以拉动的菜单,右侧则是引脚图形化的一个快速预览,通过点击左侧菜单进行配置,右侧的引脚也会随之变化。当然你也可以提前布局好你的引脚,再去分配资源。

以下是引脚颜色意义的说明:1已经分配好资源,并且启用的引脚会用绿色标出;带有大头针的引脚则是用户自己写有标签(USER LABER)类似于注释的作用;2黄色的引脚则是系统工作必需引脚,用户无法对其定义,比如:VDD、BOOT等;3橘黄色的引脚则是你已经对其模式进行了选择,比如ADC(模数转换),TIM4_CH2(定时器4通道2),但是没有在相应的地方配置系统资源,比如ADC中未配置打开ADC,TIM4没有打开CH2。

经过细心的观察会发现在引脚的图形化界面上方有两个选项,一个是Pinout View(引脚显示),另外一个是System view(系统显示)。默认情况下都是显示的引脚情况。有些时候会忘记自己的资源怎么配置的,GPIO怎么分配的,那么不用一个个去左侧的菜单中寻找,选择System View即可快速对你已配置的资源进行查看。

让我们进入第二个选项卡:Clock configuration。这是系统时钟配置界面:

认识STM32Cube MX.pdf

这个界面东西比较复杂,要了解的东西比较多,我会在后面配置工程的时候详细说明。最基本的看法就是从左往右,顺着箭头看。

接下来就是第三个选项卡了:Project Manager。在这个选项卡中是用于管理生成我们工程文件的设置。如下图:

值得一提的是在桌面建立工程的时候一定要注意自己的计算机名称是否含有中文,如果含有的话那么会在生成工程的时候失败。

 

 

 

 

第四个选项卡,Tools。内容如下:

暂时还未用到,如果用到以后会做详细说明。

这一章节就这样结束了,撒哟啦啦~


PS:由于图片在我这里不能正常显示,所以我上传了一份PDF文件(其实图片看不看无所谓啦~)


Stm32F103RCT6硬件i2c HAL库函数bug

经验分享君莫笑 发表了文章 • 1 个评论 • 194 次浏览 • 2018-12-25 09:24 • 来自相关话题

问题描述 使用stm32f103rcT6芯片的i2c引脚PB6 PB7连接EEROM AT24C02进行EEROM读写时调用 HAL_I2C_Mem_Write和HAL_I2C_Mem_Read函数进行读写操作不能成功,使用示波器测的引脚也无波形产生,最终在函数void HAL_I2C_MspInit(I2C_HandleTypeDef* i2cHandle)中发现其代码如下void HAL_I2C_MspInit(I2C_HandleTypeDef* i2cHandle){  GPIO_InitTypeDef GPIO_InitStruct;  if(i2cHandle->Instance==I2C1)  {  /* USER CODE BEGIN I2C1_MspInit 0 */  /* USER CODE END I2C1_MspInit 0 */      /**I2C1 GPIO Configuration        PB6     ------> I2C1_SCL    PB7     ------> I2C1_SDA     */    GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;    GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);    /* I2C1 clock enable */    __HAL_RCC_I2C1_CLK_ENABLE();  /* USER CODE BEGIN I2C1_MspInit 1 */  /* USER CODE END I2C1_MspInit 1 */  }}将其更改为如下 即先使能时钟 再初始化引脚问题得以解决可以正常读写EEROMvoid HAL_I2C_MspInit(I2C_HandleTypeDef* i2cHandle){  GPIO_InitTypeDef GPIO_InitStruct;  if(i2cHandle->Instance==I2C1)  {  /* USER CODE BEGIN I2C1_MspInit 0 */  /* USER CODE END I2C1_MspInit 0 */  /* I2C1 clock enable */   __HAL_RCC_I2C1_CLK_ENABLE();    /**I2C1 GPIO Configuration        PB6     ------> I2C1_SCL    PB7     ------> I2C1_SDA     */    GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;    GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);      /* USER CODE BEGIN I2C1_MspInit 1 */  /* USER CODE END I2C1_MspInit 1 */  }}希望对后面遇到的人有用 by荒野大嫖客 查看全部

问题描述 使用stm32f103rcT6芯片的i2c引脚PB6 PB7连接EEROM AT24C02进行EEROM读写时调用 HAL_I2C_Mem_Write和HAL_I2C_Mem_Read函数进行读写操作不能成功,使用示波器测的引脚也无波形产生,最终在函数void HAL_I2C_MspInit(I2C_HandleTypeDef* i2cHandle)中发现其代码如下

void HAL_I2C_MspInit(I2C_HandleTypeDef* i2cHandle)

{


  GPIO_InitTypeDef GPIO_InitStruct;

  if(i2cHandle->Instance==I2C1)

  {

  /* USER CODE BEGIN I2C1_MspInit 0 */


  /* USER CODE END I2C1_MspInit 0 */

  

    /**I2C1 GPIO Configuration    

    PB6     ------> I2C1_SCL

    PB7     ------> I2C1_SDA 

    */

    GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;

    GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;

    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;

    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);


    /* I2C1 clock enable */

    __HAL_RCC_I2C1_CLK_ENABLE();

  /* USER CODE BEGIN I2C1_MspInit 1 */


  /* USER CODE END I2C1_MspInit 1 */

  }

}

将其更改为如下 即先使能时钟 再初始化引脚问题得以解决可以正常读写EEROM

void HAL_I2C_MspInit(I2C_HandleTypeDef* i2cHandle)

{


  GPIO_InitTypeDef GPIO_InitStruct;

  if(i2cHandle->Instance==I2C1)

  {

  /* USER CODE BEGIN I2C1_MspInit 0 */


  /* USER CODE END I2C1_MspInit 0 */

  /* I2C1 clock enable */

  __HAL_RCC_I2C1_CLK_ENABLE();

    /**I2C1 GPIO Configuration    

    PB6     ------> I2C1_SCL

    PB7     ------> I2C1_SDA 

    */

    GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;

    GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;

    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;

    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);


    

  /* USER CODE BEGIN I2C1_MspInit 1 */


  /* USER CODE END I2C1_MspInit 1 */

  }

}

希望对后面遇到的人有用 by荒野大嫖客


请问STM32写flash怎么总是写不进?

问题困惑§MiCE§ 回复了问题 • 3 人关注 • 2 个回复 • 1793 次浏览 • 2018-12-24 21:19 • 来自相关话题

The code is successfully geberated under

问题困惑admin 回复了问题 • 2 人关注 • 1 个回复 • 60 次浏览 • 2018-12-21 22:29 • 来自相关话题

用STM32CubeMX 者.26.1生成代码后SRC文件夹不见了

问题困惑董侠™ 回复了问题 • 4 人关注 • 3 个回复 • 553 次浏览 • 2018-12-21 14:09 • 来自相关话题

一个实用的按键扫描方案

经验分享乌龟也会飞 发表了文章 • 3 个评论 • 185 次浏览 • 2018-12-21 09:00 • 来自相关话题

由于项目需要外置一个控制盒通过按键来控制系统移动、启动功能,其中感觉所写的按键部分还算实用就分享出来,如果更好的方案不妨给出指点和分享出来大家都学习学习 以下文章按键弹起状态为1 按下状态为0 基本原理 机械按键由于其特殊性在按下或者弹起的时刻会有机械抖动引起误差,会出现采集状态在0和1之间来回切换,直到稳定状态。我所设计的系统中有4个按键上行按键UpKey,停止按键StopKey,下行按键DownKey活启动/停止按键OnOffKey,设计思路就是不停的扫描对应的IO口状态步骤1,开启一个定时器频率为1000Hz(周期为1ms)的定时器,在其回调函数中进行对应的IO口扫描 //开启定时器中断 频率1000Hz  HAL_TIM_Base_Start_IT(&htim6);步骤二定义一个按键标志数组,和一个按键灵敏度控制变量uint8_t KeyMask[4] = {0x0}; //分别对应上行按键 停止按键 下行按键 启动/关闭按键状态 0x01对应按键按下 0x00对应无按键按下状态#define KEYMASK 0x0000ffff   //定义按键灵敏度,即当按键按下处于稳定状态0达到多少ms后才算按键按下 16ms可以根据自己所需要进行调节步骤三编写中断定时器回调函数void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){ //缓存32次按键扫描结果,每次扫描保存左移一位 static uint32_t KeyUpCoder = 0xffffffff; //按键没有按下时刻为高电平状态 static uint32_t KeyStopCoder = 0xffffffff; static uint32_t KeyDownCoder = 0xffffffff; static uint32_t KeySysCoder = 0xffffffff; if(htim->Instance == htim6.Instance){                //判断定时器中断触发源 //左移一位,剔除最早采集的状态准备加入最新的采集状态 KeyUpCoder   <<= 1; KeyStopCoder <<= 1; KeyDownCoder <<= 1; KeySysCoder  <<= 1; //采样按键值 KeyUpCoder   |= HAL_GPIO_ReadPin(KeyUp_GPIO_Port,KeyUp_Pin); KeyStopCoder |= HAL_GPIO_ReadPin(KeyStop_GPIO_Port,KeyStop_Pin); KeyDownCoder |= HAL_GPIO_ReadPin(KeyDown_GPIO_Port,KeyDown_Pin); KeySysCoder  |= HAL_GPIO_ReadPin(KeySys_GPIO_Port,KeySys_Pin); //进行按键解析是否存在按键, //首先判断之前是否发生过按键按下情况,且主程序是否完成了对应按键的程序处理 //如果主程序还未完成相关程序处理,则本次按键无效 //KeyMask代表按键是否有效,且表达了主程序是否完成了相关服务程序的                 //通过判断只有连续出现了大于等于灵敏度次稳定状态电平,才会判断定按键按下一般机械抖动在10ms左右,可根据自己需要调动                //在主程序中通过判断KeyMask来识别是否有按键按下 完成相关服务函数处理同时需要释放KeyMask,来开始新的一次扫描 //判断上行按键 if((!KeyMask[0])&&((KeyUpCoder&KEYMASK)== 0x00000000)) //完成消抖判断 KeyMask[0] = 0x01; //判断停止按键 if((!KeyMask[1])&&((KeyStopCoder&KEYMASK)== 0x00000000)) KeyMask[1] = 0x01; //判断下行按键 if((!KeyMask[2])&&((KeyDownCoder&KEYMASK)== 0x00000000)) KeyMask[2] = 0x01; //判断系统按键 if((!KeyMask[3])&&((KeySysCoder&KEYMASK)== 0x00000000)) KeyMask[3] = 0x01; }}by 荒野大嫖客 查看全部

由于项目需要外置一个控制盒通过按键来控制系统移动、启动功能,其中感觉所写的按键部分还算实用就分享出来,如果更好的方案不妨给出指点和分享出来大家都学习学习 以下文章按键弹起状态为1 按下状态为0 

基本原理 机械按键由于其特殊性在按下或者弹起的时刻会有机械抖动引起误差,会出现采集状态在0和1之间来回切换,直到稳定状态。我所设计的系统中有4个按键上行按键UpKey,停止按键StopKey,下行按键DownKey活启动/停止按键OnOffKey,设计思路就是不停的扫描对应的IO口状态

步骤1,开启一个定时器频率为1000Hz(周期为1ms)的定时器,在其回调函数中进行对应的IO口扫描

 //开启定时器中断 频率1000Hz

  HAL_TIM_Base_Start_IT(&htim6);

步骤二定义一个按键标志数组,和一个按键灵敏度控制变量

uint8_t KeyMask[4] = {0x0}; //分别对应上行按键 停止按键 下行按键 启动/关闭按键状态 0x01对应按键按下 0x00对应无按键按下状态

#define KEYMASK 0x0000ffff   //定义按键灵敏度,即当按键按下处于稳定状态0达到多少ms后才算按键按下 16ms可以根据自己所需要进行调节

步骤三编写中断定时器回调函数

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){

//缓存32次按键扫描结果,每次扫描保存左移一位

static uint32_t KeyUpCoder = 0xffffffff; //按键没有按下时刻为高电平状态

static uint32_t KeyStopCoder = 0xffffffff;

static uint32_t KeyDownCoder = 0xffffffff;

static uint32_t KeySysCoder = 0xffffffff;

if(htim->Instance == htim6.Instance){                //判断定时器中断触发源

//左移一位,剔除最早采集的状态准备加入最新的采集状态

KeyUpCoder   <<= 1;

KeyStopCoder <<= 1;

KeyDownCoder <<= 1;

KeySysCoder  <<= 1;

//采样按键值

KeyUpCoder   |= HAL_GPIO_ReadPin(KeyUp_GPIO_Port,KeyUp_Pin);

KeyStopCoder |= HAL_GPIO_ReadPin(KeyStop_GPIO_Port,KeyStop_Pin);

KeyDownCoder |= HAL_GPIO_ReadPin(KeyDown_GPIO_Port,KeyDown_Pin);

KeySysCoder  |= HAL_GPIO_ReadPin(KeySys_GPIO_Port,KeySys_Pin);

//进行按键解析是否存在按键,

//首先判断之前是否发生过按键按下情况,且主程序是否完成了对应按键的程序处理

//如果主程序还未完成相关程序处理,则本次按键无效

//KeyMask代表按键是否有效,且表达了主程序是否完成了相关服务程序的 

                //通过判断只有连续出现了大于等于灵敏度次稳定状态电平,才会判断定按键按下一般机械抖动在10ms左右,可根据自己需要调动

                //在主程序中通过判断KeyMask来识别是否有按键按下 完成相关服务函数处理同时需要释放KeyMask,来开始新的一次扫描

//判断上行按键

if((!KeyMask[0])&&((KeyUpCoder&KEYMASK)== 0x00000000)) //完成消抖判断

KeyMask[0] = 0x01;

//判断停止按键

if((!KeyMask[1])&&((KeyStopCoder&KEYMASK)== 0x00000000))

KeyMask[1] = 0x01;

//判断下行按键

if((!KeyMask[2])&&((KeyDownCoder&KEYMASK)== 0x00000000))

KeyMask[2] = 0x01;

//判断系统按键

if((!KeyMask[3])&&((KeySysCoder&KEYMASK)== 0x00000000))

KeyMask[3] = 0x01;

}

}

by 荒野大嫖客

HAL_CAN_AddTxMessage 发送后CAN盒无法接收

回复

问题困惑Rainner 回复了问题 • 1 人关注 • 1 个回复 • 215 次浏览 • 2018-12-20 18:59 • 来自相关话题