首页 > 技术知识 > 正文

LPUART(Low power universal asynchronous receiver transmitter,低功耗通用异步收发器),相比标准的UART,其功耗极低,支持在低功耗模式下运行,并且可以将MCU从低功耗模式唤醒。

本文介绍MM32全新低功耗系列MM32L0130的LPUART外设,实现基本UART收发通信、通过UART中断使MCU从低功耗模式中唤醒。

1LPUART 简介

1.1 LPUART功能框图

基于MM32L0130的LPUART应用(1)-基于个人同意处理个人信息的,该同意应当由个人

1.2 LPUART功能特征

支持UART帧格式的全双工异步数据收发。

支持输入任意频率的时钟源,可配置为LSE/LSI/PCLK。

支持可编程的波特率数据传输,发送和接收时可采用3、4分频交替,防止累计误差。

可配置奇偶校验位、停止位。

可配置收发数据信号取反。

2LPUART时钟配置

LPUART时钟源配置寄存器在RCC_CFGR2中的位0和位1,可配置LSE、LSI、PCLK作为时钟源。

基于MM32L0130的LPUART应用(1)-基于个人同意处理个人信息的,该同意应当由个人1

3LPUART中断与唤醒

支持的中断源:

接收缓冲溢出

帧错误

奇偶校验错误

接收器检测到起始位

接收器检测到下降沿

接收器完整接收 1byte 数据

接收器完整接收数据且与预设数据匹配

发送器数据完成发送

发送器缓冲空

支持低功耗模式下的唤醒源:

接收器检测到下降沿唤醒

接收器检测到起始位唤醒

接收器1字节接收完成唤醒

接收器1字节数据接收并匹配唤醒

4接收和发送时序

由于LPUART工作时钟不是波特率的整数倍,采用固定分频系数的话会引入累计误差,所以在接收和发送的时候采用3、4分频交替进行接收和发送,每个bit采样一次,每个bit采用3分频还是4分频由MCTL寄存器控制,接收和发送时序图如下:

基于MM32L0130的LPUART应用(1)-基于个人同意处理个人信息的,该同意应当由个人2

当LPUART工作时钟配置为标准的32.768KHz时,软件可配置BREN为0,然后根据通信波特率调整调制寄存器MCTL,建议配置参数如下表:

基于MM32L0130的LPUART应用(1)-基于个人同意处理个人信息的,该同意应当由个人3

5LPUART寄存器概览

基于MM32L0130的LPUART应用(1)-基于个人同意处理个人信息的,该同意应当由个人4

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< strlen(string); i++)     {         Output_Byte(LPUART1, string[i]);     }     while(1)     {         temp = Input_Byte(LPUART1);         if(temp != 0)         {             Output_Byte(LPUART1, temp);         }     } }

g.在main函数中配置好LPUART后,调用LPUART_TxRx_Test函数,可得到如下实验结果:

基于MM32L0130的LPUART应用(1)-基于个人同意处理个人信息的,该同意应当由个人5

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< strlen(string1); i++)     {         Output_Byte(LPUART1, string1[i]);     }     DELAY_Ms(20);     for(i = 0; i < strlen(string2); i++)     {         Output_Byte(LPUART1, string2[i]);     }     PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI);//休眠     for(i = 0; i < strlen(string3); i++)     {         Output_Byte(LPUART1, string3[i]);     }     while(1)     {     } }

g.在main函数中配置好LPUART后,调用实验函数LPUART_Wakeup_Test,可以的到如下结果:

基于MM32L0130的LPUART应用(1)-基于个人同意处理个人信息的,该同意应当由个人6

审核编辑:汤梓红

猜你喜欢