0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

基于MM32L0130的LPUART应用(2)

灵动MM32MCU 来源:灵动MM32MCU 作者:灵动MM32MCU 2022-11-24 17:52 次阅读

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

上期介绍了MM32全新低功耗系列MM32L0130的LPUART外设,并实现了基本UART收发通信和使用LPUART唤醒MCU。本期介绍LPUART的高级应用,实现DMA收发实验、使用数据匹配寄存器匹配到指定字符后唤醒MCU。

1LPUART使用DMA

LPUART可以使用DMA来搬运数据,实现无需CPU参与的快速自动数据传输。硬件发出DMA请求与对应的DMA通道直连,也可以通过软件配置寄存器的方式触发DMA通道请求。LPUART的控制寄存器有对应的DMA使能位,如下图所示:

fbdf09b6-6bdc-11ed-8abf-dac502259ad0.png

1.1 DMA中断

DMA的每个通道都有三种中断事件标志:DMA半传输、DMA传输完成和DMA传输出错。各通道单独的中断请求由这3种事件标志逻辑或起来。可以配置寄存器的对应位来使能这些中断:

fc0d9858-6bdc-11ed-8abf-dac502259ad0.png

1.2 LPUART使用DMA的配置步骤

1根据基本UART配置步骤配置LPUART

2使能LPUEN的DMAR与DMAT位激活DMA模式

3使能DMA时钟

4发送需要配置DMA的源地址(存储器地址)和目的地址(LPUTXD),传输的数据量以及DMA通道

5配置完发送后,只要TXFIFO为空,就会请求DMA发送

6接收需要配置DMA的源地址(LPURXD)和目的地址(存储器地址),传输的数据量以及DMA通道

7配置完接收后,只要RXFIFO有数据,即不为空,就会请求DMA接收

1.3 功能代码实现

下面例程实现了使用DMA发送和接收LPUART数据,发送和接收完成后进入中断,例程在基本UART收发实验的基础上完成。

a.申请例程所用到的TX和RX缓存、TX和RX完成标志:

uint8_tTX_Buffer[16],RX_Buffer[16];
uint8_tTX_Complete=0,RX_Complete=0;

b.配置NVIC:

NVIC_InitTypeDefNVIC_InitStruct;
NVIC_InitStruct.NVIC_IRQChannel=DMA1_Channel2_3_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPriority=2;
NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_InitStruct);

c.配置DMA通道2为LPUART_TX:

voidLPUART_DMA_TX_Init(void)
{
DMA_InitTypeDefDMA_InitStruct;

RCC_DMA_ClockCmd(DMA1,ENABLE);
DMA_DeInit(DMA1_Channel2);
DMA_StructInit(&DMA_InitStruct);
//DMAtransferperipheraladdress
DMA_InitStruct.DMA_PeripheralBaseAddr=(uint32_t)&LPUART1->LPUTXD;
//DMAtransfermemoryaddress
DMA_InitStruct.DMA_MemoryBaseAddr=(uint32_t)TX_Buffer;
//DMAtransferdirectionfromperipheraltomemory
DMA_InitStruct.DMA_DIR=DMA_DIR_PeripheralDST;
//DMAcachesize
DMA_InitStruct.DMA_BufferSize=16;
//Theperipheraladdressisforbiddentomovebackward
DMA_InitStruct.DMA_PeripheralInc=DMA_PeripheralInc_Disable;
//Thememoryaddressisshiftedbackward
DMA_InitStruct.DMA_MemoryInc=DMA_MemoryInc_Enable;
//Definetheperipheraldatawidthto8bits
DMA_InitStruct.DMA_PeripheralDataSize=DMA_PeripheralDataSize_Byte;
DMA_InitStruct.DMA_MemoryDataSize=DMA_MemoryDataSize_Byte;
DMA_InitStruct.DMA_Mode=DMA_Mode_Normal;
DMA_InitStruct.DMA_Priority=DMA_Priority_Medium;
//M2Mmodeisdisabled
DMA_InitStruct.DMA_M2M=DMA_M2M_Disable;
DMA_InitStruct.DMA_Auto_reload=DMA_Auto_Reload_Disable;
DMA_Init(DMA1_Channel2,&DMA_InitStruct);
DMA_SetChannelMuxSource(DMA1_Channel2,DMA1_MUX_LPUART1_TX);
//EnableLPUART_DMA1_ChannelTransfercompleteinterrupt
DMA_ITConfig(DMA1_Channel2,DMA_IT_TC,ENABLE);
LPUART_TX_DMACmd(LPUART1,ENABLE);
while((LPUART1->LPUEN&LPUART_LPUEN_DMAT)==0);
//LPUART_DMA1_Channelenable
DMA_Cmd(DMA1_Channel2,ENABLE);
}

