微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 流水灯实验(试用第一弹)

流水灯实验(试用第一弹)

时间:10-02 整理:3721RD 点击:

   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);

        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<LEDn;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);


}


修改一点也得审核,看来我的等级太低了

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top