硬件電路
在國信長天提供的資料中,我們可以看出板子有兩個串口,但是具體用一個呢?在這我可以肯定比賽的時候用的一定是USART2,因爲USART1需要通過232轉接一下,況且不是每個地方都有這玩意,所以比賽的時候一定不會用這個。所以我們只需要瞭解好USART2就夠了。
代碼實現
usart.c
#include "usart.h"
_Bool Rx_Flag=0; //代表數據接收完成
u8 RxBuffer1[20]; //接收到的數據放的數組
u8 RxCounter1=0; //接收到了多少個
u8 Demo[20]="OK"; //這是一個例子,後面在數組比較中使用
void Usart2_Init(void){
USART_InitTypeDef USART_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO,ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
USART_InitStructure.USART_BaudRate = 9600;
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;
USART_Init(USART2, &USART_InitStructure);
USART_ITConfig(USART2,USART_IT_RXNE,ENABLE);
USART_Cmd(USART2, ENABLE);
}
void USART2_IRQHandler(void)
{
u8 temp=0;
if(USART_GetITStatus(USART2,USART_IT_RXNE)!=RESET)
{
usart_State = 1;
USART_ClearFlag(USART2, USART_IT_RXNE);
temp= USART_ReceiveData(USART2);
if(temp=='\n')
{
Rx_Flag=1;
RxCounter1=0;
USART_ITConfig(USART2,USART_IT_RXNE,DISABLE);
}
else{
RxBuffer1[RxCounter1++] = temp;
}
}
}
_Bool Buffercmp(uint8_t* pBuffer1, uint8_t* pBuffer2)
{
while(*pBuffer1!=0)
{
if(*pBuffer1 != *pBuffer2)
{
return 0;
}
pBuffer1++;
pBuffer2++;
}
return 1;
}
PUTCHAR_PROTOTYPE //這個內容會在.h中有宏定義的
{
USART_SendData(USART2, (uint8_t) ch);
while (USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET)
{}
return ch;
}
void Usart_Check(void){
u8 i =0;
if(Rx_Flag){
if(Buffercmp(RxBuffer1,Demo)) printf("OK");
else printf("ERROR");
for(i=0;i<20;i++){
RxBuffer1[i]=0;
}
USART_ITConfig(USART2,USART_IT_RXNE,ENABLE);
Rx_Flag=0;
}
}
注意事項
- 串口中斷是沒接收到一個字符進入一次,那麼我們先對這個字符進行判斷這個字符是不是接收數據的結束標誌位。如果是則另Rx_Flag=1,RxCounter1=0(這裏置0是爲了下次再接收數據的時候,從數組第一位開始存放),對接收中斷失能(這裏是爲了現在主函數對這個數組進行處理完畢,再打開,避免相互影響)。
- Buffercmp這個函數就是一個字符串比較函數,你可以先定義一個數組內容然後與接收到的數組進行比較,這就很方便的。
- PUTCHAR_PROTOTYPE這是是對printf函數進行重寫,當你再用printf的時候,是直接通過串口發送到PC機了。注意這裏是USART_FLAG_TXE,如果用USART_FLAG_TC會造成發送第一個數據丟失的現象。這裏要包含#include "stdio.h"還要勾選微庫,如下圖所示。
- Usart_Check()是對接受到的數組進行判斷,如果正確則發送OK,否則發送ERROR,這個函數放到main的循環中就可以了。這裏有幾個細節要注意一下,1:進入函數後要對Rx_Flag標誌位要清0,防止一直進入。2:要對接受數組清0,防止上次的數據對本次有影響。3:要再次打開串口接收中斷,爲了處理後的再次接收。
usart.h
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __usart_H
#define __usart_H
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
_Bool Buffercmp(uint8_t* pBuffer1, uint8_t* pBuffer2);
void Usart2_Init(void);
void Usart_Check(void);
extern _Bool Rx_Flag;
extern u8 RxBuffer1[20],Demo[20];
extern u8 RxCounter1;
#endif