串口是USART(通用同步/異步收發器)的俗稱。實際上,串行總線并不只有USART,還包含IIC、SPI、CAN、K線、單總線、USB、485等等總線,只是因為UART用得較多,習慣上叫做“串口”。
首先來看下UART的通信模型,
設備1與設備2進行通信
TXD:發送端,負責發送數據
RXD:接收端,負責接收數據
GND:地線,保證設備1與設備2有相同的參考電壓,保證通信的正常進行。
從模型上我們可以看出UART(USART是同步通信,在這個模型的基礎上都一條始終控制總線,但不常用)是一個異步、全雙工、串行通信。既然是異步的,那么就需要控制設備1與設備2數據收發的速度一致性,也就是兩設備要有相同的波特率(bit/s一秒鐘能傳的),否則通信會出現數據傳輸錯誤。
現在我們配置stm32的串口1,實現與PC端上的串口助手實現通信。首先查看串口的引腳、查看芯片手冊上各引腳對用的復用功能等。
以下是實現代碼,主要是實現Uart1數據的收發。
void USART1_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
//配置時鐘
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);
/* USART1 GPIO config */
/* Configure USART1 Tx (PA.09) as alternate function push-pull */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* 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);
/* USART1 mode config */
USART_InitStructure.USART_BaudRate = 115200;
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(USART1, &USART_InitStructure);
//使能串口中斷
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
//清空發送完成標志位
USART_ClearFlag(USART1,USART_FLAG_TC);
//使能串口
USART_Cmd(USART1, ENABLE);
}
//定義printf函數接口(printf重定向)
int fputc(int ch, FILE *f)
{
USART_SendData(USART1, (uint8_t) ch);
while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
return (ch);
}
//定義scanf函數接口(scanf重定向)
int fgetc(FILE *f)
{
while (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET);
return (int)USART_ReceiveData(USART1);
}
//發送字符
char usart1_putc(char ch)
{
USART_SendData(USART1, (uint8_t) ch);
while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) != SET);
return (ch);
}
//發送字符串
int usart1_putstr(unsigned char* buff,int len)
{
int i = 0;
for(i = 0;i < len;i++)
{
usart1_putc(buff[i]);
}
return len;
}
//接收字符
char usart1_getc(void)
{
char temp = 0;
while(USART_GetFlagStatus(USART1,USART_FLAG_RXNE)!= SET);
temp = USART_ReceiveData(USART1);
return temp;
}
//接收字符串
int usart1_getstr(unsigned char* buff,int len)
{
int i = 0;
for(i = 0;i < len;i++)
{
buff[i] = usart1_getc();
}
return len;
}
配置好之后,將這些函數放到頭文件中申明,并放到主函數中去初始化及調用,就可以實現數據的收發功能。