活动介绍
file-type

裸机定时器实现多任务轮询调度

ZIP文件

5星 · 超过95%的资源 | 1KB | 更新于2025-03-31 | 145 浏览量 | 15 下载量 举报 2 收藏
download 立即下载
标题“TIMER_轮询_裸机定时器任务调度_”和描述“裸机多任务轮询定时器,用于简单任务的轮询”涉及的是嵌入式系统或微控制器编程中常见的一种任务调度技术。在这种技术中,定时器用于实现多任务轮询机制,以保证系统能够按照预定的时间间隔或者事件周期来执行不同的任务。该技术主要适用于那些硬件资源相对有限、不需要操作系统支持的裸机(bare metal)环境。 在详细阐述之前,我们首先要明确几个核心概念: 1. 裸机(Bare Metal):指的是没有运行任何操作系统,直接在硬件上执行程序的情况。在这种情况下,所有的任务调度、内存管理、I/O操作等都要由程序员自行通过编程实现。 2. 轮询(Polling):这是一种在裸机环境中常见的技术,用于周期性地检查硬件设备的状态,从而实现对设备的控制。轮询通常使用循环结构来不断检查设备的标志位或寄存器值。 3. 定时器(Timer):定时器是微控制器或处理器中用于计时的硬件单元。它可以通过编程设定时间间隔,当时间到达时,定时器会产生一个中断信号或更新一个状态寄存器。 4. 任务调度(Task Scheduling):是指在有限的计算资源下,合理分配时间片给多个任务,并管理这些任务的执行顺序和时机,以达到多任务运行的效率和目标。 接下来,我们详细探讨这些知识点: 裸机多任务轮询定时器实际上是一个基于时间的调度算法。在这个算法中,系统通过一个或多个定时器周期性地产生定时器中断。每当定时器中断发生时,主循环(轮询循环)将被中断,执行一个固定的中断服务例程(ISR)。在ISR中,系统会根据当前时间,来决定执行哪一个任务或者哪些任务。 定时器中断的配置通常包括设定中断频率(即定时器溢出的时间间隔),和配置中断触发模式(比如上升沿触发、下降沿触发、高电平触发等)。在中断服务例程中,最重要的操作之一是更新系统时钟,这通常是通过增加一个时钟变量来实现的。该变量用于跟踪系统已经运行的总时间。 任务调度部分,则是依据预设的任务切换逻辑,决定下一个应该运行的任务。这个过程可能涉及对任务优先级的考虑,也可能是简单的轮询顺序。任务在执行时需要尽可能地短小精悍,以避免阻塞整个系统的运行。每个任务都应当在预定的时间内执行完毕,或者等待下一个调度周期。 裸机环境下的任务调度与操作系统(如RTOS)中的任务调度有所不同。在裸机环境,任务调度的实现和控制完全由开发者完成,因此,更加依赖于开发者对硬件和程序运行机制的深刻理解。而在RTOS环境下,大部分任务调度的工作都是由系统内核自动完成的,程序员只需要定义任务以及它们的优先级即可。 此外,定时器任务调度器的设计还需要考虑如何处理多任务之间的同步和互斥问题。由于裸机环境下不支持多线程,因此,对共享资源的访问需要通过特定的同步机制来保证数据的一致性和完整性。 在实现轮询定时器任务调度时,常用的程序结构有无限循环、中断服务程序、以及可被定时器中断触发的任务切换逻辑。通过精心设计这些组件,即使在资源有限的裸机环境下,也能实现较为复杂的功能。 总结来说,TIMER_轮询_裸机定时器任务调度_的知识点涵盖了裸机环境下编程的一些核心概念和技巧,包括裸机编程的含义、轮询机制的作用、定时器的配置和使用、以及基于时间的任务调度算法。这些知识点在嵌入式系统设计、微控制器编程、以及其他需要高效利用硬件资源的场景中非常关键。

相关推荐

filetype