d.配置DMA通道3为LPUART_RX:

voidLPUART_DMA_RX_Init(void)
{
DMA_InitTypeDefDMA_InitStruct;

RCC_DMA_ClockCmd(DMA1,ENABLE);

DMA_DeInit(DMA1_Channel3);
DMA_StructInit(&DMA_InitStruct);
//DMAtransferperipheraladdress
DMA_InitStruct.DMA_PeripheralBaseAddr=(uint32_t)&LPUART1->LPURXD;
//DMAtransfermemoryaddress
DMA_InitStruct.DMA_MemoryBaseAddr=(uint32_t)RX_Buffer;
//DMAtransferdirectionfromperipheraltomemory
DMA_InitStruct.DMA_DIR=DMA_DIR_PeripheralSRC;
//DMAcachesize
DMA_InitStruct.DMA_BufferSize=16;
//Theperipheraladdressisforbiddentomovebackward
DMA_InitStruct.DMA_PeripheralInc=DMA_PeripheralInc_Disable;
//Thememoryaddressisshiftedbackward
DMA_InitStruct.DMA_MemoryInc=DMA_MemoryInc_Enable;
//Definetheperipheraldatawidthto8bits
DMA_InitStruct.DMA_PeripheralDataSize=DMA_PeripheralDataSize_Byte;
DMA_InitStruct.DMA_MemoryDataSize=DMA_MemoryDataSize_Byte;
DMA_InitStruct.DMA_Mode=DMA_Mode_Normal;
DMA_InitStruct.DMA_Priority=DMA_Priority_Medium;
//M2Mmodeisdisabled
DMA_InitStruct.DMA_M2M=DMA_M2M_Disable;
DMA_InitStruct.DMA_Auto_reload=DMA_Auto_Reload_Disable;
DMA_Init(DMA1_Channel3,&DMA_InitStruct);
DMA_SetChannelMuxSource(DMA1_Channel3,DMA1_MUX_LPUART1_RX);
//EnableLPUART_DMA1_ChannelTransfercompleteinterrupt
DMA_ITConfig(DMA1_Channel3,DMA_IT_TC,ENABLE);
LPUART_RX_DMACmd(LPUART1,ENABLE);
while((LPUART1->LPUEN&LPUART_LPUEN_DMAR)==0);
//LPUART_DMA1_Channelenable
DMA_Cmd(DMA1_Channel3,ENABLE);
}

e.编写中断服务函数:

voidDMA1_Channel2_3_IRQHandler(void)
{
if(DMA_GetITStatus(DMA1_IT_TC2))
{
DMA_ClearITPendingBit(DMA1_IT_TC2);
TX_Complete=1;
}
if(DMA_GetITStatus(DMA1_IT_TC3))
{
DMA_ClearITPendingBit(DMA1_IT_TC3);
RX_Complete=1;
}
}

f.编写实验样例:

voidLPUART_RxTx_DMA_Test(void)
{
uint8_ti;

for(i=0;i< 16; i++)
    {
        TX_Buffer[i] = i;
    }
    LPUART_DMA_TX_Init();
    LPUART_DMA_RX_Init();

    while(1)
    {
        if(TX_Complete == 1)
        {
            TX_Complete = 0;
            DMA1_Channel3->CMAR=(uint32_t)RX_Buffer;
DMA1_Channel3->CNDTR=16;
DMA_Cmd(DMA1_Channel3,ENABLE);
}
if(RX_Complete==1)
{
RX_Complete=0;
memcpy((void*)TX_Buffer,(void*)RX_Buffer,16);
DMA1_Channel2->CMAR=(uint32_t)TX_Buffer;
DMA1_Channel2->CNDTR=16;
DMA_Cmd(DMA1_Channel2,ENABLE);
}
}
}

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

