初试 STC8A8K64D4 库函数 + Small RTOS51 1.12

2023-10-17 18:10

本文主要是介绍初试 STC8A8K64D4 库函数 + Small RTOS51 1.12,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

零、目录

零、目录

一、注意事项

二、本次期望达到的目标

三、添加 STC8A8K64D4 库函数

四、Small RTOS51 1.12 的移植

五、编写多线程测试代码

六、总结


一、注意事项

  1. 本次使用 STC8A8K64D4 作为 MCU,其库函数可以在 STC 官网下载:http://www.stcmcudata.com/
  2. 本次使用 Small RTOS51 1.12 版本,1.20 版本等以后有空了再瞅瞅,目前先用 1.12 版本的学习学习。网络上有关 1.12 版本的下载路径很多,这里暂时不单独贴出。
  3. Small RTOS51 在类型定义、文件命名部分与 STC8A8K64D4 相冲突,编译时将会导致报错。这里采用的解决方法是对 Small RTOS51 的文件进行小的修改,因为 Small RTOS51 也可以移植到其他的 STC 51 单片机上,如果要用到 STC 的库函数的话,这些小的修改将有利于今后的移植。
  4. 如果不适应 STC 库函数的话,本教程也可以适用于单纯 Small RTOS51 的移植,只需要跳过有关 Small RTOS51 的代码修改、库函数的移植和使用即可。

       


二、本次期望达到的目标

  1. 利用 STC8A8K64D4 在 33.1776MHz 的时钟下通过 UART1 打印三个任务的信息,以初步体验使用 Small RTOS51 来进行多任务操作。
  2. 略微小改 Small RTOS51 的部分类型、文件命名,使其可以兼容 STC8A8K64D4 的库函数,同时修改 OSWait() 的参数类型,使其数据类型便于修改,并可以实现延时时间的加长,这个步骤可以依据实际情况进行,可以不修改如果想用寄存器而不使用库函数,则可以跳过 Small RTOS51 的修改,因为修改只是为了兼容库函数,不会影响 RTOS 的实际功能。

        


三、添加 STC8A8K64D4 库函数

  1. 在 STC 官网下载 STC8A8K64D4 库函数,解压压缩包,官方的库函数均存放于 Driver 文件夹下。
  2. 官方的库文件还依赖其他文件,有:Config.h、isr.arm、STC8A8K64D4.H 和 Type_def.h

  3. 新建 KEIL 项目,将 Driver 文件夹放到工程文件夹下,将前面提到的 4 个文件也添加到 Driver/ 路径下。

  4. 内存模式设置为 small 模式。

  5. 在 KEIL 项目中添加需要的文件,本次只需要使用以下功能:STC8A_Delay.c (延时)、STC8A_UART.c (串口输出)。同时添加库函数的中断函数 STC8A_UART_Isr.c。

  6. 添加 Driver/ 路径和 Driver/Inc/ 路径到项目中。

  7. 到 Config.h 下修改 MCU 时钟频率,本次时钟为 33177600L。

  8. 编写程序进行测试,查看库函数是否移植成功:

    #include "Config.h"
    #include "STC8A_Delay.h"
    #include "STC8A_UART.h"void main(void)
    {COMx_InitDefine xdata com;P_SW2 |= 0x80;com.BaudRateDouble = DISABLE;com.Morecommunicate = DISABLE;com.UART_BaudRate = 115200;com.UART_BRT_Use = BRT_Timer1;com.UART_Mode = UART_8bit_BRTx;com.UART_RxEnable = ENABLE;UART_Configuration(UART1, &com);ES = 1;EA = 1;while(1){delay_ms(1000);PrintString1("Hello STC8A8K Driver!\r\n");}
    }

     烧录程序后到串口查看效果。

          可以看到串口正常输出,表明库函数移植完成。


