LPUART(Low power universal asynchronous receiver transmitter,低功耗通用異步收發器),相比標準的UART,其功耗極低,支持在低功耗模式下運行,并且可以將MCU從低功耗模式喚醒。
本文介紹MM32全新低功耗系列MM32L0130的LPUART外設,實現基本UART收發通信、通過UART中斷使MCU從低功耗模式中喚醒。
1LPUART 簡介
1.1 LPUART功能框圖
? ?
1.2 LPUART功能特征
支持UART幀格式的全雙工異步數據收發。
支持輸入任意頻率的時鐘源,可配置為LSE/LSI/PCLK。
支持可編程的波特率數據傳輸,發送和接收時可采用3、4分頻交替,防止累計誤差。
可配置奇偶校驗位、停止位。
可配置收發數據信號取反。
2LPUART時鐘配置
LPUART時鐘源配置寄存器在RCC_CFGR2中的位0和位1,可配置LSE、LSI、PCLK作為時鐘源。

3LPUART中斷與喚醒
支持的中斷源:
接收緩沖溢出
幀錯誤
奇偶校驗錯誤
接收器檢測到起始位
接收器檢測到下降沿
接收器完整接收 1byte 數據
接收器完整接收數據且與預設數據匹配
發送器數據完成發送
發送器緩沖空
支持低功耗模式下的喚醒源:
接收器檢測到下降沿喚醒
接收器檢測到起始位喚醒
接收器1字節接收完成喚醒
接收器1字節數據接收并匹配喚醒
4接收和發送時序
由于LPUART工作時鐘不是波特率的整數倍,采用固定分頻系數的話會引入累計誤差,所以在接收和發送的時候采用3、4分頻交替進行接收和發送,每個bit采樣一次,每個bit采用3分頻還是4分頻由MCTL寄存器控制,接收和發送時序圖如下:

當LPUART工作時鐘配置為標準的32.768KHz時,軟件可配置BREN為0,然后根據通信波特率調整調制寄存器MCTL,建議配置參數如下表:

5LPUART寄存器概覽

