3.实现串口功能及消息邮箱

来源:互联网 发布:java工程师是做什么的 编辑:程序博客网 时间:2024/06/05 11:09

提醒:

如果您是完全按照《1.一步一步移植ucos到stm32f103开发版(修订版)》来新建的工程的话,那很遗憾,你要重新建立一个工程,因为,在那篇文章的步骤1中,我们选中了GPIO,但是没有选中USART,所以要新建一个工程,只是也要把USART选中


BSP.c文件中增加对串口的初始化及中断的初始化:


void NVIC_Configuration(void){  //EXTI_InitTypeDef EXTI_InitStructure;  NVIC_InitTypeDef NVIC_InitStructure;    /* Configure the NVIC Preemption Priority Bits */    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);  NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;  NVIC_Init(&NVIC_InitStructure);}void USART_Config(USART_TypeDef* USARTx,u32 baud){  USART_InitTypeDef USART_InitStructure;  GPIO_InitTypeDef GPIO_InitStructure;  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);   RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);  RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);    //usart_init----------------------------------------------------  /* Configure USART1 Rx (PA.10) as input floating */  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;  GPIO_Init(GPIOA, &GPIO_InitStructure);     /* Configure USART1 Tx (PA.09) as alternate function push-pull */  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  GPIO_Init(GPIOA, &GPIO_InitStructure);      USART_InitStructure.USART_BaudRate =baud;  USART_InitStructure.USART_WordLength = USART_WordLength_8b;  USART_InitStructure.USART_StopBits = USART_StopBits_1;  USART_InitStructure.USART_Parity = USART_Parity_No;  USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;  USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;  /* Configure USART1 */  USART_Init(USARTx, &USART_InitStructure);     /* Enable USART1 Receive and Transmit interrupts */  USART_ITConfig(USARTx, USART_IT_RXNE, ENABLE);  //USART_ITConfig(USARTx, USART_IT_TXE, ENABLE);    /* Enable the USART1 */  USART_Cmd(USARTx, ENABLE);  //USART_ClearFlag(USARTx, USART_FLAG_TXE);}void BSP_Init(void){  /* System Clocks Configuration --72M*/  RCC_Configuration();     GPIO_Configuration();  NVIC_Configuration();  USART_Config(USART1,115200);}

APP目录下新建USART.c文件,添加如下代码:

#include <usart.h>void USART_OUT(USART_TypeDef* USARTx, uint8_t *Data,...){ const char *s;int d;char buf[16];va_list ap;va_start(ap, Data);while(*Data!=0){if(*Data==0x5c){switch (*++Data){case 'r':USART_SendData(USARTx, 0x0d);Data++;break;case 'n':USART_SendData(USARTx, 0x0a);Data++;break;default:Data++;break;}}else if(*Data=='%'){switch (*++Data){case 's':s = va_arg(ap, const char *);for ( ; *s; s++) {USART_SendData(USARTx,*s);while(USART_GetFlagStatus(USARTx, USART_FLAG_TC)==RESET);}Data++;break;case 'd':d = va_arg(ap, int);itoa(d, buf, 10);for (s = buf; *s; s++) {USART_SendData(USARTx,*s);while(USART_GetFlagStatus(USARTx, USART_FLAG_TC)==RESET);}Data++;break;default:Data++;break;} }else{USART_SendData(USARTx, *Data++);}while(USART_GetFlagStatus(USARTx, USART_FLAG_TC)==RESET);}}char *itoa(int value, char *string, int radix){int     i, d;int     flag = 0;char    *ptr = string;/* This implementation only works for decimal numbers. */if (radix != 10){*ptr = 0;return string;}if (!value){*ptr++ = 0x30;*ptr = 0;return string;}/* if this is a negative value insert the minus sign. */if (value < 0){*ptr++ = '-';/* Make the value positive. */value *= -1;}for (i = 10000; i > 0; i /= 10){d = value / i;if (d || flag){*ptr++ = (char)(d + 0x30);value -= (d * i);flag = 1;}}/* Null terminate the string. */*ptr = 0;return string;} /* NCL_Itoa */int SendChar (int ch)  {                /* Write character to Serial Port     */  USART_SendData(USART1, (unsigned char) ch);  while (!(USART1->SR & USART_FLAG_TXE));if(ch=='\r')SendChar('\n');  return (ch);}


新建usart.h文件:

<pre name="code" class="html">#ifndef __USART_H__#define __USART_H__#include <includes.h>void USART_OUT(USART_TypeDef* USARTx, uint8_t *Data,...);char *itoa(int value, char *string, int radix);int SendChar (int ch);#endif

stm32f10x_it.c文件中添加串口中断处理:

void USART1_IRQHandler(void){unsigned int i;unsigned char msg[50];OS_CPU_SR  cpu_sr;OS_ENTER_CRITICAL();OSIntNesting++;OS_EXIT_CRITICAL();//OSTimeTick();if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET){if(RxCounter1>20)RxCounter1=1;// Read one byte from the receive data register msg[RxCounter1++]= USART_ReceiveData(USART1);SendChar(msg[RxCounter1-1]);if(msg[RxCounter1-1]=='L'){msg[0]='L'; RxCounter1=1;}else if(msg[RxCounter1-1]=='F'){for(i=0; i< RxCounter1; i++){TxBuffer1[i]=msg[i];}TxBuffer1[RxCounter1]=0;RxCounter1=0;//OSSemPost(Com1_SEM);   OSMboxPost(Com1_MBOX,(void *)&msg);                    }}if(USART_GetITStatus(USART1, USART_IT_TXE) != RESET){ USART_ITConfig(USART1, USART_IT_TXE, DISABLE);}OSIntExit();}


APP.c文件中新建消息邮箱处理函数:


static  void Task_Com1(void *p_arg){INT8U err;unsigned char * msg;(void)p_arg;    while(1){msg=(unsigned char *)OSMboxPend(Com1_MBOX,0,&err);if(msg[0]=='L'&&msg[1]=='1'){milsec1=atoi(&msg[3]);USART_OUT(USART1,"\r\n");USART_OUT(USART1,"LED1: %d ms delay",milsec1);USART_OUT(USART1,"\r\n");}else if(msg[0]=='L'&&msg[1]=='2'){milsec2=atoi(&msg[3]);USART_OUT(USART1,"\r\n");USART_OUT(USART1,"LED2: %d ms delay",milsec2);USART_OUT(USART1,"\r\n");}}}



并添加该任务:

 OSTaskCreateExt(Task_Com1,(void *)0,(OS_STK *)&Task_Com1Stk[Task_Com1_STK_SIZE-1],Task_Com1_PRIO,Task_Com1_PRIO,(OS_STK *)&Task_Com1Stk[0],Task_Com1_STK_SIZE,(void *)0,OS_TASK_OPT_STK_CHK|OS_TASK_OPT_STK_CLR);

新建一个头文件globals.h:

#ifdef GLOBALS #define EXT#else#define EXT extern #endif EXT unsigned char TxBuffer1[400]; EXT unsigned char TxBuffer2[]; EXT unsigned char RxBuffer1[400];EXT unsigned char RxBuffer2[];EXT unsigned char TxCounter1;EXT unsigned int TxCounter2;EXT volatile unsigned int RxCounter1; EXT volatile unsigned int RxCounter2;EXT volatile unsigned char rec_f,tx_flag;EXT volatile unsigned long Rec_Len;EXT volatile unsigned  int  milsec1,milsec2,milsec3;

将 globals.h 文件 include 到 APP.c 和 stm32f10x_it.c 中,注意,在APP.c文件 中应该先define GLOBALS,即:

#define GLOBALS#include <globals.h>

APP.c文件中添加全局变量:

OS_EVENT* Com1_MBOX;

stm32f10x_it.c 中也添加该变量:

extern OS_EVENT* Com1_MBOX;

本工程在奋斗V5开发板测试通过:

通过串口连接开发板,可输入L1 500F即可将Led1的闪烁速度设置为500ms,L2 600F即可将Led2的闪烁速度设置为600ms

0 0
原创粉丝点击