
《《《《《正文》》》》》
?
《前言》
基于UART的串口在實際專案中的應用相當廣泛,包括wifi、can、lin等均可使用uart進行通信,方便且成本低;而uart串口功能不僅僅體現在產品使用功能上,在開發除錯階段更是一個必不可少的除錯助手,今天就來構建一個基于uart的除錯串口功能模塊;
開發需求:使用stm32f103的usart模塊開發一個具有發送任意字串的除錯串口功能的模塊;
相關代碼獲取地址:
https://pan.baidu.com/s/1zyrOF18WxIq0H3_4qU7Evg
關注公眾號,發送1234,獲取提取碼;
《硬體設計》
| TX | PA9 |
| RX | PA10 |

《加載USART庫檔案》



《軟體設計》
第一步:中斷等級配置函式
void NvicConfig(void){NVIC_InitTypeDef NVIC_InitStruct;?NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);?NVIC_InitStruct.NVIC_IRQChannel=USART1_IRQn; //USART中斷通道NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=2; //設定搶占優先級為0NVIC_InitStruct.NVIC_IRQChannelSubPriority=1; //設定子優先級為1NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE; //使能外USART中斷通道NVIC_Init(&NVIC_InitStruct); //中斷優先級初始化函式}
第二步:串口初始化函式
//傳入引數為波特率void USART_init(uint32_t baudrate){GPIO_InitTypeDef GPIO_InitStruct; //定義GPIO結構體變數USART_InitTypeDef USART_InitStruct; //定義串口結構體變數?RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_USART1,ENABLE); //使能GPIOA、USART1的時鐘?GPIO_InitStruct.GPIO_Pin=GPIO_Pin_9; //配置TX引腳GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF_PP; //配置PA9為復用推挽輸出GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz; //配置PA9速率GPIO_Init(GPIOA,&GPIO_InitStruct); //GPIO初始化函式?GPIO_InitStruct.GPIO_Pin=GPIO_Pin_10; //配置RX引腳GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IN_FLOATING; //配置PA10為浮空輸入GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz; //配置PA10速率GPIO_Init(GPIOA,&GPIO_InitStruct); //GPIO初始化函式?USART_InitStruct.USART_Mode=USART_Mode_Tx|USART_Mode_Rx; //發送接收模式USART_InitStruct.USART_Parity=USART_Parity_No; //無奇偶校驗USART_InitStruct.USART_BaudRate=baudrate; //波特率USART_InitStruct.USART_StopBits=USART_StopBits_1; //停止位1位USART_InitStruct.USART_WordLength=USART_WordLength_8b; //字長8位USART_InitStruct.USART_HardwareFlowControl=USART_HardwareFlowControl_None; //無硬體資料流控制USART_Init(USART1,&USART_InitStruct); //串口初始化函式?USART_ITConfig(USART1,USART_IT_RXNE,ENABLE); //串口接收中斷USART_ITConfig(USART1,USART_IT_IDLE,ENABLE); //串口空閑中斷?USART_Cmd(USART1,ENABLE); //使能USART1}
第三步:中斷處理函式
void USART1_IRQHandler(void){uint8_t clear = clear; //定義這個變數是針對編譯出現“沒有用到這個變數”的警告提示uint8_t res;?if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //接收中斷{res = USART1->DR;//在此做資料接收處理}else if(USART_GetITStatus(USART1, USART_IT_IDLE) != RESET) //空閑中斷{clear = USART1->SR; //讀SR暫存器clear = USART1->DR; //讀DR暫存器(先讀SR,再度DR,就是為了清除IDIE中斷)}USART_ClearITPendingBit(USART1,USART_IT_RXNE);}
第四步:寫發送資料函式
void usart_send(uint8_t *data,uint8_t len){uint8_t i;?for(i=0;i<len;i++){USART_SendData(USART1,*(data+i));while(USART_GetFlagStatus(USART1,USART_FLAG_TC) == RESET);}}
第五步:來個簡單的測驗,主函式:
int main(void){uint8_t usartSendbuf[5] = {1,2,3,4,5};NvicConfig();USART_init(115200);?for(;;){usart_send(usartSendbuf,5);}}
結果:

《printf函式重定向》
重定向函式:
int fputc(int ch,FILE *f) //printf重定向函式{USART_SendData(USART1,(uint8_t)ch); //發送一位元組資料while(USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET); //等待發送完成return ch;}
我們這里直接寫是不行,因為這是C庫自帶的東西,但是可以重定向到這個函式(printf()在c標準庫函式實質是一個宏,實際是呼叫fputc()函式),fputc()函式默認是把字符輸出到除錯器控制視窗,所以要想把資料通過USART輸出到串口助手,需對基于fputc()的printf()系列函式的輸出重定向到USART埠上去,
這里特別注意:打開“Options for target...”->“target”勾選“Use MiclroLIB” 不然用printf會有問題;

最后上測驗函式:
int main(void){NvicConfig();USART_init(115200);?for(;;){printf("System Init Finish\n");printf("我正在測驗\n");}}
結果:

《《《《《END》》》》》

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/277744.html
標籤:其他