fc20b6d6-6bdc-11ed-8abf-dac502259ad0.png

2使用数据匹配寄存器匹配到指定字符后唤醒MCU

为进一步降低系统功耗,MM32L0130系列的LPUART提供了一种接收到指定字符才能唤醒低功耗状态的MCU的功能。用于唤醒的指定字符,由数据匹配寄存器确定:

fc39390e-6bdc-11ed-8abf-dac502259ad0.png

2.1接收中断配置寄存器

可以通过LPUART的LPUCON.RXEV寄存器配置唤醒事件为START位、一帧接收完成、一帧数据匹配或者RXD下降沿唤醒。

fc61bea6-6bdc-11ed-8abf-dac502259ad0.png

2.2 功能代码实现

匹配指定字符唤醒MCU功能,需要在上期讲解的LPUART唤醒低功耗模式中的MCU基础上修改中断事件配置、指定唤醒字符,具体代码如下:

a.配置LPUART接收中断事件为接收数据匹配成功:

LPUART_InitTypeDefinit_struct;

init_struct.LPUART_Clock_Source=0;
init_struct.LPUART_BaudRate=LPUART_Baudrate_9600;
init_struct.LPUART_WordLength=LPUART_WordLength_8b;
init_struct.LPUART_StopBits=LPUART_StopBits_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_RecvData_Mactched;
LPUART_Init(LPUART1,&init_struct);

b.配置特定的唤醒字符:

LPUART_SetMatchData(LPUART1,‘5’);//指定字符’5’为唤醒字符

c.编写中断服务程序,判断接收匹配事件并清除标志:

voidLPUART1_IRQHandler()
{
if(LPUART_GetFlagStatus(LPUART1,LPUART_LPUSTA_START))
{
LPUART_ClearFlagStatus(LPUART1,LPUART_LPUSTA_START);
}
if(LPUART_GetFlagStatus(LPUART1,LPUART_LPUSTA_MATCH))
{//判断接收中断匹配事件
LPUART_ClearFlagStatus(LPUART1,LPUART_LPUSTA_MATCH);

}
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;
}
EXTI_ClearITPendingBit(EXTI_Line22);
}

d.编写试验样例:

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)
    {

    }
}

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

fc7c642c-6bdc-11ed-8abf-dac502259ad0.png

审核编辑:汤梓红
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • mcu
    mcu
    +关注

    关注

    146

    文章

    16023

    浏览量

    343710
  • 收发器
    +关注

    关注

    10

    文章

    2976

    浏览量

    104795
  • uart
    +关注

    关注

    22

    文章

    1159

    浏览量

    99982
  • dma
    dma
    +关注

    关注

    3

    文章

    536

    浏览量

    99072

原文标题:灵动微课堂 (第237讲)|基于MM32L0130的LPUART应用(2)

