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