完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
stm32f1系列的FreeRTOS移植
一、源码处理 文件下载 1、官网下载源码 2、找到相关的例程 3、进入源码文件 4、找到相关的文件 keil、RVDS为需要的文件,MemMang为需要的内存文件 文件移植 1、在之前led灯程序基础上添加文件 注释:在正点原子开源工程里可以下载 创建文件并包含以下文件 2、将相关.h文件包含进去 此时编译会报错 继续包含所需要的文件 文件地址: 3、修改相关文件 注释:正点原子给的工程例程是支持ucos的,所以我们需要把一些oc相关的删除掉 以下是修改之后程序代码: sys.h usart.c 原来是include.h,需要改成FreePTOS.h delay.c 1:SysTIck_Handler() extern void xPortSysTickHandler(void); //systick中断服务函数,使用ucos时用到 void SysTick_Handler(void) { if(xTaskGetSchedulerState()!=taskSCHEDULER_NOT_STARTED)//系统已经运行 { xPortSysTickHandler(); } } 2:delay_init oid delay_init() { u32 reload; SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK);//选择外部时钟 HCLK fac_us=SystemCoreClock/1000000; //不论是否使用OS,fac_us都需要使用 reload=SystemCoreClock/1000000; //每秒钟的计数次数 单位为M reload*=1000000/configTICK_RATE_HZ; //根据configTICK_RATE_HZ设定溢出时间 //reload为24位寄存器,最大值:16777216,在72M下,约合0.233s左右 fac_ms=1000/configTICK_RATE_HZ; //代表OS可以延时的最少单位 SysTick->CTRL|=SysTick_CTRL_TICKINT_Msk; //开启SYSTICK中断 SysTick->LOAD=reload; //每1/configTICK_RATE_HZ秒中断一次 SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk; //开启SYSTICK } 3:两个延时函数 //延时nus //nus:要延时的us数. //nus:0~204522252(最大值即2^32/fac_us@fac_us=168) void delay_us(u32 nus) { u32 ticks; u32 told,tnow,tcnt=0; u32 reload=SysTick->LOAD; //LOAD的值 ticks=nus*fac_us; //需要的节拍数 told=SysTick->VAL; //刚进入时的计数器值 while(1) { tnow=SysTick->VAL; if(tnow!=told) { if(tnow told=tnow; if(tcnt>=ticks)break; //时间超过/等于要延迟的时间,则退出. } }; } //延时nms //nms:要延时的ms数 //nms:0~65535 void delay_ms(u32 nms) { if(xTaskGetSchedulerState()!=taskSCHEDULER_NOT_STARTED)//系统已经运行 { if(nms>=fac_ms) //延时的时间大于OS的最少时间周期 { vTaskDelay(nms/fac_ms); //FreeRTOS延时 } nms%=fac_ms; //OS已经无法提供这么小的延时了,采用普通方式延时 } delay_us((u32)(nms*1000)); //普通方式延时 } //延时nms,不会引起任务调度 //nms:要延时的ms数 void delay_xms(u32 nms) { u32 i; for(i=0;i 4、屏蔽中断 5、最后编译一下,就创建成功啦!!! 创建任务并执行任务 创建任务分以下步骤: 设置任务优先级设置任务堆栈大小设置任务句柄设置任务函数 我创建了一个任务,使得两个灯同时闪烁,以及串口输出Halloword,以及在移植OLED屏幕的程序 OLED程序移植相对简单,只需要把相关文件夹进去就行 这是移植所需要的的一些相关文件: 其中NRF24L01.c是无线通信模块的,我还在肝中,有需要请私信我。 主函数: #include "sys.h" #include "delay.h" #include "usart.h" #include "led.h" #include "FreeRTOS.h" #include "task.h" #include "lcd.h" //任务优先级 #define START_TASK_PRIO 1 //任务堆栈大小 #define START_STK_SIZE 128 //任务句柄 TaskHandle_t StartTask_Handler; //任务函数 void start_task(void *pvParameters); //任务优先级 #define LED0_TASK_PRIO 2 //任务堆栈大小 #define LED0_STK_SIZE 50 //任务句柄 TaskHandle_t LED0Task_Handler; //任务函数 void led0_task(void *pvParameters); //任务优先级 #define USART0_TASK_PRIO 3 //任务堆栈大小 #define USART0_STK_SIZE 50 //任务句柄 TaskHandle_t USART0Task_Handler; //任务函数 void usart0_task(void *pvParameters); //任务优先级 #define TEMPER0_TASK_PRIO 4 //任务堆栈大小 #define TEMPER0_STK_SIZE 50 TaskHandle_t TEMPER0Task_Handler; //任务函数 void TEMPER0_task(void *pvParameters); //任务优先级 #define LCD_TO_TASK_PRIO 5 //任务堆栈大小 #define LCD_TO_STK_SIZE 50 //任务句柄 TaskHandle_t LCD_TOTask_Handler; //任务函数 void LCD_TO_task(void *pvParameters); //任务句柄 TaskHandle_t TEMPER0Task_Handler; //任务函数 void temper0_task(void *pvParameters); int main(void) { NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//设置系统中断优先级分组4 delay_init(); //延时函数初始化 uart_init(115200); //初始化串口 LED_Init(); //初始化LED LCD_Init(); POINT_COLOR=RED; //初始化LCD //创建开始任务 xTaskCreate((TaskFunction_t )start_task, //任务函数 (const char* )"start_task", //任务名称 (uint16_t )START_STK_SIZE, //任务堆栈大小 (void* )NULL, //传递给任务函数的参数 (UBaseType_t )START_TASK_PRIO, //任务优先级 (TaskHandle_t* )&StartTask_Handler); //任务句柄 vTaskStartScheduler(); //开启任务调度 } //开始任务任务函数 void start_task(void *pvParameters) { taskENTER_CRITICAL(); //进入临界区 //创建LED0任务 xTaskCreate((TaskFunction_t )led0_task, (const char* )"led0_task", (uint16_t )LED0_STK_SIZE, (void* )NULL, (UBaseType_t )LED0_TASK_PRIO, (TaskHandle_t* )&LED0Task_Handler); //创建usart0任务 xTaskCreate((TaskFunction_t )usart0_task, (const char* )"usart0_task", (uint16_t )USART0_STK_SIZE, (void* )NULL, (UBaseType_t )USART0_TASK_PRIO, (TaskHandle_t* )&USART0Task_Handler); //创建temper0任务 xTaskCreate((TaskFunction_t )temper0_task, (const char* )"temper_task", (uint16_t )TEMPER0_STK_SIZE, (void* )NULL, (UBaseType_t )TEMPER0_TASK_PRIO, (TaskHandle_t* )&TEMPER0Task_Handler); xTaskCreate((TaskFunction_t )LCD_TO_task, (const char* )"LCD_TO_task", (uint16_t )LCD_TO_STK_SIZE, (void* )NULL, (UBaseType_t )LCD_TO_TASK_PRIO, (TaskHandle_t* )&LCD_TOTask_Handler); vTaskDelete(StartTask_Handler); //删除开始任务 taskEXIT_CRITICAL(); //退出临界区 } //LED0任务函数 void led0_task(void *pvParameters) { while(1) { LED0=~LED0; if(LED0==1) printf("灯灭rn"); else printf("灯亮rn"); vTaskDelay(1000); } } //usart0任务函数 void usart0_task(void *pvParameters) { while(1) { printf("hello lee"); printf("rn"); vTaskDelay(1000); } } //temper0任务函数(暂时为LED1翻转) void temper0_task(void *pvParameters) { while (1) { LED1=~LED1; vTaskDelay(1000); } } void LCD_TO_task(void *pvParameters) { u8 lcd_id[12]; sprintf((char*)lcd_id,"LCD ID:%04X",lcddev.id); while (1) { LCD_ShowString(30,40,210,24,24,"WarShip STM32 ^_^"); LCD_ShowString(30,70,200,16,16,"TFTLCD TEST"); LCD_ShowString(30,90,200,16,16,"DARKSTARS"); LCD_ShowString(30,110,200,16,16,lcd_id); //显示LCD ID LCD_ShowString(30,130,200,12,12,"2020/12/4"); vTaskDelay(1000); } } 总结 通过这次系统的移植,我感受到系统的魅力,有了系统之后,许多程序就能并行运行了,这样我们就能完成更加高效,更加同步的信息处理和信息传输。对于高刷新率的信息处理,移植系统无疑是更好的选择。 |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
64 浏览 0 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
440 浏览 1 评论
286 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
254 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
618 浏览 2 评论
1382浏览 9评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
80浏览 3评论
43浏览 3评论
STM32CUBEMX4.22.1在main函数里面添加一行语句就死机的原因?
55浏览 3评论
49浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-5-2 23:44 , Processed in 0.779887 second(s), Total 71, Slave 59 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号