完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
扫一扫,分享给好友
一、前几天准备
:STM32F103ZET6 开发环境:MDK5.14 库函数:标准库V3.5 FreeRTOS:V9.0.0(网上下载,官网上现在是V10.0.1) 二、实验效果 结果6个任务,串口11串口2 ,4个RGB小灯以不同频率的光源0.5050 RGB LED驱动请参考RGB驱动,串口1,2-同时打印测试信息。 三,准备移植下载好的免费RTOS的源码中,非常适合加入源文件夹工程。1.FreeRTOS内核文件,如下图所示,里面所有的文件都加入到工程里面2.将便携中删除删除掉,只留下带走的三个文件夹。Keil文件夹不用,MemMang里面是内存管理源码,这里是内存管理源码,这里移植将heap4.c工程。RVDS中加入ARM_M3的C文件加入工程3.Keil工程4.修改stm32启动文件 四、代码uart.h #ifndef __UART_H__ #定义 __UART_H__ #include "stm32f10x.h"; #include #include #include #include "message.h"; /* UART IOpin 定义 */ #define TX1 GPIO_Pin_9 #define RX1 GPIO_Pin_10 #define TX2 GPIO_Pin_2 #define RX2 GPIO_Pin_3 #define TX3 GPIO_Pin_10 #define RX3 GPIO_Pin_11 #define RecDataexReLencData 128 ; 外部字符 *pIndex; 外部字符 *pWrite; 外部字符 *pRead; extern int USART_PRINTF_FLAG; extern void USARTConfiguration(int Baudrate); extern void USART_Send(USART_TypeDef* USARTx, char c); extern char USART_Received(USART_TypeDef* USARTx); #endif uart.c,多串口通用printf程序请参考多串口消耗printf教程 #include "uart.h" char RecData[RecDataLen] = {0}; char *pIndex = RecData; char *pWrite = RecData; char *pRead = RecData; int USART_PRINTF_FLAG = 0; void USARTConfiguration(int Baudrate) { USART_InitTypeDef MyUSART; GPIO_InitTypeDef GPIO; NVIC_InitTypeDef MyNVIC; RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2 | RCC_APB1Periph_USART3,启用); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO,启用); /* 配置 USART1 Tx (PA.09) 作为交替功能推挽 */ GPIO.GPIO_Pin = TX1; GPIO.GPIO_Mode = GPIO_Mode_AF_PP; GPIO.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO); /* 配置 USART1 Rx (PA.10) 作为输入浮动 */ GPIO.GPIO_Pin = RX1; GPIO.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, &GPIO); NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4); MyNVIC.NVIC_IRQChannel = USART1_IRQn; MyNVIC.NVIC_IRQChannelSubPriority = 0; MyNVIC.NVIC_IRQChannelPreemptionPriority = 0; MyNVIC.NVIC_IRQChannelCmd = 启用; NVIC_Init(&MyNVIC); MyUSART.USART_BaudRate = 波特率; MyUSART.USART_WordLength = USART_WordLength_8b; MyUSART.USART_StopBits = USART_StopBits_1; MyUSART.USART_Parity = USART_Parity_No; MyUSART.USART_HardwareFlowControl = USART_HardwareFlowControl_None; MyUSART.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; USART_Init(USART1, &MyUSART); USART_Cmd(USART1,启用); USART_ITConfig(USART1,USART_IT_RXNE,启用); USART_ITConfig(USART1,USART_IT_IDLE,启用); /* 配置 USART2 Tx (PA.02) 作为替代功能推挽 */ GPIO.GPIO_Pin = TX2; GPIO.GPIO_Mode = GPIO_Mode_AF_PP; GPIO.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO); /* 配置 USART2 Rx (PA.3) 作为输入浮动 */ GPIO.GPIO_Pin = RX2; GPIO.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, &GPIO); NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4); MyNVIC.NVIC_IRQChannel = USART2_IRQn; MyNVIC.NVIC_IRQChannelSubPriority = 0; MyNVIC.NVIC_IRQChannelPreemptionPriority = 1; MyNVIC.NVIC_IRQChannelCmd = 启用; NVIC_Init(&MyNVIC); MyUSART.USART_BaudRate = 波特率; MyUSART.USART_WordLength = USART_WordLength_8b; MyUSART.USART_StopBits = USART_StopBits_1; MyUSART.USART_Parity = USART_Parity_No; MyUSART.USART_HardwareFlowControl = USART_HardwareFlowControl_None; MyUSART.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; USART_Init(USART2, &MyUSART); USART_Cmd(USART2,启用); USART_ITConfig(USART2,USART_IT_RXNE,启用); USART_ITConfig(USART2,USART_IT_IDLE,启用); /* 配置 USART3 Tx (PB.10) 作为替代功能推挽 */ GPIO.GPIO_Pin = TX3; GPIO.GPIO_Mode = GPIO_Mode_AF_PP; GPIO.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO); /* 配置 USART3 Rx (PB.11) 作为输入浮动 */ GPIO.GPIO_Pin = RX3; GPIO.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOB, &GPIO); NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4); MyNVIC.NVIC_IRQChannel = USART3_IRQn; MyNVIC.NVIC_IRQChannelSubPriority = 0; MyNVIC.NVIC_IRQChannelPreemptionPriority = 2; MyNVIC.NVIC_IRQChannelCmd = 启用; NVIC_Init(&MyNVIC); MyUSART.USART_BaudRate = 波特率; MyUSART.USART_WordLength = USART_WordLength_8b; MyUSART.USART_StopBits = USART_StopBits_1; MyUSART.USART_Parity = USART_Parity_No; MyUSART.USART_HardwareFlowControl = USART_HardwareFlowControl_None; MyUSART.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; USART_Init(USART3, &MyUSART); USART_Cmd(USART3,启用); USART_ITConfig(USART3,USART_IT_RXNE,启用); USART_ITConfig(USART3,USART_IT_IDLE,启用); } void USART_Send(USART_TypeDef* USARTx, char c) { USART_SendData(USARTx, c); /* 循环直到传输结束 */ while (USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET); } char USART_Received(USART_TypeDef* USARTx) { char dat; //while (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET); dat = (char)(USART_ReceiveData(USARTx)&0xff); 返回数据; } void USART1_IRQHandler(void) { uint8_t clear = clear; USART_PRINTF_FLAG = 1; if(USART_GetFlagStatus(USART1,USART_IT_RXNE) != RESET ) { if ( (*(pWrite-1) != 0x0A) && ((pWrite - pIndex) < RecDataLen) ) { *pWrite = USART_Received(USART1); p写++; } else { USART_Received(USART1); } } else if (USART_GetITStatus(USART1, USART_IT_IDLE) != RESET) { if ( *(pWrite - 1) == 0x0A && *(pWrite - 2) == 0x0D) { cmdDealFlag = 1; } else { printf(“%s”, RecFlowMess); } pWrite = pIndex; 清除 = USART1->SR; 清除 = USART1->DR; } } void USART2_IRQHandler(void) { uint8_t clear = clear; USART_PRINTF_FLAG = 2; if(USART_GetFlagStatus(USART2,USART_IT_RXNE) != RESET ) { if ( (*(pWrite-1) != 0x0A) && ((pWrite - pIndex) < RecDataLen) ) { *pWrite = USART_Received(USART2); p写++; } else { USART_Received(USART2); } } else if (USART_GetITStatus(USART2, USART_IT_IDLE) != RESET) { if ( *(pWrite - 1) == 0x0A && *(pWrite - 2) == 0x0D) { cmdDealFlag = 1; } else { printf("%s", RecFlowMess); } pWrite = pIndex; 清除 = USART2->SR; 清除 = USART2-> DR; } } void USART3_IRQHandler(void) { uint8_t clear = clear; USART_PRINTF_FLAG = 3; if(USART_GetFlagStatus(USART3,USART_IT_RXNE) != RESET ) { if ( (*(pWrite-1) != 0x0A) && ((pWrite - pIndex) < RecDataLen) ) { *pWrite = USART_Received(USART3); p写++; } else { USART_Received(USART3); } } else if (USART_GetITStatus(USART3, USART_IT_IDLE) != RESET) { if ( *(pWrite - 1) == 0x0A && *(pWrite - 2) == 0x0D) { cmdDealFlag = 1; } else { printf("%s", RecFlowMess); } pWrite = pIndex; 清除 = USART3->SR; 清除 = USART3->DR; } } int fputc(int ch, FILE *f) { #ifdef DBG_ITM /* ?Printf????ITM??????? */ if (DEMCR & TRCENA) { while (ITM_Port32(0) == 0); ITM_Port8(0) = ch; } #else /* ?printf?????? */ switch (USART_PRINTF_FLAG) { case 1: USART_SendData(USART1, (unsigned char) ch); 而 (!(USART1->SR & USART_FLAG_TXE)); 休息; 情况 2: USART_SendData(USART2, (unsigned char) ch); 而 (!(USART2->SR & USART_FLAG_TXE)); 休息; 情况 3: USART_SendData(USART3, (unsigned char) ch); 而 (!(USART3->SR & USART_FLAG_TXE)); 休息; 默认值: USART_SendData(USART1, (unsigned char) ch); 而 (!(USART1->SR & USART_FLAG_TXE)); 休息; } #endif 返回 (ch); } |
|
|
|
rtos_app.h
#ifndef __RTOS_APP_H__ #define __RTOS_APP_H__ #include "stm32f10x.h" #include "uart.h" #include "gpio.h" #include "FreeRTOS.h" #include "task.h" #define START_TASK_PRIO 1 #define START_STK_SIZE 128 extern TaskHandle_t StartTask_Handler; extern void Start_task(void *pvParameters); #define LED0_TASK_PRIO 2 #define LED0_STK_SIZE 50 extern void LED0_task(void *pvParameters); #define LED1_TASK_PRIO 3 #define LED1_STK_SIZE 50 extern void LED1_task(void *pvParameters); #define LED2_TASK_PRIO 6 #define LED2_STK_SIZE 50 extern void LED2_task(void *pvParameters); #define LED3_TASK_PRIO 5 #define LED3_STK_SIZE 50 extern void LED3_task(void *pvParameters); #define UART1_TASK_PRIO 4 #define UART1_STK_SIZE 50 #define UART2_TASK_PRIO 7 #define UART2_STK_SIZE 50 #endif rtos_app.c,因为多串口共用 printf()打印信息,需要访问标志量USART_PRINTF_FLAG ,这个变量是临界资源,必须加上处理措施,才能进行正常的运行。这里是在俩段程中各加入了进入临界资源taskENTER_CRITICAL(); 和退出临界资源taskEXIT_CRITICAL();函数进行保护。有关临界资源互斥、同步访问的问题,请自行百度。 #include "rtos_app.h" TaskHandle_t StartTask_Handler; TaskHandle_t LED0Task_Handler; TaskHandle_t LED1Task_Handler; TaskHandle_t LED2Task_Handler; TaskHandle_t LED3Task_Handler; TaskHandle_t UART1Task_Handler; TaskHandle_t UART2Task_Handler; void LED0_task(void *pvParameters) { while(1) { RGB_LED1 = ON; vTaskDelay(200 / portTICK_RATE_MS); RGB_LED1 = OFF; vTaskDelay(800 / portTICK_RATE_MS); } } void LED1_task(void *pvParameters) { while(1) { RGB_LED2 = ON; vTaskDelay(400 / portTICK_RATE_MS); RGB_LED2 = OFF; vTaskDelay(600 / portTICK_RATE_MS); } } void LED2_task(void *pvParameters) { while(1) { RGB_LED3 = ON; vTaskDelay(600 / portTICK_RATE_MS); RGB_LED3 = OFF; vTaskDelay(400 / portTICK_RATE_MS); } } void LED3_task(void *pvParameters) { while(1) { RGB_LED4= ON; vTaskDelay(800 / portTICK_RATE_MS); RGB_LED4 = OFF; vTaskDelay(200 / portTICK_RATE_MS); } } void UART1_task(void *pvParameters) { int i = 0; while(1) { taskENTER_CRITICAL(); USART_PRINTF_FLAG = 1; printf("UART1-%06d: FreeRTOS Test!rn",i); vTaskDelay(1000 / portTICK_RATE_MS); i ++; taskEXIT_CRITICAL(); } } void UART2_task(void *pvParameters) { int i = 0; while(1) { taskENTER_CRITICAL(); USART_PRINTF_FLAG = 2; printf("UART2-%06d: FreeRTOS Test!rn",i); vTaskDelay(1000 / portTICK_RATE_MS); i ++; taskEXIT_CRITICAL(); } } void Start_task(void *pvParameters) { taskENTER_CRITICAL(); 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 ); xTaskCreate( (TaskFunction_t) LED1_task, (const char *) "LED1_task", (uint16_t) LED1_STK_SIZE, (void *) NULL, (UBaseType_t) LED1_TASK_PRIO, (TaskHandle_t *) &LED1Task_Handler ); xTaskCreate( (TaskFunction_t) UART1_task, (const char *) "UART1_task", (uint16_t) UART1_STK_SIZE, (void *) NULL, (UBaseType_t) UART1_TASK_PRIO, (TaskHandle_t *) &UART1Task_Handler ); xTaskCreate( (TaskFunction_t) LED2_task, (const char *) "LED2_task", (uint16_t) LED2_STK_SIZE, (void *) NULL, (UBaseType_t) LED2_TASK_PRIO, (TaskHandle_t *) &LED2Task_Handler ); xTaskCreate( (TaskFunction_t) LED3_task, (const char *) "LED3_task", (uint16_t) LED3_STK_SIZE, (void *) NULL, (UBaseType_t) LED3_TASK_PRIO, (TaskHandle_t *) &LED3Task_Handler ); xTaskCreate( (TaskFunction_t) UART2_task, (const char *) "UART2_task", (uint16_t) UART2_STK_SIZE, (void *) NULL, (UBaseType_t) UART2_TASK_PRIO, (TaskHandle_t *) &UART2Task_Handler ); vTaskDelete(StartTask_Handler); taskEXIT_CRITICAL(); } main.c /*************************************************** ** STM32F103ZET6 工程模板 ** MDK5,JLink-V8, StdPeriph_Lib V3.5 ** 基本配置 ** 1.时钟树配置,72MHz ** 2.精准1ms,10us延时函数 ** 3.GPIO口重定向,实现类51的IO操作方式 ** 4.USART1配置,波特率115200 ** 5.USART1, TXD: PA9 RXD: PA10 ** 作者:ALEX HUA ** 时间:2018/2/9 **************************************************** ** 测试程序说明 ** 1)*IDN? 2)*Help? 3) *Version? 4)*LED ON/OFF? ** 串口模版自带前三个命令,第四个命令为测试命令 ** 以上命令发送均要带 ** 以上命令发送均不区分大小写 ****************************************************/ #include "conf.h" int main (void) { Configuration(); LED_R = OFF; LED_G = ON; LED_B = OFF; //GPIOD->ODR = 0x0000; // while (1) // { // if (cmdDealFlag == 1) // { // DealWithUARTMess(RecData); // cmdDealFlag = 0; // } // } 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(); } |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1627 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1550 浏览 1 评论
984 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
688 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1601 浏览 2 评论
1867浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
650浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
518浏览 3评论
536浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
506浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-24 19:29 , Processed in 0.865922 second(s), Total 79, Slave 62 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号