大锤子 发表于 2024-11-21 09:52:35

向CosyOS成功迈出的第一步: 通过串口库助手观察任务管理器输出:





首先从作者的gitee仓库拉取最新的没有测试case的纯净版本,防止其他因素影响;


然后按照作者文档中心 -> 开发流程 创建keil 工程(为了使用CosyOS 给mac电脑装了个win系统 {:5_318:});
接下来添加需要的代码:
1、在初始化钩子中添加初始化代码:
/**************************************************************************//**
* @item   CosyOS-II Hook
* @file   init_hook.c
* @brief    初始化钩子
* @detail   在主函数中首先被调用,适用于初始化时钟、GPIO、寄存器等工作。
* @author   迟凯峰
* @versionV3.0.0
* @date   2024.06.25
******************************************************************************/

#include "..\System\os_link.h"

void init_hook(void)
{
        #define BAUD115200 // 串口波特率
        #define TM2   (65536 - SYSCFG_SYSCLK / 4 / BAUD)
        P0M0 = 0; P0M1 = 0;
        P1M0 = 0; P1M1 = 0;
        P2M0 = 0; P2M1 = 0;
        P3M0 = 0; P3M1 = 0;
        P4M0 = 0; P4M1 = 0;
        P5M0 = 0; P5M1 = 0;
        P6M0 = 0; P6M1 = 0;
        P7M0 = 0; P7M1 = 0;
       
        AUXR=        0x00;// 允许访问内部xdata
        P_SW2 =        EAXFR | 0x01; // xxxx xxxx = 1000 0000 允许访问扩展RAM区特殊功能寄存器, 我是用的是STCH试验箱,因此这里需要切换串口二的引脚;
       
        TMOD = 0x00;   // 定时器0、1、2、3、4为16位自动重装载模式
        AUXR = 0x45;   // 定时器1、2为1T模式,串口1用定时器2做波特率发生器
        SCON = 0x40;   // 串口1工作模式为模式1
        S2CON = 0x40;// 串口2工作模式为模式0,串口2用定时器2做波特率发生器
        P_SW1 = 0xC0;// 串口1切换至P4.3/P4.4
        TI = 1;      // 用于printf
        /* 定时器2 */
        T2L = (unsigned char)TM2;
        T2H = (unsigned char)(TM2 >> 8);
        AUXR|= T2R;
        /* UART2中断优先级为1级 */
        IP2H &=~PS2H;
        IP2 |= PS2;
        /* INT0中断优先级为0级 */
        IPH &=~PX0H;
        PX0 = 0;
        /* 任务管理器 */
        #if SYSCFG_DEBUGGING == 1
        S2CON |= S2REN;
        IE2 |= ES2;
        #endif
}


2、在用户分组下新建.C 文件编写串口处理程序(直接copy 作者的)
/**************************************************************************//**
* @item   CosyOS-II User
* @file   Taskmgr.c
* @brief    CosyOS-II 任务管理器
* @detail   当前配置为使用UART2,用户可自行调整。
             正常情况下,下方代码中,您仅需调整:UART2_Isr、中断向量号、S2CON、S2TI、S2RI、S2BUF。
             您需自行初始化串口、串口中断优先级、波特率等相关配置。
* @author   迟凯峰
* @versionV1.0.2
* @date   2024.05.11
******************************************************************************/

#include "..\System\os_link.h"
#if SYSCFG_DEBUGGING == __ENABLED__

void UART2_Isr(void) interrupt 8// using 3
{
        if(S2CON & S2TI){
                S2CON &= ~S2TI;
                if(*s_debug_sendptr){
                        S2BUF = *s_debug_sendptr++;
                }
                else{
                        iDebugSend;
                }
        }
        if(S2CON & S2RI){
                S2CON &= ~S2RI;
                if(s_debug_recvptr - s_debug_recvbuff < OS_DEBUGRECVBUFFSIZE - 1){
                        *s_debug_recvptr++ = S2BUF;
                }
                iDebugRecv;
        }
}

#endif
由于使用了串口二,需要使用LINK1D的另一组串口,接线如下:



效果如下:





