STM32 中使用USB轉(zhuǎn)TTL接口 使用USART1 與PC通訊
USART:通用同步/異步串行接收/發(fā)送器
STM32開(kāi)發(fā)板USART1的 TXD1對(duì)應(yīng)PA9,RXD1對(duì)應(yīng)PA10,如圖:
PA9 && PA10.png開(kāi)發(fā)板中自帶usb轉(zhuǎn)ttl接口,并且使用的是usart1,正好是PA9和PA10,如圖:
圖片.png注意:usb轉(zhuǎn)ttl接口的TXD管腳需要接STM32的RXD,usb轉(zhuǎn)TTL接口的RXD管腳需要接STM32的TXD管腳,由于開(kāi)發(fā)板自帶了,所以已經(jīng)正確連接了,無(wú)需擔(dān)心。
查詢(xún)方式與PC端交互
1.打開(kāi)A端口和USART1和IO復(fù)用的時(shí)鐘
由于用到了PA9和PA10,所以需要將A端口時(shí)鐘打開(kāi),此外用到了USART1,我們需要將USART1的時(shí)鐘使能,此外還需要對(duì)IO端口復(fù)用端口使能。
SystemInit();//將系統(tǒng)時(shí)鐘打開(kāi),這是第一句必須寫(xiě)的代碼,
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOB, ENABLE);
2.將PA9和PA10的管腳初始化
PA9對(duì)應(yīng)的是TXD,所以是輸出端口,往外部寫(xiě),需要初始化為GPIO_Mode_AF_PP; //復(fù)用推挽輸出
PA10對(duì)應(yīng)的是RXD,所以是輸入端口,往內(nèi)部讀,需要初始化GPIO_Mode_IN_FLOATING; //浮空輸入
GPIO_InitTypeDef GPIO_InitStructure;
//USART1 Tx(PA.09)
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_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;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空輸入
GPIO_Init(GPIOA, &GPIO_InitStructure);
3. 將USART1進(jìn)行初始化
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate = 9600; //波特率
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; //收發(fā)模式
USART_Init(USART1, &USART_InitStructure);//初始化USART1
4. 將USART1使能,這是最后一步了就可以收發(fā)數(shù)據(jù)了
USART_Cmd(USART1, ENABLE); //USART1使能
測(cè)試代碼,連接到PC 使用串口調(diào)試工具
uint16_t temp;
while (1)
{
if(USART_GetFlagStatus(USART1, USART_FLAG_RXNE) != RESET)
{
temp = USART_ReceiveData(USART1);//得到一個(gè)數(shù)
USART_SendData(USART1,temp + 1); //然后將這個(gè)數(shù)字加1,再發(fā)送出去
}
}
成功效果如圖:
圖片.png
接下來(lái)我們嘗試一下中斷方式利用USART1與PC端進(jìn)行中斷
1.打開(kāi)A端口和USART1和IO復(fù)用的時(shí)鐘
由于用到了PA9和PA10,所以需要將A端口時(shí)鐘打開(kāi),此外用到了USART1,我們需要將USART1的時(shí)鐘使能,此外還需要對(duì)IO端口復(fù)用端口使能。
SystemInit();//將系統(tǒng)時(shí)鐘打開(kāi),這是第一句必須寫(xiě)的代碼,
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOB, ENABLE);
2.將PA9和PA10的管腳初始化
PA9對(duì)應(yīng)的是TXD,所以是輸出端口,往外部寫(xiě),需要初始化為GPIO_Mode_AF_PP; //復(fù)用推挽輸出
PA10對(duì)應(yīng)的是RXD,所以是輸入端口,往內(nèi)部讀,需要初始化GPIO_Mode_IN_FLOATING; //浮空輸入
GPIO_InitTypeDef GPIO_InitStructure;
//USART1 Tx(PA.09)
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_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;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空輸入
GPIO_Init(GPIOA, &GPIO_InitStructure);
3. 將USART1進(jìn)行初始化
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate = 9600; //波特率
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; //收發(fā)模式
USART_Init(USART1, &USART_InitStructure);//初始化USART1
4. 配置USART1的中斷優(yōu)先級(jí)
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate = 9600;//波特率為9600
USART_InitStructure.USART_WordLength = USART_WordLength_8b;//配置數(shù)據(jù)位是8位
USART_InitStructure.USART_StopBits = USART_StopBits_1;//停止位是1位
USART_InitStructure.USART_Parity = USART_Parity_No; //無(wú)校驗(yàn)?zāi)J? USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//無(wú)硬件控制模式
USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;//收發(fā)模式使能 可以
USART_Init(USART1, &USART_InitStructure);//初始化USART1
5.打開(kāi)USART1的中斷
USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//打開(kāi)中斷
6.清除中斷標(biāo)志位
USART_ClearFlag(USART1,USART_FLAG_TC);//清除發(fā)送完成標(biāo)志位
7.將外設(shè)USART1使能,接下來(lái)我們只差寫(xiě)中斷函數(shù)了
USART_Cmd(USART1,ENABLE);//將串口1使能
8.中斷函數(shù),將得到的數(shù)加上1之后再發(fā)出去
void USART1_IRQHandler(void)
{
if(USART_GetITStatus(USART1,USART_IT_RXNE) == SET)
{
USART_SendData(USART1,USART_ReceiveData(USART1) + 1);
//判斷是否發(fā)送完成,如果沒(méi)有發(fā)送完成 不讓其退出中斷,那么此時(shí)此刻發(fā)送數(shù)據(jù)寄存器空標(biāo)志位是0,當(dāng)空標(biāo)志位等于1時(shí),可以退出
while(USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET);
}
}
成功效果如圖
圖片.png
實(shí)驗(yàn)感想
中斷方式的話很容易出現(xiàn)問(wèn)題,會(huì)容易損失數(shù)據(jù),比如你想要發(fā)送123456789這九個(gè)數(shù)據(jù),其實(shí)調(diào)用了9次中斷,但是中斷過(guò)程需要時(shí)間,所以極大概率會(huì)損失數(shù)據(jù)。所以呢中斷過(guò)程可以只接受數(shù)據(jù),但是不處理數(shù)據(jù),在本次實(shí)驗(yàn)中,發(fā)送數(shù)據(jù)其實(shí)就是處理數(shù)據(jù)了。
如何使用printf函數(shù)來(lái)向串口發(fā)送數(shù)據(jù)
我們只需要重載一個(gè)函數(shù)就可以了
int fputc(int ch,FILE *f)
{
USART_SendData(USART1,(u8)ch);
while(USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET);
return ch;
}
接下來(lái)包含頭文件stdio.h頭文件就可以使用printf來(lái)向串口發(fā)送數(shù)據(jù)了。
QQ: 271257129



