找回密码
 立即注册

QQ登录

只需一步,快速开始

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

51单片机嵌入UCOS系统 程序

[复制链接]
跳转到指定楼层
楼主
ID:107189 发表于 2016-3-6 13:47 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 51黑tt 于 2016-3-6 13:49 编辑

8位单片机代表类型是51单片机,
最近正对51单片机嵌入UCOS系统很感兴趣,
很少人会对51嵌入UCOS感冒,原因是51的RAm太少,最近看到一篇《制造自己的操作系统,》学习了一下午,感觉不是很强大,我是个菜鸟,可能还不知道其中的精髓吧,下贴出,留念。
  1. #include <reg51.h>


  2. /*============================以下为任务管理器代码============================*/

  3. #define MAX_TASKS 3//任务槽个数.在本例中并未考虑任务换入换出,所以实际运行的任务有多少个,就定义多少个任务槽,不可多定义或少定义

  4. //任务的栈指针
  5. unsigned char idata task_sp[MAX_TASKS];
  6.          
  7. #define MAX_TASK_DEP 12 //最大栈深.最低不得少于2个,保守值为12.
  8.       //预估方法:以2为基数,每增加一层函数调用,加2字节.如果其间可能发生中断,则还要再加上中断需要的栈深.
  9.       //减小栈深的方法:1.尽量少嵌套子程序 2.调子程序前关中断.
  10. unsigned char idata task_stack[MAX_TASKS][MAX_TASK_DEP];//任务堆栈.

  11. unsigned char task_id;//当前活动任务号


  12. //任务切换函数(任务调度器)
  13. void task_switch(){
  14. task_sp[task_id] = SP;

  15. if(++task_id == MAX_TASKS)
  16.   task_id = 0;

  17. SP = task_sp[task_id];
  18. }

  19. //任务装入函数.将指定的函数(参数1)装入指定(参数2)的任务槽中.如果该槽中原来就有任务,则原任务丢失,但系统本身不会发生错误.
  20. void task_load(unsigned int fn, unsigned char tid){
  21. task_sp[tid] = task_stack[tid] + 1;
  22. task_stack[tid][0] = (unsigned int)fn & 0xff;
  23. task_stack[tid][1] = (unsigned int)fn >> 8;
  24. }

  25. //从指定的任务开始运行任务调度.调用该宏后,将永不返回.
  26. #define os_start(tid) {task_id = tid,SP = task_sp[tid];return;}




  27. /*============================以下为测试代码============================*/


  28. unsigned char stra[3], strb[3];//用于内存块复制测试的数组.




  29. //测试任务:复制内存块.每复制一个字节释放CPU一次
  30. void task1(){
  31. //每复制一个字节释放CPU一次,控制循环的变量必须考虑覆盖
  32. static unsigned char i;//如果将这个变量前的static去掉,会发生什么事?
  33. i = 0;

  34. while(1){//任务必须为死循环,不得退出函数,否则系统会崩溃
  35.   stra[i] = strb[i];
  36.   if(++i == sizeof(stra))
  37.    i = 0;

  38.   //变量i在这里跨越了task_switch(),因此它必须定义为静态(static),否则它将会被其它进程修改,因为在另一个进程里也会用到该变量所占用的地址.
  39.   task_switch();//释放CPU一会儿,让其它进程有机会运行.如果去掉该行,则别的进程永远不会被调用到
  40. }
  41. }

  42. //测试任务:复制内存块.每复制一个字节释放CPU一次.
  43. void task2(){
  44. //每复制一个字节释放CPU一次,控制循环的变量必须考虑覆盖
  45. static unsigned char i;//如果将这个变量前的static去掉,将会发生覆盖问题.task1()和task2()会被编译器分配到同一个内存地址上,当两个任务同时运行时,i的值就会被两个任务改来改去
  46. i = 0;

  47. while(1){//任务必须为死循环,不得退出函数,否则系统会崩溃
  48.   stra[i] = strb[i];
  49.   if(++i == sizeof(stra))
  50.    i = 0;

  51.   //变量i在这里跨越了task_switch(),因此它必须定义为静态(static),否则它将会被其它进程修改,因为在另一个进程里也会用到该变量所占用的地址.
  52.   task_switch();//释放CPU一会儿,让其它进程有机会运行.如果去掉该行,则别的进程永远不会被调用到
  53. }
  54. }

  55. //测试任务:复制内存块.复制完所有字节后释放CPU一次.
  56. void task3(){
  57. //复制全部字节后才释放CPU,控制循环的变量不须考虑覆盖
  58. unsigned char i;//这个变量前不需要加static,因为在它的作用域内并没有释放过CPU

  59. while(1){//任务必须为死循环,不得退出函数,否则系统会崩溃
  60.   i = sizeof(stra);
  61.   do{
  62.    stra[i-1] = strb[i-1];
  63.   }while(--i);

  64.   //变量i在这里已完成它的使命,所以无需定义为静态.你甚至可以定义为寄存器型(regiter)
  65.   task_switch();//释放CPU一会儿,让其它进程有机会运行.如果去掉该行,则别的进程永远不会被调用到
  66. }
  67. }

  68. void main(){
  69. //在这个示例里并没有考虑任务的换入换出,所以任务槽必须全部用完,否则系统会崩溃.
  70. //这里装载了三个任务,因此在定义MAX_TASKS时也必须定义为3
  71. task_load(task1, 0);//将task1函数装入0号槽
  72. task_load(task2, 1);//将task2函数装入1号槽
  73. task_load(task3, 2);//将task3函数装入2号槽

  74. os_start(0);//启动任务调度,并从0号槽开始运行.参数改为1,则首先运行1号槽.
  75.     //调用该宏后,程序流将永不再返回main(),也就是说,该语句行之后的所有语句都不被执行到.
  76. }
复制代码

看了看其形式就是
void  main (void)
{
while(1)
          {
            task_1();
                task_2();
                    task_3();  
          }  
}
我唯一的目的是想看一下51到底有跑多大,
另外,16位单片机代表MSP430是典型代表,
我马上会学到,真的希望有电子或是计算机专业的同学给我教教,杨秀旭,他好像在电子科技大学,我联系不上她,但是找他去
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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