CosyOS 发表于 2024-11-21 12:49:13

大锤子 发表于 2024-11-21 09:52
向CosyOS成功迈出的第一步: 通过串口库助手观察任务管理器输出:




{:5_332:}

任务管理器相关命令:
开启任务管理器:taskmgr
退出任务管理器:exit
设置任务管理器更新速度:taskmgr /s=xxx
xxx: 50~5000, 单位毫秒。

命令结尾要加 回车换行 \r\n
要靠串口助手自动加,而不是写到命令中。

大锤子 发表于 2024-11-22 14:34:46

使用CosyOS点亮试验箱的流水灯:


1、在用户组中添加led.h 头文件,和 led.c源文件:
这里有个小疑问, led.c 文件中的两个变量是全局变量把, 任务是不是不可重入的;

#ifndef __LED_H
#define __LED_H

dExternTask(led_flow);// 在头文件中声明任务

#endif#include "..\User\led.h"
#include "..\System\os_link.h"

s_u8_t xdata ledIndex;
s_u8_t code ledNum[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};

uCreateTask(led_flow, 1, 32,0,0) {
    P6 = ~ledNum;        //输出低驱动
      ledIndex++;
      if(ledIndex > 7)
      {
            ledIndex = 0;
      }
    uDelay_ms(300);
      
      uEndTasking;

}

2、在初始化钩子中设置端口,并且打开led电源开关:

P6M1 = 0x00;   P6M0 = 0xff;   //设置为推挽输出

P40 = 0;                //LED Power On


3、在启动钩子中启动任务:
/**************************************************************************//**
* @item   CosyOS-II Hook
* @file   start_hook.c
* @brief    启动钩子
* @detail   在启动任务中被调用,可在此启动用户任务。
* @serviceuStartTask(task, status); 启动任务
             uStartTask_Ready(task);   启动任务并就绪
             uStartTask_Suspend(task); 启动任务并挂起
* @author   迟凯峰
* @versionV3.0.0
* @date   2024.06.25
******************************************************************************/

#include "..\System\os_link.h"
#include "stdio.h"
#include "..\User\led.h"

void start_hook(void)
{
        uStartTask(led_flow, 0);
}


看流水灯和任务管理器效果:


CosyOS 发表于 2024-11-22 17:10:24

大锤子 发表于 2024-11-22 14:34
使用CosyOS点亮试验箱的流水灯:




任务创建 要 注意 动态 或 静态 的问题,

uCreateTask:静态创建
uExternTask:静态声明

dCreateTask:动态创建
dExternTask:动态声明

静态创建的要静态声明,动态创建的要动态声明,否则编译器应该会有警告!

大锤子 发表于 2024-11-22 19:14:42

CosyOS 发表于 2024-11-22 17:10
任务创建 要 注意 动态 或 静态 的问题,

uCreateTask:静态创建


哦哦,原来如此,确实有告警,没来得及看原因。

大锤子 发表于 2024-11-26 09:45:12

STC8试验箱例程16 用CosyOS实现

例程16的功能是:
1、模拟RTC显示时分;
2、行列扫描方式实现检测矩阵键盘更新时间;
3、数码管显示时间和按键值;

思路:
三个功能分别对应三个任务:
1、rtc_task:用来延时500ms,循环执行,执行过程中调用display_task 提供的修改显示缓存的函数;
2、display_task:延时1ms 通过P6,P7发送显示数据到595, 并且提供刷新显示缓存函数;
3、key_task:用来检测按键,调用led 提供的修改显示缓存函数修改按键显示值和时间显示;

步骤:
1、 按照迟老师教程搭建工程,也可以复制之前的工程,修改内容;
2、添加 lec.c , led.h、key.c、key.h、 rtc.h、rtc.c:

内容如下:
led.c:


#include "..\System\os_link.h"
#include "..\User\led.h"

#define DIS_DOT   0x20
#define DIS_BLACK   0x10
#define DIS_      0x11