四、Small RTOS51 1.12 的移植

  1.  Small RTOS51 代码文件夹下有三个文件夹:CONFIG_H/、OS/、TARGET_CPU/。将这三个文件夹添加到 KEIL 项目文件夹下。由于这三个文件夹都在 Small_RTOS51/ 文件夹下,因此直接赋值该文件夹即可。
  2. 修改 CONFIG_H 文件夹下的 CONFIG.H 的文件名,由于库函数的 Config.h 被库函数的很多文件引用,因此这里将修改 Small RTOS51 的 CONFIG.H 头文件,避免因为重名而导致文件无法添加到 KEIL  项目中本次将 CONFIG.H 改名为 SmallRTOS51.H(因为用户只需要包含该头文件即可调用到 Small RTOS51 的系统函数,因此仿照 rtthread.h 进行命名)。
  3. 到 KEIL 项目中添加 Small RTOS51 的所有文件。
  4. 由于 OS_CPU_A.ASM 引用了 OS_CPU.H 和 OS_CFG.H,因此需要为 .asm 添加头文件路径:Option for Target → A51 → Include Paths 中添加 .h 头文件路径。
  5. 因为前面修改了 CONFIG.H 的文件名,因此需要到以下文件中手动修改 #include 引用的文件名 —— 修改为新命名的文件名即可。如果不使用库函数则可以跳过这一步。
    OS_CORE.C
    OS_Q.C
    OS_SEM.C
    OS_CPU_C.C
  6. 由于 Small RTOS51 的类型定义与库函数重叠,考虑到今后的移植,这边将对 Small RTOS51 的数据类型进行修改如果嫌这步麻烦的阅读者可以跳过这一步

    1. 利用 VSCODE,将以 “uint” 开头的类型全部替换为 “os_uint”、以 “int” 开头的类型全部替换为 “os_int”(Small RTOS51 中基本上使用的都是 uint8 类型)。

      typedef unsigned char  os_uint8;                                   /* 定义可移植的无符号8位整数关键字            */
      typedef signed   char  os_int8;                                    /* 定义可移植的有符号8位整数关键字            */
      typedef unsigned int   os_uint16;                                  /* 定义可移植的无符号16位整数关键字           */
      typedef signed   int   os_int16;                                   /* 定义可移植的有符号16位整数关键字           */
      typedef unsigned long  os_uint32;                                  /* 定义可移植的无符号32位整数关键字           */
      typedef signed   long  os_int32;                                   /* 定义可移植的有符号32位整数关键字           */
    2. 将 #define const code 移除,将用到 const 关键字的变量修改为 code 修饰的变量。(可做可不做)

    3. 在 OS_CPU.H 中,新添类型:

      typedef os_uint16	   os_tick_t;

      添加该类型的目的是为便于修改 OSWait() 的延时时长,原版的 OSWait() 只能延时 255 个系统滴答时钟,修改为 16位 数据类型后可以延长到 65535 个系统滴答时钟,而且使用 typedef 的方法也便于类型的修改。

      需要修改的函数和数组有:

      函数OSWait() 的 tick 参数
      函数

      OSSemPend() 的 tick 参数

      函数

      OSQPend() 的 tick 参数

      数组

      OSWaitTick[]

      修改完后,OSWait() 的延时时长便可方便的进行修改了。

  7. 到 OS_CFG.H 中,修改一下宏定义:

    #define OS_MAX_TASKS            3          /* 最大任务数1~16                                           */
    #define OS_TICKS_PER_SEC        0          /* 声明1秒系统系统节拍数,这个得自己计算出来   os_uint8 OSWaitTick[OS_MAX_TASKS];   */
    #define EN_USER_TICK_TIMER      0          /* 禁止(0)或允许(1)系统定时中断调用用户函数UserTickTimer() ,在系统中断中挂钩的用户计时器 */
    #define EN_OS_INT_ENTER         1           /* 禁止(0)或允许(1)中断嵌套管理                             */
    #define EN_TIMER_SHARING        1           /* 禁止(0)或允许(1) 系统 定时器中断调用OSTimeTick() ,禁止时要在高优先级任务中调用 OSTimeTick()*/
    #define TICK_TIMER_SHARING      1           /* 定义进入多少次硬件中断为一次系统定时器软中断             */

    OS_TICKS_PER_SEC 在当前版本的 Small RTOS51 中并未使用。TICK_TIMER_SHARING 意思是,累计触发若干次硬件定时器中断作为一次系统滴答计数。这里修改为 1 意味着一次硬件定时器中断就是一次系统滴答计数。EN_OS_INT_ENTER 需要被开启,因为涉及到串口的数据发送,这里会引起新的中断,因此要加入中断嵌套管理。

  8. 到 OS_CPU.H 中,修改一下宏定义:

    #define  OS_TIME_ISR     1                                     /* 系统定时器使用的中断                           */

    由于 STC8A8K64D4 的 Timer0 的已经具备了专用于 RTOS 的 16位不可屏蔽的自动重装载模式,因此这里选用 Timer0 作为系统定时器。

  9. 编译项目,若无报错即移植完毕。

       


