STC32G单片机开发指南(5):基于FreeRTOS的操作系统移植及设置和延时函数修改说明

前言

说到一款单片机,要发挥更高的性能使用操作系统是必然,最近我也是对其操作系统的移植进行了了解,这边官方给了FreeRTOS的例程,但是使用和CAN总线通信协议绑定,难免有些复杂,我也在移植过程也遇到了一些问题和报错,本文来对其进行讲解并且帮助读者更好入门STC32单片机的操作系统和修改一些之前使用的延时函数,使其适用FreeRTOS。

移植过程

这边我们可以直接搜索STC的官网,这边我们打开官方给的例程,查看路径找到FreeRTOS和的文件User之中的FreeRTOSConfig(用户自定义使用)头文件

然后我们在自己的工程文件创建一个FreeRTOS的文件夹来放置FreeRTOS的源文件(.c)和头文件(.h)和User的FreeRTOSConfig.h(我们用户自己定义使用),接着我们将这些要移植的头文件和源文件(包括include 和 portable之中的)全部添加到我们自己创建的文件夹之中。

随后我们就将FreeRTOS文件全部都移植到我们的文件之中了,我们就可以点开工程了

接着我们创建一个组命名为FreeRTOS,然后将源文件(.c)全部添加到里面,然后再将FreeRTOSConfig.h添加到User(存放main.c)的分组之中,然后在点魔术棒再选C251添加头文件路径就可以了,但是我们做完这些再编译工程会出现报错,这时我们还要修改一些东西

(1)右键(port.c)接口文件选择Option修改打上这两个勾(粗体黑)

(2)再次点开魔术棒修改Target和C251的配置为这样

这样我们再编译就不会报错了,但是还有一些警告,这边我们可以忽视不用管他哈

这样我们的移植就完成了

验证操作系统代码

#include <STC32G.H>
#include "Delay.h"
#include "GPIO.h"
#include "FreeRTOS.h"
#include "task.h"

//设置优先级,栈内存,任务句柄,任务函数
#define START_TASK_PRIO 1
#define START_TASK_STK 128
TaskHandle_t Start_Handler;
void Start_Task(void*pvParameters);

#define LED1_TASK_PRIO 2
#define LED1_TASK_STK 128
TaskHandle_t LED1_Handler;
void LED1_Task(void*pvParameters);

#define LED2_TASK_PRIO 3
#define LED2_TASK_STK 128
TaskHandle_t LED2_Handler;
void LED2_Task(void*pvParameters);

#define LED3_TASK_PRIO 4
#define LED3_TASK_STK 128
TaskHandle_t LED3_Handler;
void LED3_Task(void*pvParameters);


void main(void)
{	
    //设置为推挽输出
	GPIO_Init(4,0,GPIO_Mode_Out_PP,GPIO_NoPull);
	GPIO_Init(4,1,GPIO_Mode_Out_PP,GPIO_NoPull);
	GPIO_Init(4,2,GPIO_Mode_Out_PP,GPIO_NoPull);
    //创建开始任务	xTaskCreate(Start_Task,"Start_Task",START_TASK_STK,NULL,START_TASK_PRIO,&Start_Handler);
	vTaskStartScheduler();//进入任务调度
	while(1);
}

void Start_Task(void*pvParameters)
{
	taskENTER_CRITICAL();//进入临界保护区
    //创建任务
	xTaskCreate(LED1_Task,"LED1_Task",LED1_TASK_STK,NULL,LED1_TASK_PRIO,&LED1_Handler);
	xTaskCreate(LED2_Task,"LED2_Task",LED2_TASK_STK,NULL,LED2_TASK_PRIO,&LED2_Handler);
	xTaskCreate(LED3_Task,"LED3_Task",LED3_TASK_STK,NULL,LED3_TASK_PRIO,&LED3_Handler);
	vTaskDelete(Start_Handler);//删除开始任务 
	taskEXIT_CRITICAL();//退出临界保护区
}
void LED1_Task(void*pvParameters)
{
	while(1)
	{
		P41=~P41;
		vTaskDelay(300);
	}
}
void LED2_Task(void*pvParameters)
{
	while(1)
	{
		P40=~P40;
		vTaskDelay(400);
	}
}
void LED3_Task(void*pvParameters)
{
	while(1)
	{
		P42=~P42;
		vTaskDelay(500);
	}
}


实验现象

我们可以看到三个灯在以不同频率在闪烁

延时函数修改

之前我们用到的Timer0用于延时函数,这边我们使用到了操作系统就最好不要去使用Timer0了哈,但是如果在资源紧张的情况下,我们要实现一些us的延时比如I2C总线的通信协议,我们又要如何去实现使用定时器延时呢,这边我们可以对之前的延时函数进行一定的修改来使用

思路:因为操作系统的任务调度和时间计数是用定时器中断去实现的,所以我们在要使用延时时,关闭中断即可,延时完了再次打开就行哈,但是进行us延时一定要记得出来修改重装值为1ms的状态,我们FreeRTOS系统默认为1ms的重装值,要是不改回来,也是有大问题的哈

定时器修改代码

void Delay_us(uint16_t xus)//24MHz
{
	TR0=0;//关闭定时器设置重装值
	ET0=0;
	TH0=0xFF;//设置1us的重装值
    TL0=0xE8;
	TR0=1;
	while(xus--)
	{
		TF0=0;
		while(!TF0);
	}
	TR0=0;//关闭定时器,停止计数并且可以设置重载值
	TH0=0xA2;
	TL0=0x40;
	ET0=1;//再次使能定时器中断
	TR0=1;//开启定时器
}

void Delay_ms(uint16_t xms)//24MHz
{
	TR0=0;//开启定时器,才可以设置重载值
	ET0=0;//关闭定时器中断
	TH0=0xA2;
	TL0=0x40;
	TR0=1;//开启定时器
	while(xms--)
	{
		TF0=0;//清除定时器标志位
		while(!TF0);//
	}
	TR0=0;//关闭定时器,停止计数并且可以设置重载值
	//此时可以设置重载值但是本来就是1ms的重装值所以不必设置
	ET0=1;//再次使能定时器中断
	TR0=1;//开启定时器
	
}

最后

有什么错误的地方请大家指出,一起交流学习哈^–^

物联沃分享整理
物联沃-IOTWORD物联网 » STC32G单片机开发指南(5):基于FreeRTOS的操作系统移植及设置和延时函数修改说明

发表评论