s_u8_t code t_display[]={                     //标准字库
//   0    1    2    3    4    5    6    7    8    9    A    B    C    D    E    F
    0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,
//black-   H    J    K    L    N    o   P    U   t    G    Q    r   M    y
    0x00,0x40,0x76,0x1E,0x70,0x38,0x37,0x5C,0x73,0x3E,0x78,0x3d,0x67,0x50,0x37,0x6e,
    0xBF,0x86,0xDB,0xCF,0xE6,0xED,0xFD,0x87,0xFF,0xEF,0x46};    //0. 1. 2. 3. 4. 5. 6. 7. 8. 9. -1

s_u8_t code T_COM[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};      //位码


s_u8_tLED8;      //显示缓冲
s_u8_tdisplay_index;//显示位索引

uCreateTask(display_task, 6, 32, 0 ,0 ) {// 创建任务,名称为display_task,优先级为6,给定任务栈大小为32字节;
       
        s_u8_t i;
        for(i=0; i<8; i++) {
                LED8 = 0x10; //上电消隐
        }
        display_index = 0;
        refreshDisplay(12, 30, 0);
       
        while (1) {
               
                P7 = ~T_COM;
                P6 = ~t_display];
                if(++display_index >= 8) {
                        display_index = 0;//8位结束回0
                }
       
                uDelay_ms(1);        // 1毫秒延时, 延时时间到后发送数据到595
        }
       
       
        uEndTasking;
       
}

void refreshDisplay(s_u8_t hour, s_u8_t minute, s_u16_t msecond) {
        if(hour >= 10) {
               LED8 = hour / 10;
        }
    else {
                LED8 = DIS_BLACK;
        }
    LED8 = hour % 10;
    LED8 = minute / 10;
    LED8 = minute % 10;
    if(msecond >= 500) {
                LED8 |= DIS_DOT; //小时后的小数点做秒闪
        }
}

void showKeyCode(s_u8_t keyCode) {
        LED8 = keyCode / 10; //显示键码
    LED8 = keyCode % 10; //显示键码
}led.h
#ifndef __LED_H
#define __LED_H

uExternTask(display_task);

void showKeyCode(s_u8_t keyCode);
void refreshDisplay(s_u8_t hour, s_u8_t minute, s_u16_t msecond);

#endifrtc.c
#include "..\System\os_link.h"
#include "..\User\rtc.h"
#include "..\User\led.h"

s_u8_thour,minute,second; //RTC变量
s_u16_t msecond;

void RTC(void)
{
    if(++second >= 60)
    {
      second = 0;
      if(++minute >= 60)
      {
            minute = 0;
            if(++hour >= 24) {
                                hour = 0;
                        }
      }
    }
}

uCreateTask(rtc_task, 5, 32, 0, 0) {
        hour = 12;
        minute = 0;
        second = 0;
        msecond = 0;
        while(1) {
                msecond += 500;
                if(msecond >= 1000) {
                        msecond = 0;
                        RTC();
                }

      refreshDisplay(hour, minute, msecond);
               
                uDelay_ms(500);
        }
       
        uEndTasking;
}

void addHour(void) {
        if(++hour >= 24) {
                hour = 0;
        }
       
        refreshDisplay(hour, minute, msecond);
}


void decHour(void) {
        if(--hour >= 24) {
                hour = 23;
        }   
        refreshDisplay(hour, minute, msecond);
}

void addMin(void) {
        second = 0;
    if(++minute >= 60) {
                minute = 0;
        }
}

void decMin(void) {
        second = 0;
    if(--minute >= 60) {        // 这里就很巧妙,利用溢出
               minute = 59;
        }
}

rtc.h
#ifndef __RTC_H
#define __RTC_H

void addHour(void);
void decHour(void);
void addMin(void);
void decMin(void);
void RTC(void);
uExternTask(rtc_task);

#endifkey.c
#include "..\System\os_link.h"
#include "..\User\rtc.h"
#include "..\User\key.h"
#include "..\User\led.h"

s_u8_tKeyCode;    //给用户使用的键码, 1~16有效

s_u8_t IO_KeyState, IO_KeyState1, IO_KeyHoldCnt;    //行列键盘变量

s_u8_t code T_KeyTable = {0,1,2,0,3,0,0,0,4,0,0,0,0,0,0,0};

