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

提醒:

如果您是完全按照《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

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值