STC8H运行smallRTOS51操作系统(1)

最近做一个小项目,功能稍显复杂,由于以前做STM32的项目用了freeRTOS比较多,体验到了用操作系统的便捷性。因此用STC8H单片机时,不太愿意跑裸机了,于是乎就考虑在51单片机上运行一个小型操作系统。

51单片机可运行的操作系统可选性并不多,经典的可以用KEIL软件自带的tiny51系统,实际测试的时候,发现该系统比较简单、占用内存比较少,主要是基于时间片轮询的方案,当多个任务同时运用公共资源(比如都用串口输出),经常会出现输出内容不正确的情况,因此,暂时放弃了该操作系统。

思来想去,当年读大学的时候接触过一点点陈明计先生的smallRTOS操作系统,于是准备启用起来。本文的处理器采用的是STC8H1K08。

于是在网上开始查找smallRTOS代码。首先是源码,估计是网上用的并不多,操作系统的源码还真不好找,下面给出了百度网盘的下载地址:

链接:https://pan.baidu.com/s/1LnV6ty-uW7CoqvDQGmuo8g 
提取码:zfdc

源码下载后,解压出来有三个文件夹,如下图所示:

 CONFIG_H文件夹下面,是三个与操作系统配置相关的三个.h文件,其中系统的主要配置config.h就在该文件夹下。在自己新建KEIL工程的时候,这三个.h文件必须和KEIL的工程文件放在一起,否则会编译出错,这一点尤为重要。

OS文件夹存放的是操作系统的源码,如下图所示:

 OS_CORE.C是操作系统的核心实现代码,OS_Q是消息队列的实现代码,OS_SEM是信号量实现代码。

TARGET_CPU是与51单片机底层相关的文件,包含一个.c文件和汇编文件,如下图所示:

 下面新建自己的一个keil工程。其中新建keil工程就不复述了,本文只是记录一下如何将smallRTOS新添加到工程中。将smallROTS51的源码复制到新建的keil工程目录下,如下图所示:

 smallrtos51目录为操作系统的源码,然后将源码中的CONFIG_H目录下的三个.h头文件剪切到keil工程目录下,如上图的红色圈,这一步非常重要,否则会编译错误。

然后在keil中新建一个smallrtos的分组,将os的相关文件添加到文件分组内

 然后编写main函数,主函数主要就是初始化定时器0(该定时器用于操作系统的滴答信号)和启动操作系统,代码如下:

void main()  
{
    SysInit();  //端口及外设初始化    
      OSStart(); //启动操作系统
    while(1);
}    

SysInit函数是我自己编写的一个初始化本项目的 io端口和相关外设的(暂时只是IO口初始化和串口初始化),代码如下:

void SysInit(void) //系统初始化函数
{
    P1M1 = 0x0e;        // 0000 1110  配置P10,P14,P16,P17为推挽输出, P15为准双向口,P11,P12,P13为高阻输入
      P1M0 = 0xd1;     // 1101 0001
      P1PU = 0x20;      //使能P15上拉电阻  0--禁止  1--打开
    
      P3M1 = 0xf4;        // 1111 0100  配置P34~P37为开漏输出,并使能上拉电阻,实现按键输入; P33为推挽输出 驱动LED灯
      P3M0 = 0xf8;      // 1111 1000
      P3PU = 0xff;
    
      P5M1 = 0xff;
      P5M0 = 0xff;     //P5配置为开漏 并使能上拉电阻 P54为按键
      P5PU = 0xf5;
    
/*************定时器0初始化--用于smallrtos滴答时钟*********************************/
/*************经测 不能添加定时器初始值 不能设定为自动重载*********************************/    
       AUXR |= 0x80;        //定时器时钟1T模式       //计算后操作系统的滴答时钟周期为65536/24M=2.73ms
        TMOD = (TMOD & 0XF0) | 0X01;
       TL0 = 0x0; 
       TH0 = 0x0;
       TR0 = 1;
       ET0 = 1;
/*********************************************************************************/ 

/*************串口1初始化 9600bps@24.000MHz*********************************/
   SCON = 0x50;        //8位数据,可变波特率
     AUXR |= 0x01;        //串口1选择定时器2为波特率发生器
     AUXR &= 0xFB;        //定时器时钟12T模式
     T2L = 0xCC;        //设置定时初始值
     T2H = 0xFF;        //设置定时初始值
     AUXR |= 0x10;        //定时器2开始计时
     ES = 1;
    
     uart1_busy = 0;
/******************************************************/ 
   EA = 0;    //关闭总中断  在启动操作系统函数OSStart();前不能先打开中断
}

然后配置操作系统参数,打开config.h文件,第一步更改头文件,将系统默认的51单片机的reg52.h更改为stc单片机的头文件,如下所示:

 第二步是添加系统的多任务函数定义,本应用定义了5个任务如下所示:

 第三步是更改OS_MAX_TASKS为5,该变量在OS_CFG.H头文件中,更改为5,如下所示:

 第四步编写5个任务函数,均在main.c文件中添加,本文5个任务代码均相同,代码如下:

/************************************************************/
void TaskA(void)
{
    while (1)
    {
              Uart1_SendString("this is taskA running\r\n");    
        OSWait(K_TMO,183);  //延时183*2.73ms=500ms
              OSWait(K_TMO,183);  //延时183*2.73ms=500ms
    } 
}

代码的功能是每隔1s钟窗口输出各自任务的运行状态。

然后编译程序,基本上是没问题的,如下所示是本文的编译结果。

 有5个警告,均是定义了某些函数(这几个函数是我自己编写的,暂时还没有调用),不影响代码的正常运行。可以看到编译后代码所占用的内存空间是非常少的。

最后下载到硬件板子上,查看运行结果,如下所示:

 基本上每隔1s打印一次数据,5个任务打印的内容是不影响的,如果用tiny51系统的话,打印的内容会经常出错。

下面给出本工程的全部代码,编译通过并且运行正常。

链接:https://pan.baidu.com/s/1ug_h3zNOgJIyy3TfS3w2qg 
提取码:kvav

后续会进一步实验信号量和消息队列的内容。

  • 10
    点赞
  • 50
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值