初學(xué)者學(xué)習(xí)總結(jié),如有錯(cuò)誤,請(qǐng)大神指正
目的:用 STM32 的串口來發(fā)送和接收數(shù)據(jù)。
一、STM32串口
1.1 簡(jiǎn)介
ALIENTEK MiniSTM32 V3 版開發(fā)板選擇的是 STM32F103RCT6 作為 MCU,擁有5 個(gè)串口分別為
USART1、USART2、USART3、UART4、UART5,
其中只有USART1掛載在APB2總線上,其余均掛載在APB1總線上
APB1操作速度限于36MHz,APB2操 作于全速(最高72MHz)。
注:
UART? ? ?通用異步收發(fā)器
USART? ?通用同步異步收發(fā)器
1.2 端口復(fù)用
在STM32F103RCT6中串口 1 的引腳對(duì)應(yīng)的 IO 為 PA9,PA10而PA9,PA10 默認(rèn)功能是 GPIO,所以當(dāng) PA9,PA10 引腳作為串口 1 的 TX,RX 引腳使用的時(shí)候,那就是端口復(fù)用。
復(fù)用端口初始化有幾個(gè)步驟:
1) GPIO 端口時(shí)鐘使能。要使用到端口復(fù)用,當(dāng)然要使能端口的時(shí)鐘了。
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
2) 復(fù)用的外設(shè)時(shí)鐘使能。比如你要將端口 PA9,PA10 復(fù)用為串口,所以要使能串口時(shí)鐘。
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
3) 端口模式配置。在 IO 復(fù)用位內(nèi)置外設(shè)功能引腳的時(shí)候,必須設(shè)置 GPIO 端口的模式。下表為對(duì)應(yīng)模式
?例如要配置全雙工的串口 1??
代碼如下
//USART1_TX PA.9 復(fù)用推挽輸出
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //復(fù)用推挽輸出
GPIO_Init(GPIOA, &GPIO_InitStructure);
//USART1_RX PA.10 浮空輸入
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空輸入
GPIO_Init(GPIOA,GPIO_InitStructure);
1.3 USART庫(kù)函數(shù)
1.4 串口設(shè)置?
串口設(shè)置的一般步驟可以總結(jié)為如下幾個(gè)步驟:
1) 串口時(shí)鐘使能,GPIO 時(shí)鐘使能
2) 串口復(fù)位 3) GPIO 端口模式設(shè)置
4) 串口參數(shù)初始化
5) 開啟中斷并且初始化 NVIC(如果需要開啟中斷才需要這個(gè)步驟)
6) 使能串口
7) 編寫中斷處理函數(shù)文章來源地址http://www.zghlxwxcb.cn/news/detail-759640.html
1.5 主要函數(shù)介紹
1)串口時(shí)鐘使能
串口是掛載在 APB2 下面的外設(shè),所以使能函數(shù)為:
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1);
2)串口復(fù)位
?
USART_DeInit(USART1); //復(fù)位串口 1?
3)串口參數(shù)初始化
?一般的實(shí)現(xiàn)格式為:
USART_InitStructure.USART_BaudRate = bound; //波特率; USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字長(zhǎng)?8 位數(shù)據(jù)格式
USART_InitStructure.USART_StopBits = USART_StopBits_1; //一個(gè)停止位 USART_InitStructure.USART_Parity = USART_Parity_No; //無奇偶校驗(yàn)位 USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //無硬件數(shù)據(jù)流控制 USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收發(fā)模式 USART_Init(USART1, &USART_InitStructure); //初始化串口
4)數(shù)據(jù)發(fā)送與接收
STM32 的發(fā)送與接收是通過數(shù)據(jù)雙寄存器 USART_DR 來實(shí)現(xiàn)的,包含了 TDR 和 RDR。
當(dāng)向該寄存器寫數(shù)據(jù)的時(shí)候,串口就會(huì)自動(dòng)發(fā)送,當(dāng)收到收據(jù)的時(shí)候,存在該寄存器內(nèi)。
- 發(fā)送數(shù)據(jù)
例如
USART_SendData(USART3, 0x26);
- 接收數(shù)據(jù)
例如
USART_ReceiveData(USART3, 0x26);?
?5)串口狀態(tài)
6)串口使能
?例如
USART_Cmd(USART1, ENABLE);
7)開啟串口響應(yīng)中斷
?
例如
?USART_ITConfig(USART1, USART_IT_Transmit ENABLE);
8)獲取相應(yīng)中斷狀態(tài)
例如
?ITStatus ErrorITStatus;
ErrorITStatus = USART_GetITStatus(USART1, USART_IT_OverrunError);
二、硬件連接
在ALIENTEK MiniSTM32 V3 版開發(fā)板上串口 1 與 USB 串口并沒有在 PCB 上連接在一起,需要用跳線帽連接。
如圖
?三、程序設(shè)計(jì)
3.1 串口初始化程序
void uart_init(u32 bound){
//GPIO端口設(shè)置
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
//使能USART1,GPIOA時(shí)鐘
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE);
//USART1_TX即GPIOA9
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //復(fù)用推挽輸出
GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化GPIOA.9
//USART1_RX即GPIOA10初始化
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空輸入
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10
//Usart1 NVIC 配置
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//搶占優(yōu)先級(jí)3
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //子優(yōu)先級(jí)3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根據(jù)指定的參數(shù)初始化VIC寄存器
//USART 初始化設(shè)置
USART_InitStructure.USART_BaudRate = bound;//串口波特率
USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字長(zhǎng)為8位數(shù)據(jù)格式
USART_InitStructure.USART_StopBits = USART_StopBits_1;//一個(gè)停止位
USART_InitStructure.USART_Parity = USART_Parity_No;//無奇偶校驗(yàn)位
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//無硬
件數(shù)據(jù)流控制
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收發(fā)模式
USART_Init(USART1, &USART_InitStructure); //初始化串口1
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//開啟串口接受中斷
USART_Cmd(USART1, ENABLE); //使能串口1
}
代碼編寫對(duì)應(yīng)步驟:
1) 串口時(shí)鐘使能,GPIO 時(shí)鐘使能
2) 串口復(fù)位
3) GPIO 端口模式設(shè)置
4) 串口參數(shù)初始化
5) 開啟中斷并且初始化 NVIC
6) 使能串口
3.2 中斷接收程序
void USART1_IRQHandler(void) //串口1中斷服務(wù)程序
{
u8 Res;
#if SYSTEM_SUPPORT_OS //如果SYSTEM_SUPPORT_OS為真,則需要支持OS.
OSIntEnter();
#endif
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
//接收中斷(接收到的數(shù)據(jù)必須是0x0d 0x0a結(jié)尾)
{
Res =USART_ReceiveData(USART1); //讀取接收到的數(shù)據(jù)
if((USART_RX_STA&0x8000)==0)//接收未完成
{
if(USART_RX_STA&0x4000)//接收到了0x0d
{
if(Res!=0x0a)USART_RX_STA=0;//接收錯(cuò)誤,重新開始
else USART_RX_STA|=0x8000; //接收完成了
}
else //還沒收到0X0D
{
if(Res==0x0d)USART_RX_STA|=0x4000;
else
{
USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;
USART_RX_STA++;
if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;
//接收數(shù)據(jù)錯(cuò)誤,重新開始接收
}
}
}
}
即第七步文章來源:http://www.zghlxwxcb.cn/news/detail-759640.html
7) 編寫中斷處理函數(shù)
3.3 main
#include "sys.h"
#include "usart.h"
#include "delay.h"
#include "led.h"
int main(void)
{
u8 t;
u8 len;
u16 times=0;
delay_init(); //延時(shí)函數(shù)初始化
uart_init(9600); //串口初始化為 9600
LED_Init(); //初始化與 LED 連接的硬件接口
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //設(shè)置中斷分組
while(1)
{
if(USART_RX_STA&0x8000)
{
len=USART_RX_STA&0x3fff;//得到此次接收到的數(shù)據(jù)長(zhǎng)度
printf("\r\n 您發(fā)送的消息為:\r\n");
for(t=0;t<len;t++)
{
USART1->DR=USART_RX_BUF[t];
while((USART1->SR&0X40)==0);//等待發(fā)送結(jié)束
}
printf("\r\n\r\n");//插入換行
USART_RX_STA=0;
}else
{
times++;
if(times%5000==0)
{
printf("\r\nALIENTEK MiniSTM32 開發(fā)板 串口實(shí)驗(yàn)\r\n");
printf("正點(diǎn)原子@ALIENTEK\r\n\r\n\r\n");
}
if(times%200==0)printf("請(qǐng)輸入數(shù)據(jù),以回車鍵結(jié)束\r\n");
if(times%30==0)LED0=!LED0;//閃爍 LED,提示系統(tǒng)正在運(yùn)行.
delay_ms(10);
}
}
}
到了這里,關(guān)于STM32學(xué)習(xí)筆記3 正點(diǎn)原子miniSTM32串口通信實(shí)驗(yàn)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!