STC89C54应用RTX-Tiny编写一个简单程序

# RTX-Tiny的介绍

        RTX-Tiny是基于嵌入式操作系统RTX5的微型实时内核,因此其占用的RAM大小也比较小。

        根据Keil官方网站的介绍,RTX-Tiny占用的RAM大小仅为600字节左右。这个大小是指RTX-Tiny内核本身占用的RAM大小,不包括用户应用程序等占用的RAM。

        然而,实际上RTX-Tiny占用的RAM大小可能因具体的应用场景而不同。例如,在使用RTX-Tiny的应用程序中,如果涉及到动态内存分配、任务堆栈、消息队列等操作,这些都会占用额外的RAM。因此,在具体应用中,需要根据实际需求评估和优化RAM的使用,以达到最佳的性能和资源利用效果。

# 单片机资源对比

        

# 创建2个单独线程,分别输出hello1和hello2,第二个优先级高

由于STC89C54RD+芯片运行频率比较低,RTX-Tiny操作系统比较适合,因为其非常小巧,可以节省系统资源。

        首先,需要在Keil MDK中新建一个工程,并按照以下步骤进行配置:

        1. 在“Options for Target” 菜单栏中选择“C51”选项卡,勾选“Enable Extended C51 Instruction Set” 和“Enable C51 extensions in the Assembler”。

        2. 在“Options for Target” 菜单栏中选择“RTX Configuration”选项卡,勾选“Use RTX Tiny”选项,并设置任务堆栈大小和节拍周期。

        下面是一个简单的STC89C54RD+的RTX-Tiny程序,其中包含两个线程,分别输出 "Hello1" 和 "Hello2",其中线程2的优先级较高:

#include <rtx_tiny.h>
#include <REG52.H>

/* 定义任务堆栈 */
uint8_t stack1[32];
uint8_t stack2[32];

/* 定义任务ID */
osThreadId tid1;
osThreadId tid2;

/* 任务1函数 */
void Thread1 (void const *argument) {
    while (1) {
        printf("Hello1\n");
        osDelay(100);
    }
}

/* 任务2函数 */
void Thread2 (void const *argument) {
    while (1) {
        printf("Hello2\n");
        osDelay(100);
    }
}

int main(void) {
    /* 初始化 RTX-Tiny */
    osKernelInitialize();

    /* 创建任务,优先级为 1 */
    tid1 = osThreadCreate(osThread(Thread1), NULL, &stack1[31]);
    /* 创建任务,优先级为 2 */
    tid2 = osThreadCreate(osThread(Thread2), NULL, &stack2[31]);

    /* 设置任务2的优先级为高于任务1的优先级 */
    osThreadSetPriority(tid1, osPriorityBelowNormal);
    osThreadSetPriority(tid2, osPriorityNormal);

    /* 启动 RTX-Tiny */
    osKernelStart();

    /* 程序永远都不会运行到这里 */
    while (1);
    return 0;
}

需要注意的几点:

  • `main` 函数中要调用 `osKernelInitialize` 函数来初始化 RTX-Tiny,然后调用 `osKernelStart` 函数来启动 RTX-Tiny。
  • `osThreadCreate` 函数中需要传入任务函数和任务堆栈指针。
  • `osThreadSetPriority` 函数能够动态地改变任务的优先级。

#osThreadCreate和osThreadSetPriority的参数

1,`osThreadCreate` 函数有三个参数:

  •   `thread`:指向任务函数的指针。
  •   `argument`:指向任务函数参数的指针。如果不需要参数,可设为 `NULL`。
  •   `stack_mem`:指向任务堆栈的指针,堆栈的大小在初始化时需要设置。

