LPUART(Low power universal asynchronous receiver transmitter,低功耗通用異步收發(fā)器),相比標(biāo)準(zhǔn)的UART,其功耗極低,支持在低功耗模式下運(yùn)行,并且可以將MCU從低功耗模式喚醒。
本文介紹MM32全新低功耗系列MM32L0130的LPUART外設(shè),實(shí)現(xiàn)基本UART收發(fā)通信、通過UART中斷使MCU從低功耗模式中喚醒。
1LPUART 簡介
1.1 LPUART功能框圖
? ?
1.2 LPUART功能特征
支持UART幀格式的全雙工異步數(shù)據(jù)收發(fā)。
支持輸入任意頻率的時(shí)鐘源,可配置為LSE/LSI/PCLK。
支持可編程的波特率數(shù)據(jù)傳輸,發(fā)送和接收時(shí)可采用3、4分頻交替,防止累計(jì)誤差。
可配置奇偶校驗(yàn)位、停止位。
可配置收發(fā)數(shù)據(jù)信號取反。
2LPUART時(shí)鐘配置
LPUART時(shí)鐘源配置寄存器在RCC_CFGR2中的位0和位1,可配置LSE、LSI、PCLK作為時(shí)鐘源。
3LPUART中斷與喚醒
支持的中斷源:
接收緩沖溢出
幀錯(cuò)誤
奇偶校驗(yàn)錯(cuò)誤
接收器檢測到下降沿
接收器完整接收 1byte 數(shù)據(jù)
接收器完整接收數(shù)據(jù)且與預(yù)設(shè)數(shù)據(jù)匹配
發(fā)送器數(shù)據(jù)完成發(fā)送
發(fā)送器緩沖空
支持低功耗模式下的喚醒源:
接收器檢測到下降沿喚醒
接收器檢測到起始位喚醒
接收器1字節(jié)接收完成喚醒
接收器1字節(jié)數(shù)據(jù)接收并匹配喚醒
4接收和發(fā)送時(shí)序
由于LPUART工作時(shí)鐘不是波特率的整數(shù)倍,采用固定分頻系數(shù)的話會(huì)引入累計(jì)誤差,所以在接收和發(fā)送的時(shí)候采用3、4分頻交替進(jìn)行接收和發(fā)送,每個(gè)bit采樣一次,每個(gè)bit采用3分頻還是4分頻由MCTL寄存器控制,接收和發(fā)送時(shí)序圖如下:
當(dāng)LPUART工作時(shí)鐘配置為標(biāo)準(zhǔn)的32.768KHz時(shí),軟件可配置BREN為0,然后根據(jù)通信波特率調(diào)整調(diào)制寄存器MCTL,建議配置參數(shù)如下表:
5LPUART寄存器概覽
6LPUART實(shí)現(xiàn)普通UART功能配置步驟
1開啟LPUART所選時(shí)鐘源
2配置RCC_CFGR2寄存器選擇LPUART時(shí)鐘
3配置 LPUBAUD 寄存器決定波特率
4根據(jù)波特率選擇合適的調(diào)制參數(shù),配置 MCTL 寄存器
5配置 LPUCON 寄存器,選擇幀格式、極性、中斷參數(shù)等
6配置 LPUEN 寄存器打開發(fā)送、接收使能
7發(fā)送和接收數(shù)據(jù)
發(fā)送數(shù)據(jù):
將待發(fā)送的數(shù)據(jù)寫入LPUTXD,當(dāng)發(fā)送完成時(shí),LPUSTA的TXE標(biāo)志位會(huì)被硬件置起,表示數(shù)據(jù)已傳入移位寄存器,發(fā)送 buffer為空。此時(shí)可往LPUTXD寫入下一個(gè)數(shù)據(jù)。軟件向發(fā)送buffer寫數(shù)據(jù)時(shí)TXE標(biāo)志位自動(dòng)清零。
接收數(shù)據(jù):
當(dāng)接收一個(gè)完整幀時(shí),LPUSTA的RXF標(biāo)志位置起,表示已完整接收數(shù)據(jù),此時(shí)軟件可讀取LPURXD讀出接收到的數(shù)據(jù)。軟件讀LPUDATA寄存器時(shí),RXF標(biāo)志位自動(dòng)清零。
8LPUART功能實(shí)現(xiàn)代碼
首先編寫基礎(chǔ)UART的代碼,通過輪詢的方式發(fā)送和接收數(shù)據(jù)。然后添加中斷代碼,實(shí)現(xiàn)通過LPUART將MCU從低功耗模式喚醒。
8.1 基于LSE時(shí)鐘的基礎(chǔ)UART功能實(shí)現(xiàn)代碼
a.開啟BKP、LSE時(shí)鐘,待LSE時(shí)鐘穩(wěn)定,使能LPUART時(shí)鐘:
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結(jié)構(gòu)體參數(shù):
LPUART_InitTypeDefinit_struct; init_struct.LPUART_Clock_Source=0;//時(shí)鐘源選擇 init_struct.LPUART_BaudRate=LPUART_Baudrate_9600;//波特率選擇9600 init_struct.LPUART_WordLength=LPUART_WordLength_8b;//8位數(shù)據(jù)位 init_struct.LPUART_StopBits=LPUART_StopBits_1;//1位停止位 init_struct.LPUART_Parity=LPUART_Parity_No;//沒有校驗(yàn)位 init_struct.LPUART_MDU_Value=0x952;//波特率調(diào)制控制寄存器 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.設(shè)置LPUART引腳復(fù)用,例程復(fù)用到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.編寫發(fā)送函數(shù):
voidOutput_Byte(LPUART_TypeDef*lpuart,uint8_tdat) { LPUART_SendData(lpuart,dat); while(!LPUART_GetFlagStatus(lpuart,LPUART_LPUSTA_TXE)); }
e.編寫輪詢接收函數(shù):
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.編寫實(shí)驗(yàn)樣例:
voidLPUART_TxRx_Test(void) { uint8_ttemp,i; charstring[]="LPUARTpollingtest! "; for(i=0;i
g.在main函數(shù)中配置好LPUART后,調(diào)用LPUART_TxRx_Test函數(shù),可得到如下實(shí)驗(yàn)結(jié)果:
8.2 在上述基本LPUART配置的基礎(chǔ)上增加中斷配置代碼,實(shí)現(xiàn)喚醒低功耗模式中的MCU
a.開啟SYSCFG、PWR時(shí)鐘:
RCC_APB2PeriphClockCmd(RCC_APB2ENR_SYSCFG,ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1ENR_PWR,ENABLE);
b.EXTI模塊可以產(chǎn)生中斷請求,用來喚醒低功耗模式中的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.清除接收標(biāo)志并打開接收中斷:
LPUART_ClearITPendingBit(LPUART1,LPUART_LPUIF_RXIF); LPUART_ITConfig(LPUART1,LPUART_LPUCON_RXIE,ENABLE);
e.定義RX緩存,然后編寫中斷服務(wù)函數(shù):
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.編寫實(shí)驗(yàn)樣例:
voidLPUART_Wakeup_Test(void) { uint8_ttemp,i; charstring1[]="LPUARTwakeupmcutest! "; charstring2[]="mcustop! "; charstring3[]="mcuwakeup! "; for(i=0;i
g.在main函數(shù)中配置好LPUART后,調(diào)用實(shí)驗(yàn)函數(shù)LPUART_Wakeup_Test,可以的到如下結(jié)果:
審核編輯:湯梓紅
-
mcu
+關(guān)注
關(guān)注
146文章
17171瀏覽量
351481 -
寄存器
+關(guān)注
關(guān)注
31文章
5355瀏覽量
120531 -
uart
+關(guān)注
關(guān)注
22文章
1237瀏覽量
101447 -
異步收發(fā)器
+關(guān)注
關(guān)注
0文章
36瀏覽量
10855 -
MM32
+關(guān)注
關(guān)注
1文章
106瀏覽量
777
原文標(biāo)題:靈動(dòng)微課堂 (第236講)|基于MM32L0130的LPUART應(yīng)用(1)
文章出處:【微信號:MindMotion-MMCU,微信公眾號:靈動(dòng)MM32MCU】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
評論