单片机的软件定时器的设计原理是什么?

首先我们来看下下面两个图:

51单片机的内部结构框图

STM32内部框图

单片机内部包含众多硬件模块,相对单片机CPU来说这些就是外设(串口,GPIO,定时器,SPI, I2C等),就像我们的电脑主板一样,在CPU周围布置了很多外设(内存,硬盘,显卡,声卡,网卡等)。然后这些模块基本都是独立工作的,通过内部总线或I/O交互;既然是独立工作,那么就不会过多的占用CPU时钟,比如说定时器:我们设置好它的工作模式后,启动它,然后它就不停的按照我们设置的方式工作,到达状态后会有相应状态位可以检测,我们通过CPU主程序来检测标志位,同时执行相应操作;这种方式就像公司的一个组织架构一样,比如说你是老板,你交给你的直接下级去做一件事情,那么你老板是不是也要去做每个事情的细节呢?一个人你能亲历亲为,多个人呢?只是有一种特殊情况,如果我们作为中断用,那么再中断中就不要处理过多事情,因为中断实际是占用CPU时间运行的。

下面有个例子,希望能帮到您

用定时器实现4个LED不同频率的闪烁

Proteus原理图

代码:

/************ (C) COPYRIGHT 2016 wllis **************
 *
 * 文件名: RTOS_LED_Flash.c
 * 描 述:通过简单的系统实现4个LED的不同频率的闪烁
 * 作 者: wllis
 * 日 期: 2016/02/04
 *
 * LED0->P0.0
 * LED1->P0.1
 * LED2->P0.2
 * LED3->P0.3
 *
 ****************************************************/
 #include <reg52.h>
 /*************** TYPEDEFINES ***********************/
 typedef unsigned char UINT8;
 typedef unsigned int UINT16;
 // 系统全局变量
 #define OS_CLOCK 12000000 // 系统晶振频率,单位Hz
 #define TASK_CLOCK 200 // 任务中断节拍,单位Hz
 #define TASK_MAX 4 // 任务数目
 // 设置系统任务执行频度
 #define TASK_DELAY0 TASK_CLOCK/1 // 每秒1次
 #define TASK_DELAY1 TASK_CLOCK/2 // 每秒2次
 #define TASK_DELAY2 TASK_CLOCK/4 // 每秒4次
 #define TASK_DELAY3 TASK_CLOCK/8 // 每秒8次
 /************** LED DEFINES ***********************/
 sbit LED0 = P0^0;
 sbit LED1 = P0^1;
 sbit LED2 = P0^2;
 sbit LED3 = P0^3;
 /****************** Function defines **************/
 void OS_Timer0_Init( void );
 void OS_Task_Run( void (*ptask)() );
 void OS_Run( void );
 void task0( void );
 void task1( void );
 void task2( void );
 void task3( void );
 // 任务指针
 void ( *const task[] )() = { task0,task1,task2,task3 };
 // 系统任务执行频度参数
 UINT8 Task_Delay[TASK_MAX];
/*
 * 函数名:void main()
 * 描 述:主函数
 * 输 入:无
 * 输 出:无
 */
 void main()
 {
      // 端口初始化
      LED0 = 1;
      LED1 = 1;
      LED2 = 1;
      LED3 = 1;
      // 开总中断
      EA = 1;
      OS_Timer0_Init(); // 系统定时器初始化
      while(1)
      {
            OS_Run();
      }
 }
/*
 * 函数名: void OS_Timer0_Init( void )
 * 描 述:T/C0初始化函数
 * 输 入:无
 * 输 出:无
 */
 void OS_Timer0_Init( void )
 {
      UINT8 i;
      for( i=0;i<TASK_MAX;i++ )
      {
            Task_Delay[i] = 0; // 复位系统任务执行频度参数
      }
      TMOD = (TMOD&0xf0)|0x01; //设置定时器0方式1
      TH0 = 256-(OS_CLOCK/TASK_CLOCK)/12/256; //赋初值200Hz
      TL0 = 256-(OS_CLOCK/TASK_CLOCK)/12%256;
      TR0 = 1; //使能定时器0
      ET0 = 1; //使能定时器0中断
 }
/*
 * 函数名:void OS_Task_Run( void (*ptask)() )
 * 描 述:系统任务调度函数
 * 输 入:无
 * 输 出:无
 */
 void OS_Task_Run( void (*ptask)() )
 {
    (*ptask)();
 }
/*
 * 函数名:void OS_Run( void )
 * 描 述:系统运行函数
 * 输 入:无
 * 输 出:无
 */
 void OS_Run( void )
 {
      UINT8 i;
      for ( i=0; i<TASK_MAX; i++ )
      {
           if ( Task_Delay[i] == 0 )
           {
                OS_Task_Run( task[i] );
                break;
           }
      }
 }
/*
 * 函数名:void task0( void )
 * 描 述:任务0函数
 * 输 入:无
 * 输 出:无
 */
 void task0( void )
 {
      Task_Delay[0] = TASK_DELAY0;
      LED0 = ~LED0;
 }
/*
 * 函数名:void task1( void )
 * 描 述:任务1函数
 * 输 入:无
 * 输 出:无
 */
 void task1( void )
 {
      Task_Delay[1] = TASK_DELAY1;
      LED1 = ~LED1;
 }
/*
 * 函数名:void task2( void )
 * 描 述:任务2函数
 * 输 入:无
 * 输 出:无
 */
 void task2( void )
 {
      Task_Delay[2] = TASK_DELAY2;
      LED2 = ~LED2;
 }
/*
 * 函数名:void task3( void )
 * 描 述:任务3函数
 * 输 入:无
 * 输 出:无
 */
 void task3( void )
 {
      Task_Delay[3] = TASK_DELAY3;
      LED3 = ~LED3;
 }
/*
 * 函数名:void Timer0IRQ(void)
 * 描 述:定时器T/C0中断函数
 * 输 入:无
 * 输 出:无
 */
 void Timer0IRQ(void) interrupt 1
 {
      UINT8 i;
      TH0 = 256-(OS_CLOCK/TASK_CLOCK)/12/256; //赋初值200Hz
      TL0 = 256-(OS_CLOCK/TASK_CLOCK)/12%256;
      for( i=0;i<TASK_MAX;i++ )
      {
           if(Task_Delay[i])
           {
               Task_Delay[i]--;
           }
      }
 }
 /*************** end of file *************************/
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

被大佬糊弄的只会点灯的小菜鸡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值