USART的模式功能有很多本次配置的是最初級的模式,將數據發送到電腦串口助手上,以便于程序的調試.今日寫下配置步驟,以及調試的經驗總結. 配置分為三個模塊,一者GPIO 二者USART 三者printf輸出重定向函數 硬件連接(PA9/TX,PA10/RX)
GPIO模塊 首先不僅要有個疑問,為何USART模塊不是GPIO模塊,也不用點亮LED燈,為什么要配置他那.原因很簡單,因為雖然不用GPIO點燈,卻需要RX,TX與外部通信,也就是GPIO引腳不是普通的GPIO了,而是連接到USART的復用功能的引腳了.所以只要是內部外設需要與芯片外步連接的話就需要GPIO配置成復用功能. 具體來講只要用到了GPIO模塊就需要先將GPIO的時鐘打開.接下來才可以具體配置引腳.配置引腳配置哪個引腳?上一段說了,GPIO可以用到通用功能用來電燈等操作,還可以作用復用功能如USART,SPI等功能.不僅如此不要小看看這小小的芯片.USART等外設對應(連接)著自己的固定的引腳,而且不是固定的一個,根據引腳的多少不同可能對應著兩個三個甚至四個,這便是STM32的重映射功能.查看手冊USART1可用外部連接有(PA9/TX,PA10/RX),(PB6/TX,PB7/RX). C8T6只有兩個,F411有三個,這樣一來就為PCB電路設計提供了方便.當然這個外設就需要要有個控制器去選擇到底將USART模塊映射到哪里.這個控制額模塊就是AFIO模塊.所以復用的時候需要查看是否重映射了,如果是的話,要將其配置好. 以上兩段說了三個關鍵詞,通用GPIO的通用,GPIO的復用,GPIO的重映射.還有配置的兩個步驟一打開GPIOA或者B...的時鐘,二確定是否重映射,確定好硬件連接. 接下來便是配置具體的引腳. 本次USART1有兩個,選擇了(PA9/TX,PA10/RX),確定了功能之后,要配置成輸入模式還是輸出模式當然也已經確定好了.但是輸入有浮空輸入,模擬輸入,上拉下拉到底選哪一個(輸入模式沒有復用功能的選擇),這個數據手冊里每一個外設模塊有,輸出也有.可以查看.至于速度的話,一般通信的引腳配置成最大的輸出速度,通用GPIO的時候配置成最小的速度即可,根據實際情況來. 這樣一來GPIO模塊就配置完成,配置的具體的代碼如下 void USART1_GPIO_Config() { RCC->APB2ENR |=(1<<2); //開啟GPIOA的時鐘 AFIO->MAPR &=~(1<<2); //UART1沒有重映像(TX/PA9,RX/PA10)
GPIOA->CRH |= (3<<4); //PA9配置為50MHz輸出模式 GPIOA->CRH |=(2<<6); //復用推挽輸出模式
GPIOA->CRH &= ~(3<<8); //PA10配置為輸入模式 GPIOA->CRH |=(1<<10); //浮空輸入模式模式 }
接下來就是配置USART模塊了,與GPIO模塊一樣也需要先打開USART1的時鐘,與GPIO模塊不同的是USART模塊在最后配置完成后還需要有個模塊使能.在配置完USART模塊的所有功能后需要將它使能.在我看來這是沒有必要的.時鐘都打開了,已經說明我要用這個模塊了,為什么還要使能這個模塊那,有些多余.,技術手冊上寫的是清零USART的輸出和分頻器禁止.分頻器禁止了,難道輸入還可以.我要試一試.如果可以的話,不算雞肋,否則就是無用; 一頭一尾的兩條語句說完,接下來就是USART的具體配置了.USART是同步異步通信,這里的功能用到的是全雙工的異步通信方式.所以沒有用到是時鐘,只需要兩根線就可以把實現他的通信. 其配置的步驟與其通信的格式有關.如數據位,校驗位,停止位的位數,還有發送和接收使能.還有波特率(計算.需要花費點功夫),具體代碼如下.
void USART1_Init(uint32_t bound) { float temp; u16 mantissa; u16 fraction;
USART1_GPIO_Config();
RCC->APB2ENR |=1<<14;//開啟UART1的時鐘
USART1->CR1 &= ~(1<<12);//一個起始位八個數據位 USART1->CR1 &= ~(1<<10);//禁止校驗位 USART1->CR2 &= ~(3<<12);//一個停止位
USART1->CR1 |=(1<<2);//接收使能 USART1->CR1 |=(1<<3);//發送使能
temp=(float)(72*1000000)/(bound*16); mantissa=temp; fraction=(temp-mantissa)*16; mantissa<<=4; mantissa += fraction; USART1->BRR=mantissa; //設置波特率
USART1->CR1 |= 1<<13;//使能USART模塊 } 至于重定向函數,上網上找到函數,只需要把庫函數改成寄存器函數即可,本質就是,printf調用fputc函數的時候,fputc把輸出的位置不定義到電腦屏幕,而是改變這個函數,把printf要輸出的的字符通過串口發送出去,打印到串口助手的屏幕上去.如下.
int fputc(int ch, FILE *f) {
USART1->DR = (unsigned char) ch; while((USART1->SR &(1<<7))==0); return(ch); }
|