一、串口通信
通信的目的:將一個設備的數據傳送到另一個設備,擴展硬件系統
通信協議:制定通信的規則,通信雙方按照協議規則進行數據收發
STM32F103C8T6 USART資源: USART1、 USART2、 USART3
自帶波特率發生器,最高達4.5Mbits/s
可配置數據位長度(8/9)、停止位長度(0.5/1/1.5/2 -->一般都是一個停止位)??
可選校驗位(無校驗/奇校驗/偶校驗-->一般不用)
SART是STM32內部集成的硬件外設,可根據數據寄存器的一個字節數據自動生成數據幀時序,從TX引腳發送出去,也可自動接收RX引腳的數據幀時序,拼接為一個字節數據,存放在數據寄存器里
支持同步模式(多一個輸出時鐘,之后變成同步通信--->一般不用)、硬件流控制(多一條硬件的線,如果接收方準備好接收則硬件線就置高電平,否則置低電平,這樣就不會導致對方發送數據過快,沒有處理的數據被覆蓋-->一般不用硬件流方式)、DMA、智能卡、IrDA、LIN
二、接線規則
簡單雙向串口通信有兩根通信線(發送端TX和接收端RX) ,TX與RX要交叉連接 ,當只需單向的數據傳輸時,可以只接一根通信線 當電平標準不一致時,需要加電平轉換芯片。
三、串口參數、時序
波特率:串口通信的速率(例如:1Mbps,則1S傳輸1000位數據)
起始位:標志一個數據幀的開始,固定為低電平(空閑時是高電平)
數據位:數據幀的有效載荷,1為高電平,0為低電平,低位先行
校驗位:用于數據驗證,根據數據位計算得來(例如:奇校驗->包括校驗位的9個數據中的1要為奇數(1110 1110 1),偶校驗->包括校驗位的9個數據位中的1要為偶數(1100 1100 0))
停止位:用于數據幀間隔,固定為高電平(0.5/1/1.5/2)
停止位:用于數據幀間隔,固定為高電平(0.5/1/1.5/2)
四、數據發送和接收、寄存器、引腳圖
發送數據寄存器(TDR)和接收數據寄存器(RDR)占用同一個地址,在程序中表現出來的只有一個DR寄存器,寫的時候從TDR寫進去,讀的時候從RDR讀。
發送移位數據寄存器:把數據一位一位的移出去
? ? ? ? ? ? ? ? 例發送:給TDR寫入一個0X55(0101 0101)數據,此時硬件檢測到寫入數據了(數據在發送數據寄存器),就會檢查移位寄存器是否有別的數據在移位,如果沒有0x55就會整體全部進入移位數據寄存器,當數據從TDR數據寄存器進入移位寄存器時,會置一個TXE(TX Empty發送數據寄存器空)的標志位,如果標志位是1,則說明發送數據寄存器為空,可以向發送數據寄存器繼續寫入數據。移位數據寄存器有數據時,在發送控制器的驅動下,將數據發送到TX。移位數據寄存器為空時TC標志位置1;(低位先行)
? ? ? ? ? ? ? ? 例接收:RX有數據時在接收控制器的驅動下將數據一位一位的移動到移位寄存器,當移位寄存器收滿一個字節時,就會將數據整體一下子全部轉移到數據寄存器(RDR),接收移位寄存器是從高位往低位的方向移動(高位先行)。當RXNE置1是說明接收數據寄存器有數據
五、代碼
#include "usart.h"
#include "stm32f10x.h"void usart_init(void)
{GPIO_InitTypeDef gpioInit; //定義配置GPIO的結構體USART_InitTypeDef usartInit; //定義配置串口的結構體NVIC_InitTypeDef NVICInit; //定義配置中斷控制的結構體
//1.配置時鐘: GPIO口的時鐘,串口的時鐘, 引腳復用的時鐘RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//USART 中斷的配置//2.配置GPIO的結構體//配置PA9(TX)gpioInit.GPIO_Mode = GPIO_Mode_AF_PP;gpioInit.GPIO_Pin = GPIO_Pin_9;gpioInit.GPIO_Speed = GPIO_Speed_10MHz;GPIO_Init(GPIOA, &gpioInit);//配置PA10(rx)gpioInit.GPIO_Mode = GPIO_Mode_IN_FLOATING;gpioInit.GPIO_Pin = GPIO_Pin_10;GPIO_Init(GPIOA, &gpioInit);//3.配置串口的結構體usartInit.USART_BaudRate = 115200; //配置波特率為9600usartInit.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//是否開啟硬件流控模式usartInit.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //設置模式為讀和寫方式usartInit.USART_Parity = USART_Parity_No; //設置奇偶校驗位為空usartInit.USART_StopBits = USART_StopBits_1; //設置停止為1usartInit.USART_WordLength = USART_WordLength_8b; //設置發送或者接收的幀數為八字節USART_Init(USART1, &usartInit); //初始化串口的結構體USART_Cmd(USART1, ENABLE); //打開串口//配置NVIC中斷控制器
// NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);NVICInit.NVIC_IRQChannel = USART1_IRQn;NVICInit.NVIC_IRQChannelCmd = ENABLE;NVICInit.NVIC_IRQChannelPreemptionPriority = 1;NVICInit.NVIC_IRQChannelSubPriority = 1;NVIC_Init(&NVICInit);}
//發送字符
void USARTSsendData(USART_TypeDef* USARTx, uint16_t Data)
{USART_SendData(USARTx,Data); //等待發送數據寄存器中的數據被取走while(USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET);//等待高電平,數據發送完是高電平
}//發送字符串,字符串所以數據都發送完之后才跳出中斷
void USARTSsendStr(USART_TypeDef* USARTx, char *str)
{uint16_t i = 0;do{USARTSsendData(USARTx, *(str+i));i++;}while(*(str+i) != '\0');//等待發送移位寄存器(為空)while(USART_GetFlagStatus(USARTx, USART_FLAG_TC) == RESET);//等待高電平,數據發送完是高電平}
//USART_FLAG_TC就是用來標志,發送移位寄存器中的數據有沒有全部發送出去
//其實USART_FLAG_TXE就是用來標志一個事件的,通過它的值可以知道該事件有沒有發生(即發送數據寄存器中的數據有沒有被取走)。
//重定向輸出函數
int fputc(int ch,FILE *F)
{USART_SendData(USART1,(uint8_t) ch);while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);//等待高電平,數據發送完是高電平return ch;//內容是通過串口發送的,而不是這個返回值}//重定向輸入
int fgetc(FILE *F)
{while(USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET);//等待高電平,數據發送完是高電平return (int)USART_ReceiveData(USART1); //高電平的時候,收到數據可以讀出數據,0是沒有數據}//void USART1_IRQHandler(void)
//{
// char tmp;
// if(USART_GetITStatus(USART1, USART_IT_RXNE) ==SET )
// {
// USART_ClearITPendingBit(USART1, USART_IT_RXNE);
// tmp = USART_ReceiveData(USART1);
// USART_SendData(USART2, tmp);
// while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET);//等待發送完成
// }
//
//}/*@arg USART_FLAG_CTS: CTS Change flag (not available for UART4 and UART5) CTS標志位* @arg USART_FLAG_LBD: LIN Break detection flag //LIN中斷檢測位
* @arg USART_FLAG_TXE: Transmit data register empty flag //發送數據寄存器空標志位
* @arg USART_FLAG_TC: Transmission Complete flag //發送完成空標志位* @arg USART_FLAG_RXNE: Receive data register not empty flag //接收數據寄存器非空標志位* @arg USART_FLAG_IDLE: Idle Line detection flag //空閑總線標志位* @arg USART_FLAG_ORE: OverRun Error flag //溢出錯誤標志位* @arg USART_FLAG_NE: Noise Error flag //噪聲錯誤標注位* @arg USART_FLAG_FE: Framing Error flag //幀錯誤標志位* @arg USART_FLAG_PE: Parity Error flag //奇偶錯誤標志位* @retval The new state of USART_FLAG (SET or RESET).
*/