這是算是大家最常見串列通訊,他原理較簡單方便,現在韌體工程師在除錯或為簡單驗證資料,大家知道TX、RX主機和從機對接transmitter(TX)為發射端、receiver(RX)為接收端。
再來我介紹一下協議的部分吧,TX對接另個設備的RX只要兩邊的設定的鮑率相同就可以做溝通,這設定鮑率就類似像I2C的時脈線,那UART就只剩下資料線而已,那數據的格式就很簡單了啦,有點類似I2C。
資料格式:
校驗位的話可有可無,擔心傳輸中會有偏差造成資料錯誤,可以選擇校驗位開啟。
STM32的UASRT是同步非同步收發,UART為非同步收發
UASRT可以全雙工的Data,UART就去掉同步,我們通常都用到UART而已
UART部分就沒這麼複雜了,來看看程式吧
#ifndef __BSP_UART_H
#define __BSP_UART_H
#include "stm32f0xx.h"
#include "stdio.h"
#define DEBUG_USARTx USART2
#define DEBUG_USART_CLK RCC_APB1Periph_USART2
#define DEBUG_USART_APBxClkCmd RCC_APB1PeriphClockCmd
#define DEBUG_USART_BAUDRATE 9600
#define DEBUG_USART_GPIO_CLK RCC_AHBPeriph_GPIOA
#define DEBUG_USART_GPIO_AHBClkCmd RCC_AHBPeriphClockCmd
#define DEBUG_USART_TX_GPIO_PORT GPIOA
#define DEBUG_USART_TX_GPIO_PIN GPIO_Pin_2
#define DEBUG_USART_RX_GPIO_PORT GPIOA
#define DEBUG_USART_RX_GPIO_PIN GPIO_Pin_3
void DEBUG_USART_Config(void);
void Usart_SendString( USART_TypeDef * pUSARTx, char *str);
void Usart_SendByte( USART_TypeDef * pUSARTx, uint8_t ch);
這樣定義有個好處,移到其他UART口或著是移到其他型號MCU,只要來這邊做修改就好。
DEBUG_USART_Config:這是初始化UART外設IO口
Usart_SendString:發送字串
Usart_SendByte:發送1Byte的資料
//bsp board support package
#include "bsp_uart.h"
void DEBUG_USART_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
DEBUG_USART_GPIO_AHBClkCmd(DEBUG_USART_GPIO_CLK,ENABLE);
DEBUG_USART_APBxClkCmd(DEBUG_USART_CLK,ENABLE);
GPIO_InitStructure.GPIO_Pin = DEBUG_USART_TX_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_Level_1;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOA,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = DEBUG_USART_RX_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_Init(GPIOA,&GPIO_InitStructure);
GPIO_PinAFConfig(GPIOA,GPIO_PinSource2,GPIO_AF_1);
GPIO_PinAFConfig(GPIOA,GPIO_PinSource3,GPIO_AF_1);
USART_InitStructure.USART_BaudRate = DEBUG_USART_BAUDRATE;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_Init(DEBUG_USARTx,&USART_InitStructure);
UART_NVIC_InitConfig();
USART_ITConfig(DEBUG_USARTx,USART_IT_RXNE,ENABLE);
USART_ClearFlag(DEBUG_USARTx,USART_FLAG_TC);
USART_Cmd(DEBUG_USARTx,ENABLE);
}
可以看到上面,要先開UART的腳位的GPIO口復用功能,復用功能ST都設計好了,你只需要設定到復用功能AF多少就好了。
我這邊是用PA2、PA3,所以復用AF1(紅框部分)
再來是發送的程式:
void Usart_SendByte( USART_TypeDef * pUSARTx, uint8_t ch)
{
USART_SendData(pUSARTx,ch);
while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET);
}
void Usart_SendString( USART_TypeDef * pUSARTx, char *str)
{
unsigned int k=0;
do
{
Usart_SendByte( pUSARTx, *(str + k) );
k++;
} while(*(str + k)!='\0');
while(USART_GetFlagStatus(pUSARTx,USART_FLAG_TC)==RESET)
{}
}
int fputc(int ch, FILE *f)
{
/* 發送一個字節數據到串口 */
USART_SendData(DEBUG_USARTx, (uint8_t) ch);
/* 等待傳送完畢 */
while (USART_GetFlagStatus(DEBUG_USARTx, USART_FLAG_TXE) == RESET);
return (ch);
}
///重定向c库函数scanf到串口可使用scanf、getchar等函数
int fgetc(FILE *f)
{
/* 等待串口输入数据 */
while (USART_GetFlagStatus(DEBUG_USARTx, USART_FLAG_RXNE) == RESET);
return (int)USART_ReceiveData(DEBUG_USARTx);
}
看到int fputc跟int fgetc,這兩個函式就是可以讓UART傳送利用Printf做使用,接收用scanf,這樣看起來比較親切一點。
接下就在主程式就打printf TX就會發送啦,可以快速驗證自己的程式有沒有符合自己的預期~