1.串口通信簡(jiǎn)介:通用異步收發(fā)傳輸器UART(Universal Asynchronous Receiver/Transmitter)是負(fù)責(zé)處理數(shù)據(jù)總線和串口之間的串/并通信的設(shè)備。UART通信規(guī)定了數(shù)據(jù)幀的格式:起始位、數(shù)據(jù)位、校驗(yàn)位、停止位等。UART異步通信只需要通信雙方設(shè)置好數(shù)據(jù)幀的格式和波特率即可完成通信。因?yàn)槭钱惒酵ㄐ牛圆恍枰獣r(shí)鐘,只需要兩根信號(hào)線就可以實(shí)習(xí)數(shù)據(jù)通信:接受數(shù)據(jù)RXD、發(fā)送數(shù)據(jù)TXD。
常見(jiàn)的使用了UASR通信協(xié)議的接口標(biāo)準(zhǔn)有:RS232、RS485等。
UART是全雙工通信:同一時(shí)刻兩個(gè)設(shè)備之間可以同時(shí)進(jìn)行發(fā)送和接受數(shù)據(jù)操作。
(補(bǔ)充:?jiǎn)喂ねㄐ牛喝魏螘r(shí)刻數(shù)據(jù)只能從一個(gè)方向進(jìn)行通信,一個(gè)設(shè)備發(fā)送,另一個(gè)設(shè)備接受。
??????????????? 半雙工通信:兩個(gè)設(shè)備之間可以收發(fā)數(shù)據(jù),但是不能在同一個(gè)時(shí)刻進(jìn)行,即在同一個(gè)時(shí)刻,只能一個(gè)設(shè)備發(fā)送,另一個(gè)設(shè)備接受。)
2.設(shè)計(jì)思路:本文通過(guò)串口中斷接受來(lái)接受發(fā)送到串口的數(shù)據(jù)。主要步驟是使能串口和引腳的時(shí)鐘、配置引腳和串口以及中斷的信息、寫串口中斷的回調(diào)函數(shù)。
配置串口通信,需要了解串口狀態(tài)寄存器USART_SR和數(shù)據(jù)寄存器USART_DA。
(1)串口狀態(tài)寄存器USART_SR:
?主要是了解第5位RXNE和第六位TC.
RXNE:為1時(shí),表示數(shù)據(jù)寄存器中有數(shù)據(jù),可以讀取數(shù)據(jù)。為0時(shí)表示未接收到數(shù)據(jù)。當(dāng)接受到數(shù)據(jù)時(shí),RXNE由硬件置為1??梢酝ㄟ^(guò)對(duì)數(shù)據(jù)寄存器USART_DR執(zhí)行讀操作,將RXNE置為0?;蛘呦虼宋粚懭?。
TC:可以通過(guò)此位判斷數(shù)據(jù)是否發(fā)送完成??梢酝ㄟ^(guò)讀取USART_SR寄存器,再往USART_DR寄存器寫入數(shù)據(jù),將TC置為?;蛘咧苯油鵗C位寫入0。
(2)串口數(shù)據(jù)寄存器USART_DR:
?如上圖所示,USART_DR只有0-8位是有用的。
3.代碼:
(1).usart.h:
#ifndef __USART_H
#define __USART_H
#include "stm32f10x.h"
#include <stdio.h>
#define RX_LEN 100 //?ü1??óêüμ?×?′ó×??úêy
extern u8 RX_BUF[RX_LEN];
extern int len;
extern u8 RX_FLAG;
void usart_init(int bound);
#endif
(2).usart.c:
#include "USART.h"
int len = 0;
u8 data;
u8 RX_BUF[RX_LEN];
u8 RX_FLAG = 0;
//′??ú3?ê??ˉoˉêy
void usart_init(int bound)
{
//1.?¨ò?òy???¢USART?¢?D???á11ì?£o
GPIO_InitTypeDef GPIO_Initstruct;
USART_InitTypeDef USART_Initstruct;
NVIC_InitTypeDef NVIC_Initstruct;
//2.ê1?ü???úoíUSARTμ?ê±?ó£o
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1,ENABLE);
//RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1 | RCC_APB2Periph_AFIO,ENABLE);
//3.????òy??£o
//PA9£o
GPIO_Initstruct.GPIO_Pin = GPIO_Pin_9;
GPIO_Initstruct.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Initstruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_Initstruct);
//PA10:
GPIO_Initstruct.GPIO_Pin = GPIO_Pin_10;
GPIO_Initstruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Initstruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_Initstruct);
//4.????USART1:
USART_Initstruct.USART_BaudRate = bound;
USART_Initstruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_Initstruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Initstruct.USART_Parity = USART_Parity_No;
USART_Initstruct.USART_StopBits = USART_StopBits_1;
USART_Initstruct.USART_WordLength = USART_WordLength_8b;
USART_Init(USART1,&USART_Initstruct); //???à1?êy?YD′è?USARTμ???′??÷
USART_Cmd(USART1,ENABLE); //ê1?üUSART??′??÷
USART_ITConfig(USART1,USART_IT_RXNE,ENABLE); //ê1?ü?óê??D??
//5.?????D??£o
NVIC_Initstruct.NVIC_IRQChannel = USART1_IRQn;
NVIC_Initstruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Initstruct.NVIC_IRQChannelPreemptionPriority = 3;
NVIC_Initstruct.NVIC_IRQChannelSubPriority = 3;
NVIC_Init(&NVIC_Initstruct);
}
void USART1_IRQHandler(void)
{
//uint16_t x[] = {1,2,3};
//?D??ê?·?2úéú′??úêy?Y?óêü?D??
if(USART_GetITStatus(USART1,USART_IT_RXNE) != RESET)
{
data = USART_ReceiveData(USART1);
RX_BUF[len++] = data;
RX_FLAG = 1;
}
}
//???¨?òfputcoˉêy£o
int fputc(int ch,FILE *f)
{
//1.?D??′??úê?·?·¢?ííê3é£o
while((USART1->SR & 0x40) == 0);
//2.·¢?íò???×??ú£???êy?YD′è?μ???′??÷£o
USART1->DR = (u8) ch;
return ch;
}
(3).main.c:
#include "stm32f10x.h"
#include "USART.h"
#include <stdio.h>
extern u8 data;
int main(void)
{
int i;
//?D??ó??è??·?×é£o
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
//3?ê??ˉ′??úUSART1:
usart_init(9600);
//char *x = "h";
while(1)
{
if(RX_FLAG)
{
printf("?óêüμ?μ?êy?Y:\r\n");
for(i = 0;i < len;i++)
{
USART_SendData(USART1,RX_BUF[i]);
while(USART_GetFlagStatus(USART1,USART_FLAG_TC) != SET); //?ì2éê?·?·¢?ííê3é
}
RX_FLAG = 0;
len = 0;
printf("\r\n\r\n");
}
}
}
上圖中的注釋會(huì)出現(xiàn)亂碼,將代碼復(fù)制到keil中就可以正常顯示了。
4.運(yùn)行結(jié)果:
5.總結(jié):配置串口通信需要使能引腳、串口時(shí)鐘,配置rx、tx引腳 ,配置串口寄存器,配置中斷。雖然,這些都可以通過(guò)STM32提供的庫(kù)函數(shù)完成。但是,我們還是應(yīng)該是大概的了解一下對(duì)應(yīng)寄存器的功能。比如USART_SR和USART_DR。
使用異步收發(fā)傳輸器UART的通信雙方需要設(shè)置好數(shù)據(jù)幀格式、波特率,通過(guò)接受數(shù)據(jù)RXD和發(fā)送數(shù)據(jù)TXD即可完成通信。UART數(shù)據(jù)通信的方式為全雙工。UART具有通信簡(jiǎn)單,易實(shí)習(xí)的優(yōu)點(diǎn),其缺點(diǎn)是傳輸速率低、傳輸距離較短、容易被干擾。
UART與通用同步/異步串行收發(fā)器USART(Universal Synchronous/Asynchronous Receiver/Transmitter)的區(qū)別在于:UART只有異步通信,而USART有同步和異步通信。文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-603307.html
同步和異步最大的區(qū)別在于:同步通信中雙方需要時(shí)鐘線進(jìn)行同步,而異步通信不需要時(shí)鐘線。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-603307.html
到了這里,關(guān)于STM32入門學(xué)習(xí)之USART串口通信:的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!