找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3011|回复: 0
打印 上一主题 下一主题
收起左侧

分时复用程序范本51单片机程序框架

[复制链接]
跳转到指定楼层
楼主
ID:459510 发表于 2019-12-24 22:01 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
      由于经常涉及到单片机开发,所以需要一个能够跑多任务的程序框架,用操作系统有点儿浪费资源,用普通线程方式又不能执行多任务,所以采取分时复用的方式,来跑多任务。
      写一个范本为以后开发服务。

单片机源程序如下:
  1. #include "common.h"
  2. /**************************************************************************************
  3. * Variable definition                           
  4. **************************************************************************************/
  5. static TASK_COMPONENTS TaskComps[] =
  6. {
  7.     {0, 60, 60, TaskDisplay},            // 显示时钟
  8.     {0, 20, 20, TaskKeySan},               // 按键扫描
  9.     {0, 500, 500, TaskDispStatus},            // 显示工作状态
  10.                 {0, 0, 0, TaskKeyProcess},               // 按键处理任务
  11.      // 这里添加你的任务。。。。
  12. };

  13. void main(void)
  14. {
  15.         WDT_Config();                        //初始化看门狗
  16.         TaskInit();                                //任务端口资源初始化
  17.         Timer0Init();                        //系统时间片管理器初始化

  18.         while(1)
  19.         {
  20.                 WDT_CLR();                        //喂狗
  21.                 TaskProcess();        //任务处理函数
  22.                 if(keyup_data!=0)        //有按键按下需要进行处理
  23.                         TaskComps[3].Run = 1;
  24.         }
  25. }

  26. void Timer0Init(void)                //1毫秒@24.000MHz
  27. {
  28.         AUXR &= 0x7F;                //定时器时钟12T模式
  29.         TMOD &= 0xF0;                //设置定时器模式
  30.         TL0 = 0x30;                //设置定时初值
  31.         TH0 = 0xF8;                //设置定时初值
  32.         TF0 = 0;                //清除TF0标志
  33.         TR0 = 1;                //定时器0开始计时
  34.         ET0 = 1;                //开启定时器0中断
  35.         EA = 1;
  36. }


  37. /**************************************************************************************
  38. * FunctionName : TimerInterrupt()
  39. * Description : 定时中断服务函数
  40. * EntryParameter : None
  41. * ReturnValue : None
  42. **************************************************************************************/
  43. void Timer0_Interrupt() interrupt 1
  44. {
  45.         uint8 i;
  46.         for (i=0; i<TASK_NUM; i++)          // 逐个任务时间处理
  47.         {
  48.                 if (TaskComps[i].Timer)          // 时间不为0
  49.                 {
  50.                         TaskComps[i].Timer--;         // 减去一个节拍
  51.                         if (TaskComps[i].Timer == 0)       // 时间减完了
  52.                         {
  53.                                 TaskComps[i].Timer = TaskComps[i].ItvTime;       // 恢复计时器值,从新下一次
  54.                                 TaskComps[i].Run = 1;           // 任务可以运行
  55.                         }
  56.                 }
  57.         }
  58. }
  59. /**************************************************************************************
  60. * FunctionName   : WDT_Config()
  61. * Description    : 看门狗配置
  62. * EntryParameter : None
  63. * ReturnValue    : None
  64. **************************************************************************************/
  65. void WDT_Config(void)
  66. {
  67.         WDT_CONTR = 0x04;       //看门狗定时器溢出时间计算公式: (12 * 32768 * PS) / FOSC (秒)
  68.                           //设置看门狗定时器分频数为32,溢出时间如下:
  69.                           //11.0592M : 1.14s
  70.                           //18.432M  : 0.68s
  71.                           //20M      : 0.63s
  72.                                                                                                         //24M      : 0.52s
  73.         WDT_CONTR |= 0x20;      //启动看门狗
  74. }
  75. /**************************************************************************************
  76. * FunctionName   : TaskProcess()
  77. * Description    : 任务处理
  78. * EntryParameter : None
  79. * ReturnValue    : None
  80. **************************************************************************************/
  81. void TaskProcess(void)
  82. {
  83.         uint8 i;
  84.         for (i=0; i<TASK_MAX; i++)           // 逐个任务时间处理
  85.         {
  86.                 if (TaskComps[i].Run)           // 时间不为0
  87.                 {
  88.                         TaskComps[i].TaskHook();         // 运行任务
  89.                         TaskComps[i].Run = 0;          // 标志清0
  90.                 }
  91.         }   
  92. }