#include "delay.h" #include "sys.h" #include "led.h" #include "lcd_init.h" #include "lcd.h" #include "pic.h" #include "SR04.h" #include "INFRARED.h" #include "timer.h" #include "Motor.h" //===================变量========================= float Hcsr04; uint16_t speed; uint8_t miao; uint8_t miao_sure; uint8_t V_flag; float V_sure; //====================漫反射式传感器标志位 uint8_t s1, s2, s3, s4; //======================触发标志位================= uint8_t first = 0; // 第一次触发 uint8_t second = 0; // 第二次触发 //======================运行状态标志位============== uint8_t zheng = 0, fan = 0, stop = 0; uint8_t flag_mei = 0, flag = 0; uint8_t flag_zheng = 0, flag_fan = 0, flag_stop = 0; uint8_t flag_miao = 0, flag_kai = 0, flag_dingshi = 0; uint8_t flag_ok = 0; uint16_t num_miao = 0, i = 0; uint8_t flag_off;//定时时间到关闭电机 uint8_t flag_V1; //中断标志位 uint8_t flag_Vsure; //设置电压标志位 uint8_t mode=0; uint8_t bit_mode2_ON,bit_mode2_OFF; //进入模式二中断 uint8_t flag_bit1,flag_bit2,flag_bit3,flag_bit4,flag_bit5,flag_bit6; //6个自定义模式 uint8_t flag_bit3_OK; uint8_t flag10s_1momen; uint8_t flag10s_2momen; //=====================中断计次标志位=============== uint8_t count = 0; uint16_t num = 0, MEI = 0, ace = 0; //=====================LCD刷新标志位=============== uint8_t need_update_speed = 1; uint8_t need_update_distance = 1; uint8_t need_update_status = 1; uint8_t need_update_time = 1; uint8_t need_update_mode = 1; // 新增模式显示标志 //=====================静态显示初始化函数========== void LCD_InitDisplay(void) { LCD_ShowChinese(180,0,"显示器",BLACK,WHITE,32,0); LCD_ShowChinese(0,50,"指示灯",BLACK,WHITE,24,0); LCD_ShowChinese(0,110,"运动状态",BLACK,WHITE,24,0); LCD_ShowChinese(0,170,"风扇转向",BLACK,WHITE,24,0); LCD_ShowChinese(0,230,"风扇转速",BLACK,WHITE,24,0); LCD_ShowChinese(200,50,"设定运行时间",BLACK,WHITE,24,0); LCD_ShowChinese(200,110,"倒计时",BLACK,WHITE,24,0); LCD_ShowChinese(200,170,"设定工作电压",BLACK,WHITE,24,0); LCD_ShowChinese(200,230,"操作距离",BLACK,WHITE,24,0); LCD_ShowChar(350,50,'t',BLACK,WHITE,24,0); LCD_ShowChar(440,50,'S',BLACK,WHITE,24,0); LCD_ShowChar(440,110,'S',BLACK,WHITE,24,0); LCD_ShowChar(440,170,'V',BLACK,WHITE,24,0); LCD_ShowString(440,230,"cm",BLACK,WHITE,24,0); LCD_ShowPicture(100,35,40,40,gImage_16); } //*********************操作处理函数******************* void task_sign(void) { static uint32_t count; count++; if(count > 20 && flag != 1) { count = 0; s1 = E3F1_IsObjectDetected(); s2 = E3F2_IsObjectDetected(); s3 = E3F3_IsObjectDetected(); s4 = E3F4_IsObjectDetected(); if(first == 0) { if(s1) first = 1; else if(s2) first = 2; else if(s3) first = 3; else if(s4) first = 4; } if(first != 0 && second == 0) { switch(first) { case 1: if(s2) second=2; else if(s3) second=3; else if(s4) second=4,flag_mei=1,flag=1; break; case 2: if(s1) second=1; else if(s3) second=3,flag_mei=1,flag=1; else if(s4) second=4,flag_mei=1,flag=1; break; case 3: if(s1) second=1,flag_mei=1,flag=1; else if(s2) second=2; else if(s4) second=4; break; case 4: if(s1) second=1; else if(s2) second=2,flag_mei=1,flag=1; else if(s3) second=3; break; } } } } //***********************显示数据函数************************ void task_pm(void) { if(need_update_speed) { LCD_ShowIntNum(100,230,speed,4,BLACK,WHITE,24); need_update_speed = 0; } if(need_update_distance) { LCD_ShowFloatNum1(330,230,Hcsr04,4,BLACK,WHITE,24); need_update_distance = 0; } if(need_update_status) { LCD_ShowIntNum(280,0,first,1,BLACK,WHITE,24); LCD_ShowIntNum(310,0,second,1,BLACK,WHITE,24); if(V_sure>9.5) { LCD_ShowFloatNum1(360,170,V_sure,4,BLACK,WHITE,24); } else{ LCD_ShowFloatNum1(360,170,V_sure,3,BLACK,WHITE,24); } need_update_status = 0; LCD_ShowIntNum(0,260,mode,1,BLACK,WHITE,24); } if(need_update_time) { LCD_ShowIntNum(365,50,miao_sure,2,BLACK,WHITE,24); LCD_ShowIntNum(365,110,i,2,BLACK,WHITE,24); need_update_time = 0; } } //***************************信息处理函数********************** void task_chuli(void) { static uint8_t last_zheng = 0, last_fan = 0,last_stop = 0;//last_kai=0; 启动逻辑暂时用不上 if(flag != 1) { //*******************************模式0标准模式 if(mode==0) { // 正转逻辑 if(first == 1 && second == 2) { flag_zheng = 1; zheng = 1; fan = 0; LCD_ShowChinese(120,170,"正转",BLACK,WHITE,24,0); LCD_ShowChinese(120,110,"启动",BLACK,WHITE,24,0); AO_Control(0,400); flag = 1; stop = 0; } // 反转逻辑 if(first == 3 && second == 4) { flag_fan = 1; fan = 1; zheng = 0; LCD_ShowChinese(120,170,"反转",BLACK,WHITE,24,0); LCD_ShowChinese(120,110,"启动",BLACK,WHITE,24,0); AO_Control(1,400); flag = 1; stop = 0; } // 停止逻辑 if(first == 2 && second == 1) { flag_stop = 1; stop = 1; flag = 1; AO_Control(1,0); LCD_ShowChinese(120,110,"停止",BLACK,WHITE,24,0); // flag_kai = 0; } //======================定时模式处理============================ if(first == 3 && second == 2) { flag_dingshi = 1; flag_miao = 1; flag = 1; } if(flag_off==1) { LCD_ShowChinese(120,110,"停止",BLACK,WHITE,24,0); if(fan == 1) { AO_Control(1,0); // 反转 flag_off=0; } else if(zheng == 1) { AO_Control(0,0); // 正转 flag_off=0; } } //======================设定电压模式========================= if(first == 4 && second == 1) { flag_V1=1; flag_Vsure=1; flag = 1; } //**********************设定模式********************** if(first == 4 && second == 3) { mode=1; flag=1; bit_mode2_ON=1; } } //******************模式1组合模式**************************** if(mode==1) { //****************退出mode1************ if(first == 3 && second == 4) { mode=0; flag=1; bit_mode2_OFF=1; AO_Control(1,0); LCD_ShowChinese(120,110,"停止",BLACK,WHITE,24,0); } //*************************6个组合程序************* //================正转============== 按键 一 二 if(first == 1 && second == 2) { flag_bit1= 1; LCD_ShowChinese(120,170,"正转",BLACK,WHITE,24,0); LCD_ShowChinese(120,110,"启动",BLACK,WHITE,24,0); AO_Control(0,400); flag = 1; } //================反转============== 按键 一 三 if(first == 1 && second == 3) { LCD_ShowChinese(120,170,"反转",BLACK,WHITE,24,0); LCD_ShowChinese(120,110,"启动",BLACK,WHITE,24,0); AO_Control(1,400); flag = 1; flag_bit2 = 1; } //****************************定时20s*************************** if(first == 2 && second == 1) { flag_bit3_OK=1; i=miao_sure=20; flag = 1; flag_bit3 = 1; } } // ********************************状态显示优化 if(zheng != last_zheng) { LCD_ShowChinese(120,170,"正转",BLACK,WHITE,24,0); last_zheng = zheng; } if(fan != last_fan) { LCD_ShowChinese(120,170,"反转",BLACK,WHITE,24,0); last_fan = fan; } if(stop != last_stop) { LCD_ShowChinese(120,110,"停止",BLACK,WHITE,24,0); last_stop = stop; } } } ///****************用于处理task——chuli函数接收到的信息**************** // void MODE2(void) //{ // //// uint8_t motor_ctrl_cnt ; //// motor_ctrl_cnt++; //// if(motor_ctrl_cnt>20) //// { //// motor_ctrl_cnt = 0; //// //// // 电机状态机 //// if(flag10s_1momen==1) { //// AO_Control(1, 400); // 正转 //// // LCD_ShowChinese(120,170,"正转",BLACK,WHITE,24,0); //// } //// else if(flag10s_2momen==1) { //// AO_Control(0, 400); // 反转 //// // LCD_ShowChinese(120,170,"反转",BLACK,WHITE,24,0); //// } //// else if(flag10s_2momen==flag10s_1momen==0) { //// AO_Control(0, 0); // 停止 //// // LCD_ShowChinese(120,170,"停止",BLACK,WHITE,24,0); //// } //// ////} //} void TOG_1(void) { if(miao>=5&&miao<=20) { switch(miao) { case 5: miao_sure=30; break; case 6: miao_sure=29; break; case 7: miao_sure=28; break; case 8: miao_sure=27; break; case 9: miao_sure=26; break; case 10: miao_sure=25; break; case 11: miao_sure=24; break; case 12: miao_sure=23; break; case 13: miao_sure=22; break; case 14: miao_sure=21; break; case 15: miao_sure=20; break; case 16: miao_sure=19; break; case 17: miao_sure=18; break; case 18: miao_sure=17; break; case 19: miao_sure=16; break; case 20: miao_sure=15; break; } } else { flag_ok = 0; } } void TOG_2(void) { if(V_flag>=5&&V_flag<=20) { switch(V_flag) { case 5: V_sure=10.5; break; case 6: V_sure=10.0; break; case 7: V_sure=9.5; break; case 8: V_sure=9.0; break; case 9: V_sure=8.5; break; case 10: V_sure=8.0; break; case 11: V_sure=7.5; break; case 12: V_sure=7.0; break; case 13: V_sure=6.5; break; case 14: V_sure=6.0; break; case 15: V_sure=5.5; break; case 16: V_sure=5.0; break; case 17: V_sure=4.5; break; case 18: V_sure=4.0; break; case 19: V_sure=3.5; break; case 20: V_sure=3.0; break; } } else { flag_ok = 0; } } //=====================主函数===================== int main(void) { Timer_Init(); Ultrasonic_Init(); delay_init(); LED_Init(); LCD_Init(); E3F_InitAll(); LCD_Fill(0,0,LCD_W,LCD_H,WHITE); LCD_InitDisplay(); // 初始化静态显示内容 TB6612_Init(72-1,1000-1); LED=0; while(1) { static uint8_t main_loop_cnt = 0; // MODE2(); // 10ms周期任务 if(main_loop_cnt % 10 == 0) { Hcsr04 = Hcsr04GetLength(); need_update_distance = 1; } // 20ms周期任务 task_sign(); // 50ms周期任务 if(main_loop_cnt % 20 == 0) { task_chuli(); } // LCD显示更新 task_pm(); delay_ms(1); // 适当延时 main_loop_cnt++; } } //=====================中断服务函数================= void TIM4_IRQHandler(void) { if (TIM_GetITStatus(TIM4, TIM_IT_Update) == SET) { static uint16_t lcd_refresh_cnt = 0; task_sign(); //MODE2(); // 定时刷新标志(约200ms) if(++lcd_refresh_cnt >= 200) { lcd_refresh_cnt = 0; need_update_speed = 1; need_update_status = 1; need_update_time = 1; need_update_mode = 1; } if(flag_zheng || flag_fan ||flag_bit1||flag_bit2||flag_bit3|| flag_stop || flag_kai || flag_dingshi||flag_V1||bit_mode2_ON||bit_mode2_OFF) { num++; if(num > 3000) { flag_zheng = flag_fan = flag_stop = flag_kai =flag_bit2=flag_bit3= flag_dingshi = flag_V1 = bit_mode2_ON=bit_mode2_OFF=flag_bit1=0; first = second = 0; flag = 0; //---------------------------------------- if(flag_miao == 1) { miao = Hcsr04; if(miao>=5&&miao<=20) { TOG_1(); flag_miao = 0; flag_ok = 1; i = miao_sure; } else {miao=0,flag_miao=0;} } //---------------------------------------- if(flag_Vsure==1) { V_flag=Hcsr04; if(V_flag>=5&&V_flag<=20) { TOG_2(); flag_Vsure=0; } else{ flag_Vsure=0;V_flag=0; } } //----------------------------------------- num = 0; } } //========================================================= if(flag_ok == 1||flag_bit3_OK==1) { num_miao++; if(num_miao % 1000 == 0) { i--; if(i == 0) { flag_off=1; i = miao = num_miao = miao_sure=0; flag_ok = 0; flag_bit3_OK=0; } } } //========================================================== if(flag_mei == 1) { MEI++; if(MEI > 2000) { MEI = 0; first = second = 0; flag_mei = flag = 0; } } TIM_ClearITPendingBit(TIM4, TIM_IT_Update); } } 我的代码有点阻塞帮我优化,

爱牛仕
  • 粉丝: 120
上传资源 快速赚钱