2,`osThreadSetPriority` 函数有两个参数:

  •  `thread_id`:任务ID。
  •  `priority`:任务的优先级,可设置为以下值:

            `osPriorityIdle`: 空闲任务的优先级。
            `osPriorityLow`: 低优先级。
            `osPriorityBelowNormal`: 比正常优先级低一级。
            `osPriorityNormal`: 正常优先级。
            `osPriorityAboveNormal`: 比正常优先级高一级。
           `osPriorityHigh`: 高优先级。
           `osPriorityRealtime`: 实时优先级。

        在上述示例程序中,使用 `osPriorityBelowNormal` 表示任务1的优先级比任务2低,使用 `osPriorityNormal` 表示任务2的优先级为正常优先级。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是STC89C52与ESP8266 ESP-01模块通过MQTT协议进行订阅消息的C语言代码: ```c #include "reg52.h" #include "stdio.h" #include "string.h" #include "stdlib.h" #define uchar unsigned char #define uint unsigned int sbit LED=P0^0; //LED灯连接P0.0口 //串口波特率设置 #define BAUD 9600 #define FOSC 11059200L #define T1MS (65536-FOSC/12/1000) //1ms定时器计数值 //MQTT服务器地址和端口 #define SERVER_IP "192.168.1.100" #define SERVER_PORT 1883 //订阅的主题 #define TOPIC "/test/topic" //ESP8266模块发送AT指令的函数 void esp8266_cmd(char* cmd) { char buf[100]; memset(buf, 0, sizeof(buf)); sprintf(buf, "%s\r\n", cmd); printf("%s", buf); while(1) { if(strstr(buf, "OK") || strstr(buf, "ERROR")) return; if(SBUF != 0) buf[strlen(buf)] = SBUF; } } //连接MQTT服务器 void mqtt_connect() { char cmd[100]; //发送MQTT连接请求 sprintf(cmd, "AT+CIPSTART=\"TCP\",\"%s\",%d\r\n", SERVER_IP, SERVER_PORT); esp8266_cmd(cmd); sprintf(cmd, "AT+CIPSEND=%d\r\n", 34 + strlen(TOPIC)); esp8266_cmd(cmd); printf("0104000000064d5154540402001e0004"); printf("%02x", strlen(TOPIC) >> 8); printf("%02x", strlen(TOPIC) & 0xff); printf("%s", TOPIC); while(1) { if(strstr(cmd, "SEND OK")) break; } } //订阅主题 void mqtt_subscribe() { char cmd[100]; sprintf(cmd, "AT+CIPSEND=%d\r\n", 35 + strlen(TOPIC)); esp8266_cmd(cmd); printf("8205"); printf("%02x", strlen(TOPIC) >> 8); printf("%02x", strlen(TOPIC) & 0xff); printf("%s", TOPIC); printf("00"); while(1) { if(strstr(cmd, "SEND OK")) break; } } //处理接收到的MQTT消息 void mqtt_process(char* msg) { if(strstr(msg, "ON")) LED = 0; else if(strstr(msg, "OFF")) LED = 1; } //接收串口数据中断处理函数 void serial_isr() interrupt 4 { if(RI == 1) { RI = 0; SBUF = P0; if(SBUF == '+') { char buf[100]; memset(buf, 0, sizeof(buf)); uint i = 0; while(1) { if(SBUF != 0) { buf[i++] = SBUF; if(i >= sizeof(buf)) break; if(strstr(buf, "OK") || strstr(buf, "ERROR")) break; } } if(strstr(buf, TOPIC)) { char msg[100]; memset(msg, 0, sizeof(msg)); uint j = 0; while(SBUF != 0) { msg[j++] = SBUF; if(j >= sizeof(msg)) break; } mqtt_process(msg); } } } } //定时器1中断处理函数 void timer1_isr() interrupt 3 { static uint cnt = 0; TH1 = T1MS >> 8; TL1 = T1MS & 0xff; if(++cnt >= 1000) { cnt = 0; LED = !LED; } } //主函数 void main() { //串口初始化 TMOD = 0x20; TH1 = T1MS >> 8; TL1 = T1MS & 0xff; TR1 = 1; SM0 = 0; SM1 = 1; REN = 1; ES = 1; EA = 1; //连接WiFi热点 esp8266_cmd("AT+CWMODE=1"); esp8266_cmd("AT+CWJAP=\"ssid\",\"password\""); //连接MQTT服务器并订阅主题 mqtt_connect(); mqtt_subscribe(); //循环等待接收MQTT消息 while(1); } ``` 需要注意的是,上述代码需要在STC89C52的环境下编译运行,且需要将ESP8266 ESP-01模块与STC89C52通过串口连接,同时需要将LED灯连接到P0.0口。另外,代码中的MQTT服务器地址、端口和订阅的主题需要根据实际情况进行修改。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值