void IO_KeyDelay(void)
{
    s_u8_t i;
    i = 60;
    while(--i);
}

void IO_KeyScan(void)    //50ms call
{
    s_u8_tj;

    j = IO_KeyState1;   //保存上一次状态

    P0 = 0xf0;//X低,读Y
    IO_KeyDelay();
    IO_KeyState1 = P0 & 0xf0;

    P0 = 0x0f;//Y低,读X
    IO_KeyDelay();
    IO_KeyState1 |= (P0 & 0x0f);
    IO_KeyState1 ^= 0xff;   //取反
   
    if(j == IO_KeyState1)   //连续两次读相等
    {
      j = IO_KeyState;
      IO_KeyState = IO_KeyState1;
      if(IO_KeyState != 0)    //有键按下
      {
            F0 = 0;
            if(j == 0)F0 = 1; //第一次按下
            else if(j == IO_KeyState)
            {
                if(++IO_KeyHoldCnt >= 20)   //1秒后重键
                {
                  IO_KeyHoldCnt = 18;
                  F0 = 1;
                }
            }
            if(F0)
            {
                j = T_KeyTable;
                if((j != 0) && (T_KeyTable != 0))
                  KeyCode = (j - 1) * 4 + T_KeyTable + 16;    //计算键码,17~32
            }
      }
      else    IO_KeyHoldCnt = 0;
    }
    P0 = 0xff;
}


uCreateTask(key_task, 4, 32,0 ,0) {

        while(1) {
                IO_KeyScan();
               
                if(KeyCode > 0)   //有键按下
      {
                        showKeyCode(KeyCode);

            if(KeyCode == 25)   //hour +1
            {
                addHour();
            }
            if(KeyCode == 26)   //hour -1
            {
                decHour();
            }
            if(KeyCode == 27)   //minute +1
            {
                addMin();
            }
            if(KeyCode == 28)   //minute -1
            {
                decMin();
            }
            KeyCode = 0;
      }
               
               
                uDelay_ms(50);
        }
       
        uEndTasking;

}key.h
#ifndef __KEY_H
#define __KEY_H

uExternTask(key_task);

#endif3、修改初始化钩子和启动钩子
/**************************************************************************//**
* @item   CosyOS-II Hook
* @file   init_hook.c
* @brief    初始化钩子
* @detail   在主函数中首先被调用,适用于初始化时钟、GPIO、寄存器等工作。
* @author   迟凯峰
* @versionV3.0.0
* @date   2024.06.25
******************************************************************************/

#include "..\System\os_link.h"

void initGPIO(void) {
        P0M1 = 0x30;   P0M0 = 0x30;   //设置P0.4、P0.5为漏极开路(实验箱加了上拉电阻到3.3V)
    P1M0 = 0; P1M1 = 0;
    P2M0 = 0; P2M1 = 0;
    P3M0 = 0; P3M1 = 0;
    P4M0 = 0; P4M1 = 0;
    P5M0 = 0; P5M1 = 0;
        P6M1 = 0xff;   P6M0 = 0xff;   //设置为漏极开路(实验箱加了上拉电阻到3.3V)
    P7M1 = 0x00;   P7M0 = 0x00;   //设置为准双向口
}

void init_hook(void)
{
        #define BAUD115200 // 串口波特率
    #define TM2   (65536 - SYSCFG_SYSCLK / 4 / BAUD)
   
        initGPIO();                // 初始化GPIO
       
       
    AUXR=      0x00;// 允许访问内部xdata
    P_SW2 =      EAXFR | 0x01; // xxxx xxxx = 1000 0000 允许访问扩展RAM区特殊功能寄存器, 我是用的是STCH试验箱,因此这里需要切换串口二的引脚;
   
    TMOD = 0x00;   // 定时器0、1、2、3、4为16位自动重装载模式
    AUXR = 0x45;   // 定时器1、2为1T模式,串口1用定时器2做波特率发生器
    SCON = 0x40;   // 串口1工作模式为模式1
    S2CON = 0x40;// 串口2工作模式为模式0,串口2用定时器2做波特率发生器
    P_SW1 = 0xC0;// 串口1切换至P4.3/P4.4
    TI = 1;      // 用于printf
    /* 定时器2 */
    T2L = (unsigned char)TM2;
    T2H = (unsigned char)(TM2 >> 8);
    AUXR|= T2R;
    /* UART2中断优先级为1级 */
    IP2H &=~PS2H;
    IP2 |= PS2;
    /* INT0中断优先级为0级 */
    IPH &=~PX0H;
    PX0 = 0;
    /* 任务管理器 */
    #if SYSCFG_DEBUGGING == 1
    S2CON |= S2REN;
    IE2 |= ES2;
    #endif
}


