本帖最后由 21ic小喇叭 于 2016-1-19 09:32 编辑
还有两个帖子点击查看哟~~~https://bbs.21ic.com/icview-1239774-1-2.html
https://bbs.21ic.com/icview-1239682-1-1.html
折腾了两个晚上,一天安装STLINK后串口驱动始终装不上,由于WIN7 64位 GHOST版的原因,缺少组件,找了N多方法无效,参照此贴解决。http://www.stmcu.org/module/forum/thread-602290-1-1.html,但usbser.sys,mdmcpq.inf 这两个文件不同系统,是不一样的,切记。
一步步操作STM32CubeMX软件,导出的HAL库是很强大,但细细摸清楚也很烦锁,感觉不利于初学者,有两种接口,一种是宏扩展出来的,可快速操作到实例化指针对应的寄存器,一种很复杂的结构体嵌套配置函数,层次较多,最终底层是调用第一种接口的宏来操作寄存口。感觉MCU级别的库没必要这么复杂,反而麻烦,效率也不高。下面进入正题 :
1,在呼吸的流水灯,故名思义:呼吸灯 + 流水灯
呼吸灯原理:就是像呼吸一样,慢吸气,逐渐变亮,慢呼气,逐渐变暗。但灯肉眼不能看出闪烁,否则就很难看了。
开发板上带了LED,如果IO口常低就是灯亮,常高就是灯灭,要实现明暗变化,就需要占空比调制,以固定频率(人眼不能分辨的,人眼能分辨的为24Hz,当然因人而异,不排除具最强大脑的超人),减少灯亮的时间,亮度就会变暗。根据此原理,使用定时器的PWM生成固定频率的方波,占空比由高变低,然后变高,完成呼吸的一个循环。PWM频率取值100Hz。 另开发板的LED灯,内眼直接看,光源太聚集,刺眼且效果不太好看,最好加灯罩类的散光处理。简单处理,盖一张纸巾即可,效果也就一般。 很遗憾,一个都没连到定时器的PWM通道。只能变相的操作,利用定时器1的比较中断(PWM电平改变时刻),和溢出中断(定时周期到,即频率控制),做软件的PWM模拟,呼吸完一个,放松,再呼吸一个。 3,为了以后调试方便,还面要一个调试输出口,通常都习惯用串口打印输出(printf)。 由上图可知连接到STLK串口的引脚为PB10,PB11。 由上图数据手册查询可知,串口使用的是USART3 4,建立工程 启动STM32CubeMX 点击New Project. 选好开发板型号后双击,定时器使用输出比较模式,但不使能输出,利用比较,溢出中断产生软件的PWM。USART3选择Asynchronous其他选择默认即可。 点击上面的Configration会看到使能的外设设置,先配置定时器(点击上图中的小闹钟)的溢出中断,比较中断,定时器的定时时间,随后我们用编译器的宏自己计算。串口设置起用默认。 保存自行设置存储路径,在Project setting设置导出的KEIL工程,并导出。注意时钟我们没有配置,系统默认的是16M,芯片这块的手册我没有看,暂时就不管了。串口默认的波特率是115200,可以在上图的USART3中双击查看。 在生成工程配置的时候,最好配置下图红框选项,一个是项目源文件清晰,还有个是不勾初初化代码不全,我的定时器里时钟使能,NVIC中断配置没有生成。 5,源代码添加 1)调试打印口,添加图片下面代码,在程序中即可直接使用printf函数 2)定时时间计算及填写 定时器全能有点特别,库中没有同时使能溢出,比较中断的驱动 __HAL_TIM_ENABLE_IT(&htim1, TIM_IT_CC1);//ÌṩµÄÇý¶¯½Ó¿ÚûÓÐÏֳɵļȿª±È½ÏÖжϣ¬ÓÖ¿ªÒç³öÖÐ¶Ï HAL_TIM_Base_Start_IT(&htim1); 3)呼吸灯节奏控制的宏 4)中断代码 void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { /* Prevent unused argument(s) compilation warning */
if(led_num >3) led_num = 0; switch(led_num) { case 0: HAL_GPIO_WritePin(GPIOG,GPIO_PIN_6,GPIO_PIN_RESET); break; case 1: HAL_GPIO_WritePin(GPIOD,GPIO_PIN_4,GPIO_PIN_RESET); break; case 2: HAL_GPIO_WritePin(GPIOD,GPIO_PIN_5,GPIO_PIN_RESET); break; case 3: HAL_GPIO_WritePin(GPIOK,GPIO_PIN_3,GPIO_PIN_RESET); break; }
cycle_n++; if(cycle_n < level_cycle) { return; } cycle_n = 0;
if(brint_s == 0) { if(brint_c >= level_max)//´ïµ½×î´óÁÁ¶È { brint_c -= level_step; brint_s = 1; } else//δ´ïµ½×î´óÁÁ¶È£¬¼ÌÐø±äÁÁ { brint_c += level_step; } } else { if(brint_c <= level_min)//´ïµ½×îСÁÁ¶È { brint_c += level_step; brint_s = 0; led_num++; HAL_GPIO_WritePin(GPIOG,GPIO_PIN_6,GPIO_PIN_SET); HAL_GPIO_WritePin(GPIOD,GPIO_PIN_4,GPIO_PIN_SET); HAL_GPIO_WritePin(GPIOD,GPIO_PIN_5,GPIO_PIN_SET); HAL_GPIO_WritePin(GPIOK,GPIO_PIN_3,GPIO_PIN_SET); } else { brint_c -= level_step; } } __HAL_TIM_SET_COMPARE(&htim1,TIM_CHANNEL_1,brint_c);
/* NOTE : This function Should not be modified, when the callback is needed, the __HAL_TIM_PeriodElapsedCallback could be implemented in the user file */ }
void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim) { /* Prevent unused argument(s) compilation warning */ switch(led_num) { case 0: HAL_GPIO_WritePin(GPIOG,GPIO_PIN_6,GPIO_PIN_SET); break; case 1: HAL_GPIO_WritePin(GPIOD,GPIO_PIN_4,GPIO_PIN_SET); break; case 2: HAL_GPIO_WritePin(GPIOD,GPIO_PIN_5,GPIO_PIN_SET); break; case 3: HAL_GPIO_WritePin(GPIOK,GPIO_PIN_3,GPIO_PIN_SET); break; } /* NOTE : This function Should not be modified, when the callback is needed, the __HAL_TIM_PWM_PulseFinishedCallback could be implemented in the user file */ } /* USER CODE END 1 */ 最后上传工程源码。有兴趣的可以看看,效果不是很好,做的有点粗糙,在暗区和亮区的不同等级时间调成不一样,效果可能会好点,这程序不支持,而且暗区的时候LED还是会感觉闪,可能偏暗的时候还要加快频率。超过5M了还得分卷。
test.part01.rar
(2.93 MB)
|