串口介紹
串口:全稱串行接口,也稱串行通信接口或串行通訊接口(通常指COM接口),是採用串行通信方式的擴展接口。串行接口 (Serial Interface)是指數據一位一位地順序傳送。其特點是通信線路簡單,只要一對傳輸線就可以實現雙向通信(可以直接利用電話線作爲傳輸線),從而大大降低了成本,特別適用於遠距離通信,但傳送速度較慢。
STM32的串行通信接口:
1.UART:通用同步收發器。
2.USART:通用同步異步收發器。
(大容量STM32F10x系列芯片包含兩個UART與三個USART)
USART概述
USART框圖:
相關初始化:
typedef struct
{
uint32_t USART_BaudRate; //波特率設置
uint16_t USART_WordLength;//數據字長
uint16_t USART_StopBits;//停止位
uint16_t USART_Parity;//奇偶位校驗
uint16_t USART_Mode;//模式(發送或接收)
uint16_t USART_HardwareFlowControl; //硬件流控制
} USART_InitTypeDef;
奇偶校驗位:偶校驗:輸送的8位數據的1如果爲偶數則爲0,奇數爲1。(使1爲偶數)
奇校驗:輸送的8位數據的1如果爲奇數則爲0,偶數爲1。(使1爲奇數)
作用:提高數據傳輸的準確性。
波特率:每秒鐘傳送的碼元符號的個數,它是對符號傳輸速率的一種度量,它用單位時間內載波調製狀態改變的次數來表示,1波特即指每秒傳輸1個符號。(一個數字脈衝就是一個碼元,如‘1’,'0’各是一個碼元)
通信方式
按輸送位數
1.並行通信:數據各個位同時傳輸(速度快但佔用引腳多)。
2.串行通信:數據按位順序傳輸(速度慢但佔用引腳少)。
按傳輸方向
1.單工:只支持數據單方向傳輸。
2.半雙工:允許數據雙向傳輸,但同一時刻數據只能往一個方向傳輸,即方向可改變的單工通信。
3.全雙工:允許數據同時在兩個方向上傳輸。
按傳輸有無時鐘
1.同步通信:帶時鐘同步信號傳輸(SPI,IIC通信接口)。
在約定的通信速率下,發送端和接收端的時鐘信號頻率始終保持一致(同步),保證了通信雙方在發送和接收數據時具有完全一致的定時關係。
2.異步通信:不帶時鐘同步信號(UART通用異步收發器,單總線)。
同步通信與異步通信區別:
1.同步通信要求接收端時鐘頻率和發送端時鐘頻率一致,發送端發送連續的比特流;異步通信時不要求接收端時鐘和發送端時鐘同步,發送端發送完一個字節後,可經過任意長的時間間隔再發送下一個字節;
2.同步通信效率高,異步通信效率較低。(異步通信必須在每一個字符的開始和結束的地方加上標誌,即加上開始位和停止位);
3.同步通信較複雜,雙方時鐘的允許誤差較小;異步通信簡單,雙方時鐘可允許一定誤差;
4.同步通信可用於點對多點,異步通信只適用於點對點。
USART初始化步驟
1.串口時鐘使能,GPIO時鐘使能;
2.GPIO端口模式設置;
3.串口參數初始化;
4.開啓中斷並初始化NVIC;(若開啓中斷)
5.使能相應串口;
6.編寫中斷處理函數;
7.串口數據收發及傳輸狀態獲取。
例:
void MY_USART1_Init(void)
{
GPIO_InitTypeDef GPIO_InitStrue;//相應結構體初始化
USART_InitTypeDef USART_InitStrue;
NVIC_InitTypeDef NVIC_InitStrue;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//使能GPIO時鐘
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//使能串口時鐘
GPIO_InitStrue.GPIO_Mode=GPIO_Mode_AF_PP;//GPIO9的初始化
GPIO_InitStrue.GPIO_Pin=GPIO_Pin_9;
GPIO_InitStrue.GPIO_Speed=GPIO_Speed_10MHz;
GPIO_Init(GPIOA,&GPIO_InitStrue);
GPIO_InitStrue.GPIO_Mode=GPIO_Mode_IN_FLOATING;//GPIO10的初始化
GPIO_InitStrue.GPIO_Pin=GPIO_Pin_10;
GPIO_InitStrue.GPIO_Speed=GPIO_Speed_10MHz;
GPIO_Init(GPIOA,&GPIO_InitStrue);
USART_InitStrue.USART_BaudRate=115200;//初始化串口相關參數
USART_InitStrue.USART_HardwareFlowControl=USART_HardwareFlowControl_None;
USART_InitStrue.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;//使能發送與接收
USART_InitStrue.USART_Parity=USART_Parity_No;//取消奇偶校驗
USART_InitStrue.USART_StopBits=USART_StopBits_1;
USART_InitStrue.USART_WordLength=USART_WordLength_8b;
USART_Init(USART1,&USART_InitStrue);
USART_Cmd(USART1,ENABLE);//使能串口
USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//串口一中斷函數:接收中斷
NVIC_InitStrue.NVIC_IRQChannel=USART1_IRQn;//確定通道
NVIC_InitStrue.NVIC_IRQChannelCmd=ENABLE;//開啓上述通道
NVIC_InitStrue.NVIC_IRQChannelPreemptionPriority=1;//設置搶佔優先級
NVIC_InitStrue.NVIC_IRQChannelSubPriority=1;//子優先級
NVIC_Init(&NVIC_InitStrue);//優先級初始化
}
void USART1_IRQHandler(void)//中斷處理函數
{
u8 sju;
if(USART_GetITStatus(USART1,USART_IT_RXNE))//如果接收到數據
{
sju=USART_ReceiveData(USART1);//讀該串口的數據
USART_SendData(USART1,sju);//把數據發送出去
}
}
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//系統優先級分組設置爲2
MY_USART1_Init();
while(1);
}
附串口操作相關庫函數:
void USART_Init();//串口初始化
void USART_Cmd();//使能串口
void USART_ITConfig();//使能相關中斷
void USART_SendData();//發送數據到串口
uint16_t USART_ReceiveData();//接收數據
FlagStatus USART_GetFlagStatus();//獲取狀態標誌位
void USART_ClearFlag();//清除狀態標誌位
ITStatus USART_GetITStatus();//獲取中斷狀態標誌位
void USART_ClearITPendingBit();//清除狀態標誌位