五、编写多线程测试代码

  1. 编写 main.c
    #include "Config.h"
    #include "STC8A_Delay.h"
    #include "STC8A_UART.h"
    #include "SMALLRTOS51.H"void task1(void)
    {while(1){PrintString1("task1\r\n");OSWait(K_TMO, 1000);}
    }void task2(void)
    {while(1){PrintString1("\ttask2\r\n");OSWait(K_TMO, 3000);}
    }void task3(void)
    {while(1){PrintString1("\ttask3\r\n");OSWait(K_TMO, 5000);}
    }void main(void)
    {P_SW2 |= 0x80;do{// 配置系统时钟: 33.1776MHzAUXR &= 0x7F;		// 定时器时钟12T模式TMOD &= 0xF0;		// 设置定时器模式TL0 = 0x33;			// 设置定时初始值TH0 = 0xF5;			// 设置定时初始值TF0 = 0;			// 清除TF0标志TR0 = 1;			// 定时器0开始计时ET0 = 1;			// 开启定时器中断} while (0);do{COMx_InitDefine xdata com;P_SW2 |= 0x80;com.BaudRateDouble = DISABLE;com.Morecommunicate = DISABLE;com.UART_BaudRate = 115200;com.UART_BRT_Use = BRT_Timer1;com.UART_Mode = UART_8bit_BRTx;com.UART_RxEnable = ENABLE;UART_Configuration(UART1, &com);ES = 1;} while(0);OSStart();while(1);
    }
  2. 修改任务列表
    /********************************/
    /*     "以下为系统配置"           */
    /********************************/
    #pragma  REGPARMS
    #include "STC8A8K64D4.H"
    #include <intrins.h>
    #include <absacc.h>/********************************/
    /*     "操作系统定义"            */
    /********************************/
    #include "OS_CFG.H"
    #include "OS_CPU.H"
    #include "OS_CORE.H"
    #include "OS_SEM.H"
    #include "OS_Q.H"/********************************/
    /*     "以下为程序配置"           */
    /********************************/
    //任务定义
    #ifdef IN_OS_CPU_C_C               // 保证以下声明只在 OS_CPU_C中出现extern void task1(void);
    extern void task2(void);
    extern void task3(void);void  (* code TaskFuction[OS_MAX_TASKS])(void)={task1,task2,task3};//函数数组TaskFuction[]保存了各个任务初始PC指针,其按任务ID(既优先级次序)顺序保存
    #endif
  3. 修改在库函数的 Config.h 头文件中 #include "SmallRTOS51.h",为串口中断函数添加中断管理语句
    #ifdef UART1
    void UART1_ISR_Handler (void) interrupt UART1_VECTOR
    {OS_INT_ENTER();if(RI){RI = 0;if(COM1.B_RX_OK == 0){if(COM1.RX_Cnt >= COM_RX1_Lenth)	COM1.RX_Cnt = 0;RX1_Buffer[COM1.RX_Cnt++] = SBUF;COM1.RX_TimeOut = TimeOutSet1;}}if(TI){TI = 0;COM1.B_TX_busy = 0;}OSIntExit();
    }
    #endif
  4. 编译,若无错误则可以烧录到板子查看效果,测试效果如下:

         可以看到程序正常的运行了,task1 发送数据的时间间隔基本上在 1s 左右,task2、task3 的任务信息也正常的发送了,说明多任务运行没有问题。


六、总结

  • 本次成功实现了库函数与 Small RTOS51 的兼容,虽然修改了 Small RTOS51 的部分代码,但并未影响到 RTOS 的运行。
  • 这次测试只测试了每个任务是否可以正常运行,之后有机会尝试信号量和消息队列,学习线程间同步和线程间通讯。
  • 这次测试是在 small 模式下运行,由于 1.12 版本不支持 reentrant 任务,因此下次将测试一下线程调用 reentrant 函数会不会正常运行。

这篇关于初试 STC8A8K64D4 库函数 + Small RTOS51 1.12的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/227094

相关文章

INDEX+SMALL+IF+ROW函数组合使用解…

很多人在Excel中用函数公式做查询的时候,都必然会遇到的一个大问题,那就是一对多的查找/查询公式应该怎么写?大多数人都是从VLOOKUP、INDEX+MATCH中入门的,纵然你把全部的多条件查找方法都学会了而且运用娴熟,如VLOOKUP和&、SUMPRODUCT、LOOKUP(1,0/....,但仍然只能对这种一对多的查询望洋兴叹。   这里讲的INDEX+SMALL+IF+ROW的函数组合,

整理的经典面试题及各种库函数的自己实现

进程间通信方式 管道(有名管道,无名管道),共享内存,消息队列,信号量,socket通信 线程同步方式 临界区:通过对多线程的串行化来访问公共资源或一段代码,速度快,适合控制数据访问 互斥量:为协调共同对一个共享资源的单独访问而设计 信号量(PV操作):为控制一个具有有限数量用户资源而设计 事件:用来通知线程有一些事件已 进程和线程的区别 资源:进程是拥有资源的一个独立单位,线程是

【PyTorch常用库函数】torch.add():张量的加法操作

🎬 鸽芷咕:个人主页  🔥 个人专栏: 《C++干货基地》《粉丝福利》 ⛺️生活的理想,就是为了理想的生活! 文章目录 前言一 、torch.add()函数的基本用法二、示例演示示例1:两个相同形状的一维张量相加示例2:两个不同形状的一维张量相加(错误示例)示例3:使用alpha参数进行加权加法 结尾 前言 PyTorch作为一

PyTorch常用库函数:torch.acos()的详解实战使用

🎬 鸽芷咕:个人主页  🔥 个人专栏: 《C++干货基地》《粉丝福利》 ⛺️生活的理想,就是为了理想的生活! 文章目录 引言一、函数简介1.2 函数语法1.3 参数说明 二、 示例代码2.1 注意事项 总结 引言 PyTorch 是一个流行的深度学习框架,它提供了丰富的库函数,用于处理张量(多维数组)的各种操作。在科学计算和深度

ATextAppearance.AppCompat.Small not found

今天编译的代码的时候,刚才还是好的,后来吃个饭回来,就不行了。 报错如下: AGPBI: {"kind":"error","text":"error: resource style/ATextAppearance.AppCompat.Small (aka com.mci.smagazine:style/ATextAppearance.AppCompat.Small) not found.","

不使用库函数 字符串与整型 转换

摘要 本文首先 在实现中 字符串 格式化输入函数上 遇到的一个问题。其次 ,讲解 如何 处理 字符串转换为 整型常量的 实现。最终, 文章将给出 整型常量 变为 字符串的实现 源代码。 1. 编程中 格式化输入函数 遇到的一个小问题 下面这段代码 字符串输入 在句法上是没有问题的(编译、连接不会报错),但是显然会在程序运行时出错: [cpp] view plain copy

使用库函数API和C代码中嵌入汇编代码两种方式实现对sysinfo的系统调用

本例对116号系统调用sysinfo,通过c语言和嵌入式汇编语言来实现。 1.C语言实现过程如下: 打开VIM编辑器边集sysinfo.c文件,如下 #include<stdio.h>#include<sys/sysinfo.h>int main(){struct sysinfo info;if(sysinfo(&info)<0){perror("sysinfo failed!");

STM32:TIM定时中断配置的最全库函数讲解笔记

声明:本博客为哔哩哔哩up主@江协科技 “STM32入门教程”的听课笔记,仅供学习、参考使用,不得用作其他用途,违者必究。如有版权问题,请联系作者修改。 目录 一、综述 二、TIM库 初始化 2.1、TIM_DeInit 恢复缺省值 2.2、TIM_TimeBaseInit 时基单元初始化 2.3、 TIM_TimeBaseStructInit 时基单元结构体默认

初试构建工具Webpack

文章目录 一、Webpack概述二、安装Webpack三、Webpack打包实战1、创建index.js2、创建index.html3、运行webpack4、浏览index.html5、添加第二个脚本(1)创建index2.js(2)修改index.js(3)重新运行 webpack(4)浏览index.html 6、引入CSS样式进行编译(1)安装必要的 Loaders(2)更新 webp