使用stm32cubemx開(kāi)發(fā)四:串口標(biāo)準(zhǔn)化輸出
掃描二維碼
隨時(shí)隨地手機(jī)看文章
硬件平臺(tái):stm32F407Zet6
軟件平臺(tái):stm32cubeMX 4.7+MDK5.14
電路連接:PA9,PA10
第一步、通過(guò)Stm32CubeMX圖形界面創(chuàng)建Keil工程
需要配置的地方是
在這里可以修改串口工作的一下參數(shù),軟件就可以生成配置好的工程,不需要親自去配置這些了。
第二步。打開(kāi)工程,編寫(xiě)代碼,驗(yàn)證
#include"stdio.h"
#ifdef__GNUC__
#definePUTCHAR_PROTOTYPEint__io_putchar(intch)
#else
#definePUTCHAR_PROTOTYPEintfputc(intch,FILE*f)
#endif
PUTCHAR_PROTOTYPE
{
HAL_UART_Transmit(&huart1,(uint8_t*)&ch,1,0xFFFF);
returnch;
}
這段程序?yàn)榱丝梢允褂胮rintf()函數(shù),對(duì)字符輸出函數(shù)進(jìn)行了重定向,這樣我們就可以在程序中使用printf函數(shù)進(jìn)行輸出了,這里使用的是查詢發(fā)送方式,有超時(shí)控制的。接下來(lái)來(lái)看中斷方式的。
voidHAL_UART_IRQHandler(UART_HandleTypeDef*huart)
{
uint32_ttmp1=0,tmp2=0;
tmp1=__HAL_UART_GET_FLAG(huart,UART_FLAG_PE);
tmp2=__HAL_UART_GET_IT_SOURCE(huart,UART_IT_PE);
if((tmp1!=RESET)&&(tmp2!=RESET))
{
__HAL_UART_CLEAR_PEFLAG(huart);
huart->ErrorCode|=HAL_UART_ERROR_PE;
}
tmp1=__HAL_UART_GET_FLAG(huart,UART_FLAG_FE);
tmp2=__HAL_UART_GET_IT_SOURCE(huart,UART_IT_ERR);
if((tmp1!=RESET)&&(tmp2!=RESET))
{
__HAL_UART_CLEAR_FEFLAG(huart);
huart->ErrorCode|=HAL_UART_ERROR_FE;
}
tmp1=__HAL_UART_GET_FLAG(huart,UART_FLAG_NE);
tmp2=__HAL_UART_GET_IT_SOURCE(huart,UART_IT_ERR);
if((tmp1!=RESET)&&(tmp2!=RESET))
{
__HAL_UART_CLEAR_NEFLAG(huart);
huart->ErrorCode|=HAL_UART_ERROR_NE;
}
tmp1=__HAL_UART_GET_FLAG(huart,UART_FLAG_ORE);
tmp2=__HAL_UART_GET_IT_SOURCE(huart,UART_IT_ERR);
if((tmp1!=RESET)&&(tmp2!=RESET))
{
__HAL_UART_CLEAR_OREFLAG(huart);
huart->ErrorCode|=HAL_UART_ERROR_ORE;
}
tmp1=__HAL_UART_GET_FLAG(huart,UART_FLAG_RXNE);
tmp2=__HAL_UART_GET_IT_SOURCE(huart,UART_IT_RXNE);
if((tmp1!=RESET)&&(tmp2!=RESET))
{
UART_Receive_IT(huart);
}
tmp1=__HAL_UART_GET_FLAG(huart,UART_FLAG_TXE);
tmp2=__HAL_UART_GET_IT_SOURCE(huart,UART_IT_TXE);
if((tmp1!=RESET)&&(tmp2!=RESET))
{
UART_Transmit_IT(huart);
}
tmp1=__HAL_UART_GET_FLAG(huart,UART_FLAG_TC);
tmp2=__HAL_UART_GET_IT_SOURCE(huart,UART_IT_TC);
if((tmp1!=RESET)&&(tmp2!=RESET))
{
UART_EndTransmit_IT(huart);
}
if(huart->ErrorCode!=HAL_UART_ERROR_NONE)
{
huart->State=HAL_UART_STATE_READY;
HAL_UART_ErrorCallback(huart);
}
}
這個(gè)函數(shù)中查詢了所有可能發(fā)生的中斷。用到的中斷是發(fā)送完成中斷,就找到了UART_EndTransmit_IT(huart);再跳進(jìn)去看看,
staticHAL_StatusTypeDefUART_EndTransmit_IT(UART_HandleTypeDef*huart)
{
__HAL_UART_DISABLE_IT(huart,UART_IT_TC);
if(huart->State==HAL_UART_STATE_BUSY_TX_RX)
{
huart->State=HAL_UART_STATE_BUSY_RX;
}
else
{
__HAL_UART_DISABLE_IT(huart,UART_IT_PE);
__HAL_UART_DISABLE_IT(huart,UART_IT_ERR);
huart->State=HAL_UART_STATE_READY;
}
HAL_UART_TxCpltCallback(huart);
returnHAL_OK;
}
這個(gè)函數(shù)在確定中斷發(fā)生了之后調(diào)用了,HAL_UART_TxCpltCallback(huart);從函數(shù)名上可以看出,這是個(gè)回調(diào)函數(shù),就是留給上層來(lái)實(shí)現(xiàn)的函數(shù),由這個(gè)函數(shù)的實(shí)現(xiàn)不同,來(lái)實(shí)現(xiàn)不同的功能。這里來(lái)實(shí)現(xiàn)這個(gè)函數(shù),讓它在中斷發(fā)生的時(shí)候吧USART1Ready置為SET;代碼修改如下
#include"stdio.h"
#ifdef__GNUC__
#definePUTCHAR_PROTOTYPEint__io_putchar(intch)
#else
#definePUTCHAR_PROTOTYPEintfputc(intch,FILE*f)
#endif
__IOITStatusUSART1Ready=RESET;
PUTCHAR_PROTOTYPE
{
HAL_UART_Transmit_IT(&huart1,(uint8_t*)&ch,1);
while(USART1Ready!=SET)
{
}
USART1Ready=RESET;
returnch;
}
這是重定向函數(shù)的修改,啟動(dòng)發(fā)送之后,等待發(fā)送完成。重新實(shí)現(xiàn)的回調(diào)函數(shù)如下圖所示:
voidHAL_UART_TxCpltCallback(UART_HandleTypeDef*huart)
{
USART1Ready=SET;
}
這樣就可以了,下載驗(yàn)證。