赞
踩
目录
- //led.h
-
- #ifndef _LED_H
- #define _LED_H
- #include "./SYSTEM/sys/sys.h"
-
-
- /******************************************************************************************/
- /* 引脚 定义 */
-
- #define LED0_GPIO_PORT GPIOB
- #define LED0_GPIO_PIN GPIO_PIN_5
- #define LED0_GPIO_CLK_ENABLE() do{ __HAL_RCC_GPIOB_CLK_ENABLE(); }while(0) /* PB口时钟使能 */
-
- #define LED1_GPIO_PORT GPIOE
- #define LED1_GPIO_PIN GPIO_PIN_5
- #define LED1_GPIO_CLK_ENABLE() do{ __HAL_RCC_GPIOE_CLK_ENABLE(); }while(0) /* PE口时钟使能 */
-
- /******************************************************************************************/
- /* LED端口定义 */
- #define LED0(x) do{ x ? \
- HAL_GPIO_WritePin(LED0_GPIO_PORT, LED0_GPIO_PIN, GPIO_PIN_SET) : \
- HAL_GPIO_WritePin(LED0_GPIO_PORT, LED0_GPIO_PIN, GPIO_PIN_RESET); \
- }while(0) /* LED0翻转 */
-
- #define LED1(x) do{ x ? \
- HAL_GPIO_WritePin(LED1_GPIO_PORT, LED1_GPIO_PIN, GPIO_PIN_SET) : \
- HAL_GPIO_WritePin(LED1_GPIO_PORT, LED1_GPIO_PIN, GPIO_PIN_RESET); \
- }while(0) /* LED1翻转 */
-
- /* LED取反定义 */
- #define LED0_TOGGLE() do{ HAL_GPIO_TogglePin(LED0_GPIO_PORT, LED0_GPIO_PIN); }while(0) /* 翻转LED0 */
- #define LED1_TOGGLE() do{ HAL_GPIO_TogglePin(LED1_GPIO_PORT, LED1_GPIO_PIN); }while(0) /* 翻转LED1 */
-
- /******************************************************************************************/
- /* 外部接口函数*/
- void led_init(void); /* 初始化 */
-
- #endif
- //led.c
-
- void led_init(void)
- {
- GPIO_InitTypeDef gpio_init_struct;
- LED0_GPIO_CLK_ENABLE(); /* LED0时钟使能 */
- LED1_GPIO_CLK_ENABLE(); /* LED1时钟使能 */
-
- gpio_init_struct.Pin = LED0_GPIO_PIN; /* LED0引脚 */
- gpio_init_struct.Mode = GPIO_MODE_OUTPUT_PP; /* 推挽输出 */
- gpio_init_struct.Pull = GPIO_PULLUP; /* 上拉 */
- gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH; /* 高速 */
- HAL_GPIO_Init(LED0_GPIO_PORT, &gpio_init_struct); /* 初始化LED0引脚 */
-
- gpio_init_struct.Pin = LED1_GPIO_PIN; /* LED1引脚 */
- HAL_GPIO_Init(LED1_GPIO_PORT, &gpio_init_struct); /* 初始化LED1引脚 */
-
-
- LED0(1); /* 关闭 LED0 */
- LED1(1); /* 关闭 LED1 */
- }
在led初始化中需要使能对应GPIO的时钟,设置GPIO的模式推完输出,默认上拉。
由于屏和主板都是使用正点原子的产品,引脚,屏的资源已经固定,所以采用正点原子的源码略做修改,大家有需要可以去看正点原子的资料。
- //key.h
- #ifndef __KEY_H
- #define __KEY_H
-
- #include "./SYSTEM/sys/sys.h"
-
- /******************************************************************************************/
- /* 引脚 定义 */
-
- #define KEY0_GPIO_PORT GPIOE
- #define KEY0_GPIO_PIN GPIO_PIN_4
- #define KEY0_GPIO_CLK_ENABLE() do{ __HAL_RCC_GPIOE_CLK_ENABLE(); }while(0) /* PE口时钟使能 */
-
- #define KEY1_GPIO_PORT GPIOE
- #define KEY1_GPIO_PIN GPIO_PIN_3
- #define KEY1_GPIO_CLK_ENABLE() do{ __HAL_RCC_GPIOE_CLK_ENABLE(); }while(0) /* PE口时钟使能 */
-
- #define KEY2_GPIO_PORT GPIOE
- #define KEY2_GPIO_PIN GPIO_PIN_2
- #define KEY2_GPIO_CLK_ENABLE() do{ __HAL_RCC_GPIOE_CLK_ENABLE(); }while(0) /* PE口时钟使能 */
-
- #define WKUP_GPIO_PORT GPIOA
- #define WKUP_GPIO_PIN GPIO_PIN_0
- #define WKUP_GPIO_CLK_ENABLE() do{ __HAL_RCC_GPIOA_CLK_ENABLE(); }while(0) /* PA口时钟使能 */
-
- /******************************************************************************************/
-
- #define KEY0 HAL_GPIO_ReadPin(KEY0_GPIO_PORT, KEY0_GPIO_PIN) /* 读取KEY0引脚 */
- #define KEY1 HAL_GPIO_ReadPin(KEY1_GPIO_PORT, KEY1_GPIO_PIN) /* 读取KEY1引脚 */
- #define KEY2 HAL_GPIO_ReadPin(KEY2_GPIO_PORT, KEY2_GPIO_PIN) /* 读取KEY2引脚 */
- #define WK_UP HAL_GPIO_ReadPin(WKUP_GPIO_PORT, WKUP_GPIO_PIN) /* 读取WKUP引脚 */
-
-
- #define KEY0_PRES 1 /* KEY0按下 */
- #define KEY1_PRES 2 /* KEY1按下 */
- #define KEY2_PRES 3 /* KEY2按下 */
- #define WKUP_PRES 4 /* KEY_UP按下(即WK_UP) */
-
- void key_init(void); /* 按键初始化函数 */
- uint8_t key_scan(uint8_t mode); /* 按键扫描函数 */
-
- #endif
- //key.c
- #include "./BSP/KEY/key.h"
- #include "./SYSTEM/delay/delay.h"
-
-
- /**
- * @brief 按键初始化函数
- * @param 无
- * @retval 无
- */
- void key_init(void)
- {
- GPIO_InitTypeDef gpio_init_struct;
- KEY0_GPIO_CLK_ENABLE(); /* KEY0时钟使能 */
- KEY1_GPIO_CLK_ENABLE(); /* KEY1时钟使能 */
- KEY2_GPIO_CLK_ENABLE(); /* KEY2时钟使能 */
- WKUP_GPIO_CLK_ENABLE(); /* WKUP时钟使能 */
-
- gpio_init_struct.Pin = KEY0_GPIO_PIN; /* KEY0引脚 */
- gpio_init_struct.Mode = GPIO_MODE_INPUT; /* 输入 */
- gpio_init_struct.Pull = GPIO_PULLUP; /* 上拉 */
- gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH; /* 高速 */
- HAL_GPIO_Init(KEY0_GPIO_PORT, &gpio_init_struct); /* KEY0引脚模式设置,上拉输入 */
-
- gpio_init_struct.Pin = KEY1_GPIO_PIN; /* KEY1引脚 */
- gpio_init_struct.Mode = GPIO_MODE_INPUT; /* 输入 */
- gpio_init_struct.Pull = GPIO_PULLUP; /* 上拉 */
- gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH; /* 高速 */
- HAL_GPIO_Init(KEY1_GPIO_PORT, &gpio_init_struct); /* KEY1引脚模式设置,上拉输入 */
-
- gpio_init_struct.Pin = KEY2_GPIO_PIN; /* KEY2引脚 */
- gpio_init_struct.Mode = GPIO_MODE_INPUT; /* 输入 */
- gpio_init_struct.Pull = GPIO_PULLUP; /* 上拉 */
- gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH; /* 高速 */
- HAL_GPIO_Init(KEY2_GPIO_PORT, &gpio_init_struct); /* KEY2引脚模式设置,上拉输入 */
-
- gpio_init_struct.Pin = WKUP_GPIO_PIN; /* WKUP引脚 */
- gpio_init_struct.Mode = GPIO_MODE_INPUT; /* 输入 */
- gpio_init_struct.Pull = GPIO_PULLDOWN; /* 下拉 */
- gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH; /* 高速 */
- HAL_GPIO_Init(WKUP_GPIO_PORT, &gpio_init_struct); /* WKUP引脚模式设置,下拉输入 */
-
- }
-
-
- uint8_t key_scan(uint8_t mode)
- {
- static uint8_t key_up = 1; /* 按键按松开标志 */
- uint8_t keyval = 0;
-
- if (mode) key_up = 1; /* 支持连按 */
-
- if (key_up && (KEY0 == 0 || KEY1 == 0 || KEY2 == 0 || WK_UP == 1)) /* 按键松开标志为1, 且有任意一个按键按下了 */
- {
- delay_ms(10); /* 去抖动 */
- key_up = 0;
-
- if (KEY0 == 0) keyval = KEY0_PRES;
-
- if (KEY1 == 0) keyval = KEY1_PRES;
-
- if (KEY2 == 0) keyval = KEY2_PRES;
-
- if (WK_UP == 1) keyval = WKUP_PRES;
- }
- else if (KEY0 == 1 && KEY1 == 1 && KEY2 == 1 && WK_UP == 0) /* 没有任何按键按下, 标记按键松开 */
- {
- key_up = 1;
- }
-
- return keyval; /* 返回键值 */
- }
-
-
使能按键的GPIO对应时钟,设置按键对应模式,采用扫描式,改成外部中断可能会更好。
- #ifndef __BEEP_H
- #define __BEEP_H
-
- #include "./SYSTEM/sys/sys.h"
-
- /******************************************************************************************/
- /* 引脚 定义 */
-
- #define BEEP_GPIO_PORT GPIOB
- #define BEEP_GPIO_PIN GPIO_PIN_8
- #define BEEP_GPIO_CLK_ENABLE() do{ __HAL_RCC_GPIOB_CLK_ENABLE(); }while(0) /* PB口时钟使能 */
-
- /******************************************************************************************/
-
- /* 蜂鸣器控制 */
- #define BEEP(x) do{ x ? \
- HAL_GPIO_WritePin(BEEP_GPIO_PORT, BEEP_GPIO_PIN, GPIO_PIN_SET) : \
- HAL_GPIO_WritePin(BEEP_GPIO_PORT, BEEP_GPIO_PIN, GPIO_PIN_RESET); \
- }while(0)
-
- /* BEEP状态翻转 */
- #define BEEP_TOGGLE() do{ HAL_GPIO_TogglePin(BEEP_GPIO_PORT, BEEP_GPIO_PIN); }while(0) /* BEEP = !BEEP */
-
- void beep_init(void); /* 初始化蜂鸣器 */
-
- #endif
-
- #include "./BSP/BEEP/beep.h"
-
-
- /**
- * @brief 初始化BEEP相关IO口, 并使能时钟
- * @param 无
- * @retval 无
- */
- void beep_init(void)
- {
- GPIO_InitTypeDef gpio_init_struct;
- BEEP_GPIO_CLK_ENABLE(); /* BEEP时钟使能 */
-
- gpio_init_struct.Pin = BEEP_GPIO_PIN; /* 蜂鸣器引脚 */
- gpio_init_struct.Mode = GPIO_MODE_OUTPUT_PP; /* 推挽输出 */
- gpio_init_struct.Pull = GPIO_PULLUP; /* 上拉 */
- gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH; /* 高速 */
- HAL_GPIO_Init(BEEP_GPIO_PORT, &gpio_init_struct); /* 初始化蜂鸣器引脚 */
-
- BEEP(0); /* 关闭蜂鸣器 */
- }
LCD灯,按键,蜂鸣器本质都是GPIO所以代码类似。蜂鸣器采用的是有源蜂鸣器,只有响和不响两种状态。
- uint8_t rtc_init(void)
- {
-
-
- /* 检查是不是第一次配置时钟 */
- uint16_t bkpflag = 0;
-
- __HAL_RCC_PWR_CLK_ENABLE(); /* 使能电源时钟 */
- __HAL_RCC_BKP_CLK_ENABLE(); /* 使能备份时钟 */
- HAL_PWR_EnableBkUpAccess(); /* 取消备份区写保护 */
-
- bkpflag = rtc_read_bkr(0); /* 读取BKP0的值 */
-
- g_rtc_handle.Instance = RTC;
- g_rtc_handle.Init.AsynchPrediv = RTC_AUTO_1_SECOND; /*时钟周期设置,理论值:32767, 这里也可以用 RTC_AUTO_1_SECOND */
- g_rtc_handle.Init.OutPut = RTC_OUTPUTSOURCE_NONE;
- if (HAL_RTC_Init(&g_rtc_handle) != HAL_OK)
- {
- return 1;
- }
-
- if ((bkpflag != 0X5050) && (bkpflag != 0x5051)) /* 之前未初始化过,重新配置 */
- {
- rtc_set_time(2023, 4, 5, 10, 25, 35); /* 设置时间 */
- }
- //HAL_RTC_Init
- __HAL_RTC_ALARM_ENABLE_IT(&g_rtc_handle, RTC_IT_SEC); /* 允许秒中断 */
-
- HAL_NVIC_SetPriority(RTC_IRQn, 0x2, 0); /* 优先级设置 */
- HAL_NVIC_EnableIRQ(RTC_IRQn); /* 使能RTC中断通道 */
-
- rtc_get_time(); /* 更新时间 */
- return 0;
- }
-
- void HAL_RTC_MspInit(RTC_HandleTypeDef *hrtc)
- {
- uint16_t retry = 200;
-
- __HAL_RCC_RTC_ENABLE(); /* RTC时钟使能 */
-
- RCC_OscInitTypeDef rcc_oscinitstruct;
- RCC_PeriphCLKInitTypeDef rcc_periphclkinitstruct;
-
- /* 使用寄存器的方式去检测LSE是否可以正常工作 */
- RCC->BDCR |= 1 << 0; /* 开启外部低速振荡器LSE */
-
- while (retry && ((RCC->BDCR & 0X02) == 0)) /* 等待LSE准备好 */
- {
- retry--;
- delay_ms(5);
- }
-
- if (retry == 0) /* LSE起振失败 使用LSI */
- {
- rcc_oscinitstruct.OscillatorType = RCC_OSCILLATORTYPE_LSI; /* 选择要配置的振荡器 */
- rcc_oscinitstruct.LSEState = RCC_LSI_ON; /* LSI状态:开启 */
- rcc_oscinitstruct.PLL.PLLState = RCC_PLL_NONE; /* PLL无配置 */
- HAL_RCC_OscConfig(&rcc_oscinitstruct); /* 配置设置的rcc_oscinitstruct */
-
- rcc_periphclkinitstruct.PeriphClockSelection = RCC_PERIPHCLK_RTC; /* 选择要配置的外设 RTC */
- rcc_periphclkinitstruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSI; /* RTC时钟源选择 LSI */
- HAL_RCCEx_PeriphCLKConfig(&rcc_periphclkinitstruct); /* 配置设置的rcc_periphClkInitStruct */
- rtc_write_bkr(0, 0X5051);
- }
- else
- {
- rcc_oscinitstruct.OscillatorType = RCC_OSCILLATORTYPE_LSE ; /* 选择要配置的振荡器 */
- rcc_oscinitstruct.LSEState = RCC_LSE_ON; /* LSE状态:开启 */
- rcc_oscinitstruct.PLL.PLLState = RCC_PLL_NONE; /* PLL不配置 */
- HAL_RCC_OscConfig(&rcc_oscinitstruct); /* 配置设置的rcc_oscinitstruct */
-
- rcc_periphclkinitstruct.PeriphClockSelection = RCC_PERIPHCLK_RTC; /* 选择要配置外设 RTC */
- rcc_periphclkinitstruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSE; /* RTC时钟源选择LSE */
- HAL_RCCEx_PeriphCLKConfig(&rcc_periphclkinitstruct); /* 配置设置的rcc_periphclkinitstruct */
- rtc_write_bkr(0, 0X5050);
- }
- }
-
- void RTC_IRQHandler(void)
- {
- if (__HAL_RTC_ALARM_GET_FLAG(&g_rtc_handle, RTC_FLAG_SEC) != RESET) /* 秒中断 */
- {
- rtc_get_time(); /* 更新时间 */
- __HAL_RTC_ALARM_CLEAR_FLAG(&g_rtc_handle, RTC_FLAG_SEC); /* 清除秒中断 */
- // printf("sec:%d\r\n", calendar.sec); /* 打印秒钟 */
- }
-
- /* 顺带处理闹钟标志 */
- if (__HAL_RTC_ALARM_GET_FLAG(&g_rtc_handle, RTC_FLAG_ALRAF) != RESET) /* 闹钟标志 */
- {
- __HAL_RTC_ALARM_CLEAR_FLAG(&g_rtc_handle, RTC_FLAG_ALRAF); /* 清除闹钟标志 */
- // rtc_get_time();
- // time_arr[4]=calendar.hour;
- // time_arr[5]=calendar.min;
- //Create_show_medicinfo();
- // printf("zd1\r\n");
- Alar_listNum=Alerm_node->list;
- BEEP(1);
- EatFlag=1;
- Shoe_medicinfiFlag=1;
- // __HAL_RTC_ALARM_CLEAR_FLAG(&g_rtc_handle, RESET);
- Chinge_alarm();
- // printf("Alarm Time:%d-%d-%d %d:%d:%d\n", calendar.year, calendar.month, calendar.date, calendar.hour, calendar.min, calendar.sec);
- }
-
- __HAL_RTC_ALARM_CLEAR_FLAG(&g_rtc_handle, RTC_FLAG_OW); /* 清除溢出中断标志 */
- while (!__HAL_RTC_ALARM_GET_FLAG(&g_rtc_handle, RTC_FLAG_RTOFF)); /* 等待RTC寄存器操作完成, 即等待RTOFF == 1 */
- // printf("zd2\r\n");
- }
rtc实时时钟:STM32RTC是STM32系列微控制器中的实时时钟模块,它可以提供精确的时间和日期信息。该模块可以通过外部低速晶振或者内部LSI时钟源来提供时钟信号。同时,它还可以提供闹钟功能和周期性唤醒功能。
rtc初始化需要先使能时钟,这里默认使用外部低速振荡器,当系统下电时可以转为内部时钟,保证时间正常。使能秒中断,实现每秒计数器加一,rtc时间的实现的本质就是对计数器的时间进行计算,系统时间为1970年1月1日0时0分0秒到当前时间的总秒数。使能闹钟中断,当闹钟中的值,和rtc秒的计数器的值一致时产生闹钟中断,处理闹钟过程。处理的闹钟过程包括更新下一个闹钟的信息,打开闹钟提示,更新标志位,其他任务通过获取标志位实现不同的功能。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。