6LPUART實現普通UART功能配置步驟
1開啟LPUART所選時鐘源
2配置RCC_CFGR2寄存器選擇LPUART時鐘
3配置 LPUBAUD 寄存器決定波特率
4根據波特率選擇合適的調制參數,配置 MCTL 寄存器
5配置 LPUCON 寄存器,選擇幀格式、極性、中斷參數等
6配置 LPUEN 寄存器打開發送、接收使能
7發送和接收數據
發送數據:
將待發送的數據寫入LPUTXD,當發送完成時,LPUSTA的TXE標志位會被硬件置起,表示數據已傳入移位寄存器,發送 buffer為空。此時可往LPUTXD寫入下一個數據。軟件向發送buffer寫數據時TXE標志位自動清零。
接收數據:
當接收一個完整幀時,LPUSTA的RXF標志位置起,表示已完整接收數據,此時軟件可讀取LPURXD讀出接收到的數據。軟件讀LPUDATA寄存器時,RXF標志位自動清零。
8LPUART功能實現代碼
首先編寫基礎UART的代碼,通過輪詢的方式發送和接收數據。然后添加中斷代碼,實現通過LPUART將MCU從低功耗模式喚醒。
8.1 基于LSE時鐘的基礎UART功能實現代碼
a.開啟BKP、LSE時鐘,待LSE時鐘穩定,使能LPUART時鐘:
RCC_APB1PeriphClockCmd(RCC_APB1ENR_BKP,ENABLE); PWR_BackupAccessCmd(ENABLE); RCC_LSEConfig(RCC_LSE_ON); DELAY_Ms(100); while(RCC_GetFlagStatus(RCC_FLAG_LSERDY)==RESET){;} RCC_APB2PeriphClockCmd(RCC_APB2ENR_LPUART1,ENABLE);
b.配置LPUART的LPUART_InitTypeDef結構體參數:
LPUART_InitTypeDefinit_struct; init_struct.LPUART_Clock_Source=0;//時鐘源選擇 init_struct.LPUART_BaudRate=LPUART_Baudrate_9600;//波特率選擇9600 init_struct.LPUART_WordLength=LPUART_WordLength_8b;//8位數據位 init_struct.LPUART_StopBits=LPUART_StopBits_1;//1位停止位 init_struct.LPUART_Parity=LPUART_Parity_No;//沒有校驗位 init_struct.LPUART_MDU_Value=0x952;//波特率調制控制寄存器 init_struct.LPUART_NEDET_Source=LPUART_NegativeDectect_Source2;//下降沿采樣使能 init_struct.LPUART_RecvEventCfg=LPUART_RecvEvent_Start_Bit;//中斷檢測模式 LPUART_Init(LPUART1,&init_struct); LPUART_Cmd(LPUART1,ENABLE);
c.設置LPUART引腳復用,例程復用到PA4、PA5:
GPIO_InitTypeDefGPIO_InitStruct; RCC_GPIO_ClockCmd(GPIOA,ENABLE); GPIO_PinAFConfig(GPIOA,GPIO_PinSource4,GPIO_AF_3); GPIO_PinAFConfig(GPIOA,GPIO_PinSource5,GPIO_AF_3); //LPUART1_TXGPIOA.4 GPIO_StructInit(&GPIO_InitStruct); GPIO_InitStruct.GPIO_Pin=GPIO_Pin_4; GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz; GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF_PP; GPIO_Init(GPIOA,&GPIO_InitStruct); //LPUART1_RXGPIOA.5 GPIO_InitStruct.GPIO_Pin=GPIO_Pin_5; GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IPU; GPIO_Init(GPIOA,&GPIO_InitStruct);
d.編寫發送函數:
voidOutput_Byte(LPUART_TypeDef*lpuart,uint8_tdat)
{
LPUART_SendData(lpuart,dat);
while(!LPUART_GetFlagStatus(lpuart,LPUART_LPUSTA_TXE));
}
e.編寫輪詢接收函數:
uint8_tInput_Byte(LPUART_TypeDef*lpuart)
{
uint8_ttemp;
while(1){
if(LPUART_GetFlagStatus(lpuart,LPUART_LPUSTA_RXF)){
//readLPUART_LPUSTA_RXFbitandclear
temp=(uint8_t)LPUART_ReceiveData(lpuart);
break;
}
}
if(temp==0xd){
return0;
}
returntemp;
}
f.編寫實驗樣例:
voidLPUART_TxRx_Test(void)
{
uint8_ttemp,i;
charstring[]="LPUARTpollingtest!
";
for(i=0;i
g.在main函數中配置好LPUART后,調用LPUART_TxRx_Test函數,可得到如下實驗結果:

8.2 在上述基本LPUART配置的基礎上增加中斷配置代碼,實現喚醒低功耗模式中的MCU
a.開啟SYSCFG、PWR時鐘:
RCC_APB2PeriphClockCmd(RCC_APB2ENR_SYSCFG,ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1ENR_PWR,ENABLE);
b.EXTI模塊可以產生中斷請求,用來喚醒低功耗模式中的MCU,LPUART連接到EXTI22,使能EXTI22:
EXTI_InitTypeDefEXTI_InitStruct;
EXTI_StructInit(&EXTI_InitStruct);
EXTI_InitStruct.EXTI_Line=EXTI_Line22;
EXTI_InitStruct.EXTI_Mode=EXTI_Mode_Interrupt;
EXTI_InitStruct.EXTI_Trigger=EXTI_Trigger_Rising;
EXTI_InitStruct.EXTI_LineCmd=ENABLE;
EXTI_Init(&EXTI_InitStruct);
c.配置NVIC:
NVIC_InitTypeDefNVIC_InitStruct;
NVIC_InitStruct.NVIC_IRQChannel=LPUART1_IRQn;
NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;
NVIC_InitStruct.NVIC_IRQChannelPriority=1;
NVIC_Init(&NVIC_InitStruct);
d.清除接收標志并打開接收中斷:
LPUART_ClearITPendingBit(LPUART1,LPUART_LPUIF_RXIF);
LPUART_ITConfig(LPUART1,LPUART_LPUCON_RXIE,ENABLE);
e.定義RX緩存,然后編寫中斷服務函數:
charrxDataBuf[10],cnt=0;
uint8_tcnt_flag=0;
voidLPUART1_IRQHandler()
{
if(LPUART_GetFlagStatus(LPUART1,LPUART_LPUSTA_START))
{
LPUART_ClearFlagStatus(LPUART1,LPUART_LPUSTA_START);
}
if(LPUART_GetITStatus(LPUART1,LPUART_LPUIF_RXIF)==SET)
{
LPUART_ClearITPendingBit(LPUART1,LPUART_LPUIF_RXIF);
rxDataBuf[cnt]=LPUART_ReceiveData(LPUART1);
if(++cnt>=10)
{
cnt_flag=1;
cnt=0;
}
}
}
f.編寫實驗樣例:
voidLPUART_Wakeup_Test(void)
{
uint8_ttemp,i;
charstring1[]="LPUARTwakeupmcutest!
";
charstring2[]="mcustop!
";
charstring3[]="mcuwakeup!
";
for(i=0;i
g.在main函數中配置好LPUART后,調用實驗函數LPUART_Wakeup_Test,可以的到如下結果:

審核編輯:湯梓紅
-
mcu
+關注
關注
147文章
18925瀏覽量
398126 -
寄存器
+關注
關注
31文章
5608瀏覽量
129970 -
uart
+關注
關注
22文章
1314瀏覽量
106642 -
異步收發器
+關注
關注
0文章
37瀏覽量
11133 -
MM32
+關注
關注
1文章
108瀏覽量
1392
原文標題:靈動微課堂 (第236講)|基于MM32L0130的LPUART應用(1)
文章出處:【微信號:MindMotion-MMCU,微信公眾號:靈動MM32MCU】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
基于靈動MM32F0130微控制器的電子貨架標簽系統
?TE Connectivity L1/L5微型Splatch GNSS芯片天線技術解析
基于VL53L4CD的高精度ToF接近傳感器擴展板:X-NUCLEO-53L4A1 技術解析
ST VL53L7CX飛行時間傳感器與X-NUCLEO-53L7A1擴展板技術解析
RT Studio 創建 STM32G4xx的板子,LPUART1的初始化存在錯誤怎么解決?
rtt串口驅動對低功耗串口lpuart1不兼容怎么解決?
H743的LPUART1接收數據有時候出錯怎么解決?
為什么無法使用Lpuart_Uart_Ip_ 發送任何數據回調中的AsyncSend?
k32l2b31寫入LPUART1->STAT |= (1<<25)會導致semihost_hardfault是為什么?
FRDM-MCXA156 LPUART1不工作是哪里出了問題?
LPUART12 eDMA 在RT1176 CM7上不起作用的原因?
使用S32K322上的LPUART進行UART通信,接收超過14個字符時遇到問題,求解決
S32K344將LPUART6添加到Uart_example產生硬故障怎么解決?
NA150-220S36L1 NA150-220S36L1
基于MM32L0130的LPUART應用(1)
評論