效果演示:





CosyOS 发表于 2024-11-26 14:41:49

本帖最后由 CosyOS 于 2024-11-26 15:27 编辑

大锤子 发表于 2024-11-26 09:45
STC8试验箱例程16 用CosyOS实现

例程16的功能是:

现在貌似任务已经正常运行,但仍存在一些不可靠因素,需一步优化、调整。


1、refreshDisplay 应被定义为 不可重入函数,因为它被设计用来固定写访问全局数组 LED8[]。
三个任务都调用了该函数,
display_task 无所谓,因为仅初始化时调用一次;
rtc_task、key_task,可能会频繁调用该函数,而它们的任务优先级又不相同,长时间运行后,有 高优先级任务 打断 低优先级任务 的可能,导致在概率上必然存在 refreshDisplay 重入。


2、rtc_task、key_task,都会访问全局的RTC变量,对它们进行 读、写、自运算。
由于自运算的存在,每个变量(hour, minute, second, msecond)都要保证不会重入(自运算过程不可打断);
同时,hour, minute, second, msecond 也应做为一个整体来看,保证整体的不会重入;
由于 这两个任务的优先级不同,所以在概率上必然存在 RTC变量 重入。

综上所述,把三个任务都调整为相同的优先级(display_task 可以用不同优先级),且保证每个任务的运行时间(while(1)中,从头到 uDelay_ms 之前)都小于时间片,可能是一种比较好的实现互斥访问的方法,整体运行也将会非常可靠。(当然也可以考虑 任务临界区 等其它的互斥访问方法,但我认为 相同优先级的方法最好。)
如此的话,display_task 中,uDelay_ms(1) 可能需要适当延长,相同优先级的话。
另外,也许还存在其它一些我看不到的问题,就要靠你自己多思考了。

其它提示:
1、display_task 中,更新 P7、P6 的工作 可考虑在 滴答钩子中执行,每滴答周期执行一次。(就不需要 display_task 了)
   这将会是一个非常好的方法,推荐采用!
2、可考虑结合 CosyOS 的 软件RTC,一并应用。





CosyOS 发表于 2024-11-26 16:10:42

本帖最后由 CosyOS 于 2024-11-26 16:13 编辑

大锤子 发表于 2024-11-26 09:45
STC8试验箱例程16 用CosyOS实现

例程16的功能是:

如果你 启用了 CosyOS 的软件RTC,就可以用更高明的方法来实现这些功能。
1、display_task 中,更新 P7、P6 的工作 在 滴答钩子中执行,每滴答周期执行一次。
2、refreshDisplay 这个函数的功能,可全部在 滴答钩子中实现,不再需要此函数。
3、rtc_task 也不再需要,因为 RTC 将由 OS 更新。
4、仅需要一个 key_task 就可以了,在 key_task 中,先获取RTC到本地,
   而后按键导致的时间变化也更新本地的,最后再设置RTC。

如此,仅需一个 key_task 就可实现全部这些功能。
有兴趣的话,你自己尝试一下吧!

大锤子 发表于 2024-11-26 20:59:27

hsrzq 发表于 2023-5-6 14:00
膜拜大神,坐等向sdcc编译器的迁移

爬楼中,遇到了大佬

大锤子 发表于 2024-12-2 00:16:48

试验箱例程16 通过CosyOS实现改版

上一个版本存在一些问题,在迟老师的耐心细致的指导下,结合最新版的CosyOS 重新实现,最终只保留一个key_task;

