soft_timer.h
- #ifndef __SOFT_TIMER_H__
- #define __SOFT_TIMER_H__
- struct soft_timer{
- int flag; //run flag, which can be SUSPEND,RUN,STOP
- unsigned int tick_count; //left ticks to be run
- void (*time_over_proc)(void); //timer over callback function
- struct soft_timer* next;
- };
- #define TIMER_FLAG_SUSPEND 0
- #define TIMER_FLAG_RUN 1
- #define TIMER_FLAG_STOP 2
- #define TIMER_NULL ((struct soft_timer*)0)
- void soft_timer_list_reset(void);
- void add_timer(struct soft_timer* timer,void(*call_back)(void),unsigned int time_count);
- void remove_timer(struct soft_timer* timer);
- void start_timer(struct soft_timer* timer);
- void stop_timer(struct soft_timer* timer);
- void stop_timer_with_call(struct soft_timer* timer);
- void suspend_timer(struct soft_timer* timer);
- void reload_timer(struct soft_timer* timer,unsigned int time_count);
- void timer_periodic_refresh(void);
- #endif /*__SOFT_TIMER_H__*/
然后在main.c程序中配置Systick的周期和中断优先级:
- void hw_timer_init(void)
- {
- ald_systick_interval_select(SYSTICK_INTERVAL_10MS); //10 ms
- NVIC_SetPriority (SysTick_IRQn, 1); //NVIC config
- }
同时再irq.c文件中的系统嘀嗒定时器中断处理函数中添加软定时器刷新函数:
- void SysTick_Handler(void)
- {
- ald_inc_tick();
- timer_periodic_refresh();
- return;
- }
然后再程序运行开始后初始化定时器,同时复位定时器列表,添加软定时器1和软定时器2,同时在定时器1回调函数中添加按键扫描处理函数,在定时器2回调函数中添加LED灯处理函数,编译下载即可实现两个定时器任务循环调度运行。时间片可以通过定时器创建时设定。工程文件目录如下:
key.c
- #include "main.h"
- //////////////////////////////////////////////////////////////////////////////////
- //开发板
- //按键输入 驱动代码
- //////////////////////////////////////////////////////////////////////////////////
- //按键初始化函数
- void KEY_Init(void)
- {
-
- gpio_init_t x;
- x.mode = GPIO_MODE_INPUT;
- x.odos = GPIO_PUSH_PULL;
- x.pupd = GPIO_FLOATING;
- x.podrv = GPIO_OUT_DRIVE_6;
- x.nodrv = GPIO_OUT_DRIVE_6;
- x.flt = GPIO_FILTER_DISABLE;
- x.type = GPIO_TYPE_CMOS;
- x.func = GPIO_FUNC_1;
- ald_gpio_init(BSP_KEY1_PORT, BSP_KEY1_PIN, &x);
- ald_gpio_init(BSP_KEY2_PORT, BSP_KEY2_PIN, &x);
- ald_gpio_init(BSP_KEY3_PORT, BSP_KEY3_PIN, &x);
- ald_gpio_init(BSP_KEY4_PORT, BSP_KEY4_PIN, &x);
- ald_gpio_init(BSP_KEY5_PORT, BSP_KEY5_PIN, &x);
-
- }
- //按键处理函数
- //返回按键值
- //mode:0,不支持连续按;1,支持连续按;
- //返回值:
- //0,没有任何按键按下
- //KEY1_PRES,KEY1按下
- //WKUP_PRES,WK_UP按下
- //KEY3_PRES,KEY3按下
- //KEY4_PRES,KEY4按下
- uint8_t KEY_Scan(uint8_t mode)
- {
- static uint8_t key_up=1;//按键按松开标志
- if(mode)key_up=1; //支持连按
- if(key_up&&(KEY1==0||KEY2==0||KEY3==0||KEY4==0||KEY5==0))
- {
- //delay_ms(10);//去抖动
- key_up=0;
- if(KEY1==0)return KEY1_PRES;
- else if(KEY2==0)return KEY2_PRES;
- else if(KEY3==0)return KEY3_PRES;
- else if(KEY4==0)return KEY4_PRES;
- else if(KEY5==0)return KEY5_PRES;
- }else if(KEY1==1&&KEY3==1&&KEY4==1&&KEY2==1&&KEY5==1)key_up=1;
- return 0;// 无按键按下
- }
key.h
- #ifndef __KEY_H
- #define __KEY_H
- //////////////////////////////////////////////////////////////////////////////////
- //开发板
- //按键驱动代码
- //////////////////////////////////////////////////////////////////////////////////
- /* KEY1 ---> UP
- * KEY2 ---> DOWN
- * KEY3 ---> MID
- * KEY4 ---> LEFT
- * KEY5 ---> RIGHT
- */
- #define BSP_KEY_MAX 5
- #define BSP_KEY1_PORT GPIOB
- #define BSP_KEY1_PIN GPIO_PIN_2
- #define BSP_KEY2_PORT GPIOB
- #define BSP_KEY2_PIN GPIO_PIN_12
- #define BSP_KEY3_PORT GPIOC
- #define BSP_KEY3_PIN GPIO_PIN_10
- #define BSP_KEY4_PORT GPIOC
- #define BSP_KEY4_PIN GPIO_PIN_11
- #define BSP_KEY5_PORT GPIOC
- #define BSP_KEY5_PIN GPIO_PIN_12
- #define KEY1 ald_gpio_read_pin(BSP_KEY1_PORT, BSP_KEY1_PIN)//读取按键1
- #define KEY2 ald_gpio_read_pin(BSP_KEY2_PORT, BSP_KEY2_PIN)//读取按键2
- #define KEY3 ald_gpio_read_pin(BSP_KEY3_PORT, BSP_KEY3_PIN)//读取按键3
- #define KEY4 ald_gpio_read_pin(BSP_KEY4_PORT, BSP_KEY4_PIN)//读取按键4
- #define KEY5 ald_gpio_read_pin(BSP_KEY5_PORT, BSP_KEY5_PIN)//读取按键5
- #define KEY1_PRES 1 //KEY1
- #define KEY2_PRES 2 //KEY2
- #define KEY3_PRES 3 //KEY3
- #define KEY4_PRES 4 //KEY4
- #define KEY5_PRES 5 //KEY5
- void KEY_Init(void);//IO初始化
- uint8_t KEY_Scan(uint8_t mode); //按键扫描函数
- #endif
main.c
- #include "main.h"
- /** @addtogroup Projects_Templates_ALD
- * @{
- */
- /** @addtogroup Templates
- * @{
- */
- extern uart_handle_t h_uart;
- uint8_t tx_buf[32];
- uint8_t count = 0;
- struct soft_timer test_timer1,test_timer2; //creat 2 soft timers
- void timer1_call_back(void); //call back functions when timer over
- void timer2_call_back(void);
- void hw_timer_init(void)
- {
- ald_systick_interval_select(SYSTICK_INTERVAL_10MS); //10 ms
- NVIC_SetPriority (SysTick_IRQn, 1); //NVIC config
- }
- //按键扫描函数
- void KeyScan(void)
- {
- uint8_t t;
- t=KEY_Scan(0); //得到键值
- switch(t)
- {
- case KEY1_PRES:
- sprintf((char *)tx_buf, "KEY1 Clicked!\n");
- ald_uart_send(&h_uart, tx_buf, sizeof("KEY1 Clicked!\n"), 1000);
- break;
- case KEY2_PRES:
- sprintf((char *)tx_buf, "KEY2 Clicked!\n");
- ald_uart_send(&h_uart, tx_buf, sizeof("KEY2 Clicked!\n"), 1000);
- break;
- case KEY3_PRES:
- sprintf((char *)tx_buf, "KEY3 Clicked!\n");
- ald_uart_send(&h_uart, tx_buf, sizeof("KEY3 Clicked!\n"), 1000);
- break;
- case KEY4_PRES:
- sprintf((char *)tx_buf, "KEY4 Clicked!\n");
- ald_uart_send(&h_uart, tx_buf, sizeof("KEY4 Clicked!\n"), 1000);
- break;
- case KEY5_PRES:
- sprintf((char *)tx_buf, "KEY5 Clicked!\n");
- ald_uart_send(&h_uart, tx_buf, sizeof("KEY5 Clicked!\n"), 1000);
- break;
- default:
- break;
- }
- }
- void timer1_call_back(void)
- {
- reload_timer(&test_timer1,10); //
- start_timer(&test_timer1); //should be restart because of one shot software timer.
- //按键扫描
- KeyScan();
- }
- void timer2_call_back(void)
- {
- reload_timer(&test_timer2,30);
- start_timer(&test_timer2);
-
- count++;
- if(count==1)
- {
- ald_gpio_write_pin(LED1_PORT, LED1_PIN, 0);
- ald_gpio_write_pin(LED2_PORT, LED2_PIN, 1);
- }else if(count==2)
- {
- count = 0;
- ald_gpio_write_pin(LED1_PORT, LED1_PIN, 1);
- ald_gpio_write_pin(LED2_PORT, LED2_PIN, 0);
- }
- }
- /**
- * @brief This is main function.
- * Detect running time.
- * @retval Status
- */
- int main()
- {
- /* Initialize ALD */
- ald_cmu_init();
- /* Configure system clock */
- ald_cmu_pll1_config(CMU_PLL1_INPUT_HOSC_3, CMU_PLL1_OUTPUT_72M);
- ald_cmu_clock_config(CMU_CLOCK_PLL1, 72000000);
- /* Enable peripheral */
- ald_cmu_perh_clock_config(CMU_PERH_GPIO, ENABLE);
- ald_cmu_perh_clock_config(CMU_PERH_UART0, ENABLE);
-
- /* Initialize tx_buf */
- memset(tx_buf, 0x55, sizeof(tx_buf));
- ///* Initialize uart_usb */
- uart_usb_init();
-
- /* Initialize led */
- led_pin_init();
-
- KEY_Init(); //初始化与按键连接的硬件接口
-
- hw_timer_init();
- soft_timer_list_reset();
- add_timer(&test_timer1,timer1_call_back,60); //
- start_timer(&test_timer1);
- add_timer(&test_timer2,timer2_call_back,30); //
- start_timer(&test_timer2);
- //打印信息
- printf_e("Soft Timer Test Using SysTick\r\n");
- printf_e("1、KeyScan\r\n");
- printf_e("2、LED\r\n");
- while (1) {
- #if 0
- /* Send a message */
- sprintf((char *)tx_buf, "es32 uart test!\n");
- ald_uart_send(&h_uart, tx_buf, sizeof("es32 uart test!\n"), 1000);
-
- ald_gpio_write_pin(LED1_PORT, LED1_PIN, 0);
- ald_gpio_write_pin(LED2_PORT, LED2_PIN, 0);
- ald_delay_ms(500);
- ald_gpio_write_pin(LED1_PORT, LED1_PIN, 1);
- ald_gpio_write_pin(LED2_PORT, LED2_PIN, 1);
- ald_delay_ms(500);
- #endif
- ald_delay_ms(500);
- }
- }
程序编译无误下载后,即可看到LED灯循环亮灭,按下开发板上的五向按键串口进行相应的打印输出。
@21小跑堂