freeRTOS移植和protues防真stm32
STM32 移植 freeRTOS
2023-09-14 09:16:38 时间
-
准备freeRTOS源码和一个简单的工程
freeRTOS源码下载链接:
链接:https://pan.baidu.com/s/1hgyQqoDqDuETEHr_I80M8Q
提取码:e890
另外还需要准备一个简单的工程,这里使用led闪烁的例子来完成移植
已移植好的stm32f103ve例程下载链接:
https://download.csdn.net/download/mygod2008ok/12234264
-
开始移植
-
在led闪烁工程中新建一个文件夹,并命名为freeRTOS
2.将准备好的freeRTOS库中的源码全部复制
3. 粘贴到led闪烁工程中的freeRTOS文件夹中,并将portable中的文件仅保留以下4个
4.在工程中创建两个文件组freeRTOS_sourcet和freeRTOS_portable,并加入以下文件到工程,注意port.c选择M3里面的,因为stm32f1是m3系列
5. 另外要添加freeRTOS相关的文件路径到工程中
6.先编译一下,出现如下错误
7.少了FreeRTOSConfig.h文件,可以去下载一个,也可以到freeRTOS提供的Demo中复制一份过来,这里从DEMO中寻找
8.找到FreeRTOSConfig.h文件复制
9.粘贴到工程中的FreeRTOS中的include文件夹内
10.再次编译一下工程,会出现以下错误
11.按住CTRL+F键,输入xTaskGetCurrentTaskHandle后进行全局搜索
12.搜索结果如下
13.在FreeRTOSConfig.h中加入如下宏后再次编译一下
#define INCLUDE_xTaskGetCurrentTaskHandle 1
14.对port.c中的三个函数进行适配,也就是让启动文件分别能够指向这三个函数
15.再次编译一下,会出现以下错误
16.将stm32f10x_it.c中的SVC_Handler,PendSV_Handler,SysTick_Handler三个函数屏蔽掉,重新编译一下工程
17.在main文件中加入头文件task.h,然后编译一下,出现如下错误
18.双击跳转到出错处,并加入FreeRTOS.h头文件再次编译一下,编译通过
19.在main中创建以下2个任务,main.c如下
/**
* @file main.c
* @author 仙剑情缘
* @version V1.0
* @data 20-Oct-2019
* @brief 串口USART2实验
*
* 介绍配置USART2串口收发功能
*
*
*
*/
#include "stm32f10x_usart.h"
#include "stm32f10x.h"
#include <stdio.h>
#include "task.h"
/* 加入以下代码,支持printf函数,而不需要选择use MicroLIB */
#ifdef DEBUG
#pragma import(__use_no_semihosting)
//标准库需要的支持函数
struct __FILE
{
int handle;
};
FILE __stdout;
//定义_sys_exit()以避免使用半主机模式
void _sys_exit(int x)
{
x = x;
}
//重定义fputc函数
int fputc(int ch, FILE *f)
{
while((USART2->SR&0X40)==0);
USART2->DR = (u8) ch;
return ch;
}
#endif
uint8_t rxBuf[40];
uint8_t rxLen;
/**
* @brief USART2串口初时化
*
*
* @param uint32_t baudrate[in]:设置波特率
* @retval None
*/
void Usart2_Init(uint32_t baudrate)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
/* 初时化串口前,先将相应的时钟打开 */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);
/* 初时化USART2 TX PA2引脚设为复用推挽输出 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStructure);
/* 初时化USART2 RX PA3引脚为浮空输入 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA,&GPIO_InitStructure);
RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART2,ENABLE);/*!< 复位串口2 */
RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART2,DISABLE);/*!< 停止复位 */
/* USART2 NVIC初时化 */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); /*!< 设置NVIC中断分组2:2位抢占优先级,2位响应优先级 0-3; */
NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn; /*!< USART2中断通道USART1_IRQn */
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3; /*!< 抢占优先级3 */
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; /*!< 子优先级3 */
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; /*!< IRQ使能通道 */
NVIC_Init(&NVIC_InitStructure); /*!< 初时化NVIC寄存器 */
/* USART2初时化设置 */
USART_InitStructure.USART_BaudRate = baudrate; /*!< 设置波特率 */
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_WordLength = USART_WordLength_8b; /*!< 8位数据*/
USART_InitStructure.USART_StopBits = USART_StopBits_1; /*!< 1位停止位 */
USART_InitStructure.USART_Parity = USART_Parity_No; /*!< 无校验位 */
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; /*!< 收发模式*/
USART_Init(USART2,&USART_InitStructure); /*!< 初时化串口2 */
/* 开启串口2接收中断 */
USART_ITConfig(USART2,USART_IT_RXNE,ENABLE);
/* 使能串口2 */
USART_Cmd(USART2,ENABLE);
}
/**
* @brief USART2串口发送函数
*
*
* @param uint8_t *buf[in]:待发送的数据buffer
* @param uint16_t len:发送的数据长度
* @retval None
*/
void USART2_Send_Data(uint8_t *buf,uint16_t len)
{
for(uint16_t i = 0; i<len; i++)
{
while(USART_GetFlagStatus(USART2,USART_FLAG_TXE)==RESET); /*!< 是否可以写数据到发送寄存器*/
USART_SendData(USART2,buf[i]);
while(USART_GetFlagStatus(USART2,USART_FLAG_TC)==RESET); /*!<发送是否完成*/
}
}
/**
* @brief USART2串口中断函数
*
*
* @param None
* @retval None
*/
void USART2_IRQHandler(void)
{
/* 暂存接收结果 */
uint8_t result;
/* @note
* - PE (Parity error), FE (Framing error), NE (Noise error), ORE (OverRun
* error) and IDLE (Idle line detected) pending bits are cleared by
* software sequence: a read operation to USART_SR register
* (USART_GetITStatus()) followed by a read operation to USART_DR register
* (USART_ReceiveData()).
* - RXNE pending bit can be also cleared by a read to the USART_DR register
* (USART_ReceiveData()).
*/
/* 检查是否为USART2接收中断 */
if(USART_GetITStatus(USART2,USART_IT_RXNE) != RESET)
{
result = USART_ReceiveData(USART2);
if(rxLen < 20)
{
rxBuf[rxLen] = result;
rxLen++;
}
}
/* 溢出发生时,先读SR,再读DR,解决中断不进入问题*/
else if(USART_GetFlagStatus(USART2,USART_IT_ORE) == SET)
{
USART_ClearFlag(USART2,USART_IT_ORE);
USART_ReceiveData(USART2);
}
}
// 任务句柄
TaskHandle_t task2_handler;
/**
* 任务2
*/
void led2_task(void* t)
{
while(1)
{
if(GPIO_ReadOutputDataBit(GPIOB,GPIO_Pin_9))
GPIO_ResetBits(GPIOB, GPIO_Pin_9 );
else
GPIO_SetBits(GPIOB, GPIO_Pin_9 );
printf("task2\n");
vTaskDelay(20);
}
}
/**
* 任务1
*/
void led1_task(void* t)
{
uint8_t i = 5;
while(1)
{
if(GPIO_ReadOutputDataBit(GPIOB,GPIO_Pin_8))
GPIO_ResetBits(GPIOB, GPIO_Pin_8 );
else
GPIO_SetBits(GPIOB, GPIO_Pin_8 );
printf("task1\n");
vTaskDelay(10);
if(i > 0)
{
if(--i == 0)
{
vTaskDelete(task2_handler);
}
}
}
}
/**
* @brief 主函数,程序的入口
*
*
* @param None
* @retval int:不用理会,对于嵌入式系统,永远都不会返回
*/
int main(void)
{
Usart2_Init(9600);
printf("%s","hello world");
// assert_param(0);
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
xTaskCreate(led2_task, "LED2", configMINIMAL_STACK_SIZE, NULL, 3, &task2_handler );
xTaskCreate(led1_task, "LED1", configMINIMAL_STACK_SIZE, NULL, 2, NULL );
vTaskStartScheduler();
for(;;)
{
if(rxLen >= 20)
{
USART2_Send_Data(rxBuf,20);
rxLen = 0;
}
}
}
#if USE_FULL_ASSERT
void assert_failed(uint8_t* file, uint32_t line)
{
printf("\r\nfile path is %s,error line is %d\r\n",file,line);
while(1);
}
#endif
编译运行
-
protues仿真代码下载,注意protues仿真STM32串口会乱码https://download.csdn.net/download/mygod2008ok/12234385
如果这份文章对你们有帮助,请双击666
相关文章
- jlink接口定义接stm32_图解STM32 JLink 采用JTAG 模式和 SWD模式下载时引脚说明「建议收藏」
- STM32标准库移植RT-Thread Nano添加FinSH与控制台[通俗易懂]
- STM32看门狗–窗口看门狗
- 【STM32】系统时钟RCC详解(超详细,超全面)
- 基于STM32+铂电阻设计的测温仪
- stm32编程步骤_单片机STM32
- stm32相关知识_STM32单片机介绍
- stm32开发教程_单片机STM32
- stm32收发 wiegand 韦根协议开发详解
- (三)STM32基础——GPIO介绍
- (27)STM32——光敏传感器实验笔记
- (48)STM32——图片显示实验
- STM32中RTC简介以及使用方法
- 干货 | 详解 stm32 在线 IAP 升级
- STM32移植Linux系统:探索物联网的新突破(linux移植stm32)
- 如何在MacOS上使用STM32开发板进行微控制器编程(macosstm32)
- 基于Linux平台的STM32开发技巧(linux开发stm32)
- 让STM32板载Linux系统驱动舞台灯光(stm32跑linux)
- 探索Linux下STM32的开发之路(linuxstm32)