完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
本帖最后由 黑皮男 于 2016-11-7 18:48 编辑 LED灯实验堪称单片机界的hello world(借用他人语)。下面来用Nucleo-F412进行第一弹测试--流水灯实验。 板载3颗3色LED,如果只点亮一个灯,感觉有点浪费,呵呵。索性就来一个流水灯吧。下面是硬件连接: LD1------PB0 LD2------PB7 LD3------PB14 第一步首先建立好工程,个人喜欢移植,虽然可以直接用CubeMX生成工程。新建工程目录如下: app: 应用程序层 bsp:外围驱动 CMSIS和STM32F4xx_HAL_Driver直接从官方库拷贝,注意需把stm32f4xx_hal_msp_template.c,stm32f4xx_hal_timebase_rtc_alarm_template.c,stm32f4xx_hal_timebase_rtc_wakeup_template.c,stm32f4xx_hal_timebase_tim_template.c这几个文件删除,如果加入到工程中会编译通不过,这里不研究这几个文件的具体作用。 sys:系统框架层,这里主要实现系统运行相关的代码,主要是裸机代码,后续会在此文件夹内实现合作式调度器。 user:main.c以及中断入口文件在此文件夹 EWARM: IAR工程目录 接着建立IAR工程,工程结构如下: 设置头文件路径,及一些宏定义 第二步,代码分析 首先看一下main函数中的实现结构 int main(void) { HAL_Init(); /* Configure the system clock to 100 MHz */ SystemClock_Config(); /* Add your application code here */ disp_init(); /* Infinite loop */ while (1) { disp_task(); } } 接下来编写led的bsp驱动,以及显示程序,这里使用一个数组管理LED的各个IO的对应关系 GPIO_TypeDef * LED_PORT[LEDn]={LED1_GPIO_PORT, LED2_GPIO_PORT, LED3_GPIO_PORT}; const UINT16_T LED_PIN[LEDn]={LED1_GPIO_PIN, LED2_GPIO_PIN, LED3_GPIO_PIN}; LED IO口初始化,3个灯都是高电平亮,所以初始化为推挽输出,输出低电平,默认不亮。 void led_init(Led_TypeDef led){ GPIO_InitTypeDef GPIO_InitStruct; LED_GPIO_CLK_ENABLE(led); GPIO_InitStruct.Pin = LED_PIN[led]; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; HAL_GPIO_Init(LED_PORT[led], &GPIO_InitStruct); HAL_GPIO_WritePin(LED_PORT[led], LED_PIN[led],GPIO_PIN_RESET); } 下面是led灯的亮灭和翻转。 void led_on(Led_TypeDef led){ HAL_GPIO_WritePin(LED_PORT[led], LED_PIN[led], GPIO_PIN_SET); } void led_off(Led_TypeDef led){ HAL_GPIO_WritePin(LED_PORT[led], LED_PIN[led], GPIO_PIN_RESET); } void led_toggle(Led_TypeDef led){ HAL_GPIO_TogglePin(LED_PORT[led],LED_PIN[led]); } 进行显示前的初始化 void disp_init(void){ led_init(LED1); led_init(LED2); led_init(LED3); leds = 0; led_bits = 0; } leds是一个保存led状态的全局变量,每一位对应一个led灯的状态,这里只用里bit0,1,2三位。led_bits是用来实现led灯的流水灯效果。disp_stream实现了led流水效果的函数。 void disp_stream(void){ leds = (1< led_bits++; if(led_bits>=LEDn){ led_bits = 0; } } disp_update更新led的显示状态 void disp_update(void){ UINT8_T i; UINT16_T temp = leds; for(i=0;i if(temp&0x01){ led_on((Led_TypeDef)i); }else{ led_off((Led_TypeDef)i); } temp>>=1; } } 每500ms更改以此led灯的状态,程序运行后可以看到led灯循环移动的效果,500ms移动一次 void disp_task(void){ disp_stream(); disp_update(); delay_ms(500); } |
|
相关推荐
1 个讨论
|
|
你正在撰写讨论
如果你是对讨论或其他讨论精选点评或询问,请使用“评论”功能。
1470 浏览 1 评论
AD7686芯片不传输数据给STM32,但是手按住就会有数据。
1405 浏览 3 评论
3150 浏览 0 评论
如何解决MPU-9250与STM32通讯时,出现HAL_ERROR = 0x01U
1543 浏览 1 评论
hal库中i2c卡死在HAL_I2C_Master_Transmit
1975 浏览 1 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-4 07:28 , Processed in 0.620589 second(s), Total 66, Slave 49 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号