复制代码
  1. #include "common.h"

  2. //按键扫描变量
  3. uint8          keydown_data=0x00;    //按键按下后就返回的值
  4. uint8          keyup_data=0x00;      //按键抬起返回值
  5. uint16  key_time=0x00;       //按键按下之后的时间计数,该值乘以扫描一次按键函数的时间就等于按键按下的时间
  6. uint8         key_tem=0x00;         //长按的按键值与按键扫描程序过渡变量
  7. uint8          key_bak=0x00;         //按键扫描程序过渡变量

  8. /**************************************************************************************
  9. * FunctionName   : TaskInit()
  10. * Description    : 任务配置
  11. * EntryParameter : None
  12. * ReturnValue    : None
  13. **************************************************************************************/
  14. void TaskInit(void)
  15. {
  16.         TaskDispStatusInit();
  17.         TaskKeySanInit();
  18. }
  19. /**************************************************************************************
  20. * FunctionName   : TaskDisplay()
  21. * Description    : 显示任务
  22. * EntryParameter : None
  23. * ReturnValue    : None
  24. **************************************************************************************/
  25. void TaskDisplay(void)
  26. {

  27. }
  28. /**************************************************************************************
  29. * FunctionName   : TaskKeySanInit()
  30. * Description    : 扫描任务初始化
  31. * EntryParameter : None
  32. * ReturnValue    : None
  33. **************************************************************************************/
  34. void TaskKeySanInit(void)
  35. {
  36.         P0M0 = 0;
  37.         P0M1 = 0;
  38.        
  39.         P0 |= 0x0f;
  40. }
  41. /**************************************************************************************
  42. * FunctionName   : TaskKeySan()
  43. * Description    : 扫描任务
  44. * EntryParameter : None
  45. * ReturnValue    : None
  46. **************************************************************************************/
  47. void TaskKeySan(void)
  48. {
  49.         uint8        mode=0;
  50.         keyup_data=0;         //键抬起后按键值一次有效
  51.         //----------------------------------------------------------------------------------
  52.         if(KEY2==0||KEY3==0)   //有键正按下
  53.         {
  54.                 if(KEY2==0) key_tem=1;
  55.                 else if(KEY3==0) key_tem=2;
  56.                
  57.                 if (key_tem == key_bak)      //有键按下后第一次扫描不处理,与else配合第二次扫描有效,这样实现了去抖动
  58.                 {
  59.                         key_time++;             //有键按下后执行一次扫描函数,该变量加1
  60.                         keydown_data=key_tem;   //按键值赋予keydown_data
  61.                                        
  62.                         if( (mode==0)&&(key_time>1) )//key_time>1按键值无效,这就是单按,如果mode为1就为连按
  63.                                 keydown_data=0;
  64.     }
  65.           else                             //去抖动      
  66.           {
  67.                   key_time=0;
  68.                   key_bak=key_tem;
  69.           }
  70.         }
  71.         else       //键抬起
  72.         {
  73.           if(key_time>2)            //按键抬起后返回一次按键值
  74.           {
  75.                   keyup_data=key_tem;  //键抬起后按键值赋予keydown_data   
  76.           }
  77.                 key_bak=0;               //要清零,不然下次执行扫描程序时按键的值跟上次按的值一样,就没有去抖动处理了
  78.           key_time=0;
  79.                 keydown_data=0;               
  80.         }
  81.         //-----------------------------------------------------------------------------------
  82.         if(KEY0 == 0);
  83.         if(KEY1 == 0);
  84. }
  85. /**************************************************************************************
  86. * FunctionName   : TaskKeyProcess()
  87. * Description    : 扫描任务
  88. * EntryParameter : None
  89. * ReturnValue    : None
  90. **************************************************************************************/
  91. void TaskKeyProcess(void)
  92. {
  93.         switch(keyup_data)
  94.         {
  95.                 case 1:break;
  96.                 case 2:break;
  97.         }
  98. }
  99. /**************************************************************************************
  100. * FunctionName   : TaskDispStatusInit()
  101. * Description    : 工作状态显示初始化
  102. * EntryParameter : None
  103. * ReturnValue    : None
  104. **************************************************************************************/
  105. void TaskDispStatusInit(void)
  106. {
  107.         P5M0 |= 0x20;
  108.         P5M1 = 0;
  109.        
  110.         DispStatusLed = 1;
  111. }
  112. /**************************************************************************************
  113. * FunctionName   : TaskDispStatus()
  114. * Description    : 工作状态显示
  115. * EntryParameter : None
  116. * ReturnValue    : None
  117. **************************************************************************************/
  118. void TaskDispStatus(void)
  119. {
  120.         DispStatusLed = ~DispStatusLed;
  121. }
  122. // 这里添加其他任务。。。。。。。。。
复制代码


所有资料51hei提供下载:
42 程序框架.rar (168.62 KB, 下载次数: 68)


评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏2 分享淘帖 顶 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表