思路:
key_task 做按键检查,使用矩阵键盘,行列扫描的方式实现;
原来的模拟RTC任务rtc_task 使用CosyOS的软件RTC实现;
原来的显示数据发送任务led_task 使用滴答钩子实现;

具体代码:
key_task.c:
#include "..\System\os_link.h"
#include "..\User\key.h"
#include "..\User\led.h"

s_u8_tKeyCode;    //给用户使用的键码, 1~16有效

s_u8_t IO_KeyState, IO_KeyState1, IO_KeyHoldCnt;    //行列键盘变量

s_u8_t code T_KeyTable = {0,1,2,0,3,0,0,0,4,0,0,0,0,0,0,0};

void IO_KeyDelay(void)
{
    s_u8_t i;
    i = 60;
    while(--i);
}

void IO_KeyScan(void)    //50ms call
{
    s_u8_tj;

    j = IO_KeyState1;   //保存上一次状态

    P0 = 0xf0;//X低,读Y
    IO_KeyDelay();
    IO_KeyState1 = P0 & 0xf0;

    P0 = 0x0f;//Y低,读X
    IO_KeyDelay();
    IO_KeyState1 |= (P0 & 0x0f);
    IO_KeyState1 ^= 0xff;   //取反
   
    if(j == IO_KeyState1)   //连续两次读相等
    {
      j = IO_KeyState;
      IO_KeyState = IO_KeyState1;
      if(IO_KeyState != 0)    //有键按下
      {
            F0 = 0;
            if(j == 0)F0 = 1; //第一次按下
            else if(j == IO_KeyState)
            {
                if(++IO_KeyHoldCnt >= 20)   //1秒后重键
                {
                  IO_KeyHoldCnt = 18;
                  F0 = 1;
                }
            }
            if(F0)
            {
                j = T_KeyTable;
                if((j != 0) && (T_KeyTable != 0))
                  KeyCode = (j - 1) * 4 + T_KeyTable + 16;    //计算键码,17~32
            }
      }
      else    IO_KeyHoldCnt = 0;
    }
    P0 = 0xff;
}


uCreateTask(key_task, 4, 32,0 ,0) {

        while(1) {
                IO_KeyScan();
               
                if(KeyCode > 0)   //有键按下
      {
                        s_rtc_ts u_rtc;
                        showKeyCode(KeyCode);
                       
                        uGetTime(&u_rtc);        // 获取RTC到本地

            if(KeyCode == 25)   //hour +1
            {
                if(++u_rtc.hour >= 24) {
                                        u_rtc.hour = 0;
                                }
            }
            if(KeyCode == 26)   //hour -1
            {
               if(--u_rtc.hour >= 24) {
                                        u_rtc.hour = 23;
                           }
            }
            if(KeyCode == 27)   //minute +1
            {
                u_rtc.second = 0;
                                if(++u_rtc.minute >= 60) {
                                        u_rtc.minute = 0;
                                }
            }
            if(KeyCode == 28)   //minute -1
            {
                u_rtc.second = 0;
                                if(--u_rtc.minute >= 60) {
                                        u_rtc.minute = 59;
                                }
            }
                       
                        uSetTime(&u_rtc);
            KeyCode = 0;
      }
               
               
                uDelay_ms(50);
        }
       
        uEndTasking;

}

tick_hook.c
/**************************************************************************//**
* @item   CosyOS-II Hook
* @file   tick_hook.c
* @brief    滴答钩子
* @detail   每个系统滴答周期,在系统滴答中断中都会被调用一次,
             适用于每滴答周期/秒/分/时/日/月/年/...做一次的工作。
* @note1. 如果您在滴答钩子中调用服务,应调用滴答API。
          2. 如果您在滴答钩子中调用自定义函数并且您的MCU内核为8051,自定义函数
             可能需要添加using属性、或声明为相对寄存器访问。
             demo1:
             void your_function(void) MCUCFG_C51USING {... ...}
            
             demo2:
             #pragma NOAREGS
             void your_function(void) {... ...}
             #pragma AREGS
* @author   迟凯峰
* @versionV3.1.0
* @date   2024.11.26
******************************************************************************/