文章出处:【微信号:MindMotion-MMCU,微信公众号:灵动MM32MCU】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    基于MM32L0130LPUART应用(1)

    LPUART(Low power universal asynchronous receiver transmitter,低功耗通用异步收发器),相比标准的UART,其功耗极低,支持在低功耗模式下运行,并且可以将MCU从低功耗模式唤醒。
    的头像 发表于 11-18 10:35 2883次阅读
    基于<b class='flag-5'>MM32L0130</b>的<b class='flag-5'>LPUART</b>应用(1)

    使用MM32L0130 IRM实现红外发码

    1、使用MM32L0130 IRM实现红外发码  红外遥控是一种无线、非接触控制技术,具有抗干扰能力强,信息传输可靠,功耗低,成本低,易于实现等显著优点,被诸多电子设备包括消费电子、家用电器、安防
    发表于 10-21 14:22

    基于MM32L0130的低功耗电子时钟设计方案相关资料分享

    1、基于MM32L0130的低功耗电子时钟设计  MM32L0130作为灵动微电子推出的一款低功耗芯片,内置多种省电工作模式保证低功耗应用的要求。前面章节分别对MM32L0130片上外设SLCD
    发表于 11-09 16:00

    基于MM32L0130LPUART外设应用简介

    运行,并且可以将MCU从低功耗模式唤醒。本文介绍MM32全新低功耗系列MM32L0130LPUART外设,实现基本UART收发通信、通过UART中断使MCU从低功耗模式中唤醒。1 LPUAR
    发表于 12-09 16:04

    请问有人使用IAR进行过MM32L0130的开发吗?

    我在使用IAR8.30进行MM32L0130开发板试用时遇到了一个棘手的问题,其例程能够下载到开发板(至少在IAR中任何报错,也可以在线调试),可是就是一直开在时钟配置阶段,一直没有配置成功,有人遇到过这样的问题吗?或者在调试其他单片机时是否有类似现象?麻烦指导一下解决办法
    发表于 12-18 21:48

    使用MM32L0130片上IRM模块实现红外发码

    灵动股份推出的MM32L0130系列MCU具有片上IRM红外调制器,该模块使用片上的定时器和串口,实现数据的 FSK/ASK 调制,以满足红外发码的需求。
    的头像 发表于 10-13 17:03 946次阅读

    MM32L0130 RTC日历和闹钟

    RTC 模块是用于提供时间(时、分、秒、亚秒)和日期(年、月、日)功能的定时计数器,日历以 BCD码的格式显示。内部包含周期性的唤醒单元,用于唤醒低功耗模式。支持夏令时补偿,支持数字校准补偿晶振精度的偏差。灵动微电子推出的MM32L0130系列MCU片上RTC外设具有以下特征。
    的头像 发表于 10-28 10:37 955次阅读

    基于MM32L0130的低功耗电子时钟设计

    MM32L0130作为灵动微电子推出的一款低功耗芯片,内置多种省电工作模式保证低功耗应用的要求。前面章节分别对MM32L0130片上外设SLCD和RTC做了相关描述,并列举对应程序实现SLCD驱动
    的头像 发表于 11-04 10:12 1092次阅读

    MM32L0130 产品手册(中文版)

    MM32L0130 产品手册(中文版)
    发表于 02-27 18:24 0次下载
    <b class='flag-5'>MM32L0130</b> 产品手册(中文版)

    MM32L0130 产品手册(英文版)

    MM32L0130 产品手册(英文版)
    发表于 02-27 18:25 0次下载
    <b class='flag-5'>MM32L0130</b> 产品手册(英文版)

    MM32L0130 用户手册(中文版)

    MM32L0130 用户手册(中文版)
    发表于 02-27 18:26 0次下载
    <b class='flag-5'>MM32L0130</b> 用户手册(中文版)

    MM32L0130 用户手册(英文版)

    MM32L0130 用户手册(英文版)
    发表于 02-27 18:26 0次下载
    <b class='flag-5'>MM32L0130</b> 用户手册(英文版)

    基于MM32L0130LPUART应用(1)

    LPUART(Low power universal asynchronous receiver transmitter,低功耗通用异步收发器),相比标准的UART,其功耗极低,支持在低功耗模式下运行,并且可以将MCU从低功耗模式唤醒。
    的头像 发表于 06-02 17:27 766次阅读
    基于<b class='flag-5'>MM32L0130</b>的<b class='flag-5'>LPUART</b>应用(1)

    基于MM32L0130LPUART应用(2)

    LPUART(Low power universal asynchronous receiver transmitter,低功耗通用异步收发器),相比标准的UART,其功耗极低,支持在低功耗模式下运行,并且可以将MCU从低功耗模式唤醒。
    的头像 发表于 06-02 17:30 740次阅读
    基于<b class='flag-5'>MM32L0130</b>的<b class='flag-5'>LPUART</b>应用(2)

    使用MM32L0130和HYS1254的电子秤方案验证

    NPI提了需求,需要验证使用友商SDADC芯片和MM32L0130微控制器集成的一个系统应用方案。
    的头像 发表于 10-17 17:16 327次阅读
    使用<b class='flag-5'>MM32L0130</b>和HYS1254的电子秤方案验证