#include "..\System\os_link.h"
#include "..\User\led.h"

#if SYSCFG_TICKHOOK == __ENABLED__

void tick_hook(void) MCUCFG_C51USING
{
        if(true){ /* 每滴答周期执行一次 */
                refreshDisplay();
                sendData();
        }
        #if SYSCFG_SOFTRTC == __ENABLED__
        if(s_sign_every.halfsec){
                s_sign_every.halfsec = false;
                if(true){ /* 每半秒执行一次(每半秒,first tick)*/
                        setDot();
                }
                if(s_sign_every.second){
                        s_sign_every.second = false;
                        if(true){ /* 每秒钟执行一次(每秒,first tick)*/
                                clearDot();
                        }
                        if(s_sign_every.minute){
                                s_sign_every.minute = false;
                                if(true){ /* 每分钟执行一次(每分0秒,first tick)*/
                                       
                                }
                                if(s_sign_every.hour){
                                        s_sign_every.hour = false;
                                        if(true){ /* 每小时执行一次(每时0分0秒,first tick)*/
                                               
                                        }
                                        if(s_sign_every.day){
                                                s_sign_every.day = false;
                                                if(true){ /* 每天执行一次(每天0时0分0秒,first tick)*/
                                                       
                                                }
                                                if(s_sign_every.month){
                                                        s_sign_every.month = false;
                                                        if(true){ /* 每月执行一次(每月1日0时0分0秒,first tick)*/
                                                               
                                                        }
                                                        if(s_sign_every.year){
                                                                s_sign_every.year = false;
                                                                if(true){ /* 每年执行一次(每年1月1日0时0分0秒,first tick)*/
                                                                       
                                                                }
                                                        }
                                                }
                                        }
                                }
                        }
                }
        }
        #endif
}

#endif
led.c


#include "..\System\os_link.h"
#include "..\User\led.h"

#define DIS_DOT   0x20        // 0010 0000,
#define DIS_BLACK   0x10       
#define DIS_      0x11

s_u8_t code t_display[]={                     //标准字库
//   0    1    2    3    4    5    6    7    8    9    A    B    C    D    E    F
    0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,
//black-   H    J    K    L    N    o   P    U   t    G    Q    r   M    y
    0x00,0x40,0x76,0x1E,0x70,0x38,0x37,0x5C,0x73,0x3E,0x78,0x3d,0x67,0x50,0x37,0x6e,
    0xBF,0x86,0xDB,0xCF,0xE6,0xED,0xFD,0x87,0xFF,0xEF,0x46};    //0. 1. 2. 3. 4. 5. 6. 7. 8. 9. -1

s_u8_t code T_COM[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};      //位码

s_u8_t LED8 = {1,2,3,0,0,0,0,0};


void sendData(void) MCUCFG_C51USING {
        static s_u8_t display_index = 0;
        P7 = ~T_COM;
        P6 = ~t_display];
        if(++display_index >= 8) {
                display_index = 0;//8位结束回0
        }
}


void refreshDisplay(void) MCUCFG_C51USING {
       
        if(s_rtc.hour >= 10) {
                LED8 = s_rtc.hour / 10;
        } else {
                LED8 = DIS_BLACK;
        }
        LED8 = (LED8 &DIS_DOT) | s_rtc.hour % 10;    // 这里注意,否则会导致秒点不闪
        LED8 = s_rtc.minute / 10;
        LED8 = s_rtc.minute % 10;
}

void showKeyCode(s_u8_t keyCode) {
        LED8 = keyCode / 10; //显示键码
    LED8 = keyCode % 10; //显示键码
}

void setDot(void) {
        LED8 |= DIS_DOT;
}

void clearDot(void) {
        LED8 &= ~DIS_DOT;
}

效果展示:


最后:
率先使用了CosyOS的最新版本,任务管理器的内容更加美观易读。 滴答钩子中添加了半秒处理选项;


页: 89 90 91 92 93 94 95 96 97 98 [99] 100 101 102 103 104 105 106 107 108
查看完整版本: 全局不关总中断的 RTOS,CosyOS-III-V1.2.0, 送 擎天柱-AI8051U转89C52核心板