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ā)通信和使用LPUART喚醒MCU。本期介紹LPUART的高級(jí)應(yīng)用,實(shí)現(xiàn)DMA收發(fā)實(shí)驗(yàn)、使用數(shù)據(jù)匹配寄存器匹配到指定字符后喚醒MCU。
1LPUART使用DMA
LPUART可以使用DMA來(lái)搬運(yùn)數(shù)據(jù),實(shí)現(xiàn)無(wú)需CPU參與的快速自動(dòng)數(shù)據(jù)傳輸。硬件發(fā)出DMA請(qǐng)求與對(duì)應(yīng)的DMA通道直連,也可以通過(guò)軟件配置寄存器的方式觸發(fā)DMA通道請(qǐng)求。LPUART的控制寄存器有對(duì)應(yīng)的DMA使能位,如下圖所示:
1.1 DMA中斷
DMA的每個(gè)通道都有三種中斷事件標(biāo)志:DMA半傳輸、DMA傳輸完成和DMA傳輸出錯(cuò)。各通道單獨(dú)的中斷請(qǐng)求由這3種事件標(biāo)志邏輯或起來(lái)??梢耘渲眉拇嫫鞯膶?duì)應(yīng)位來(lái)使能這些中斷:
1.2 LPUART使用DMA的配置步驟
1根據(jù)基本UART配置步驟配置LPUART
2使能LPUEN的DMAR與DMAT位激活DMA模式
3使能DMA時(shí)鐘
4發(fā)送需要配置DMA的源地址(存儲(chǔ)器地址)和目的地址(LPUTXD),傳輸?shù)臄?shù)據(jù)量以及DMA通道
5配置完發(fā)送后,只要TXFIFO為空,就會(huì)請(qǐng)求DMA發(fā)送
6接收需要配置DMA的源地址(LPURXD)和目的地址(存儲(chǔ)器地址),傳輸?shù)臄?shù)據(jù)量以及DMA通道
7配置完接收后,只要RXFIFO有數(shù)據(jù),即不為空,就會(huì)請(qǐng)求DMA接收
1.3 功能代碼實(shí)現(xiàn)
下面例程實(shí)現(xiàn)了使用DMA發(fā)送和接收LPUART數(shù)據(jù),發(fā)送和接收完成后進(jìn)入中斷,例程在基本UART收發(fā)實(shí)驗(yàn)的基礎(chǔ)上完成。
a.申請(qǐng)例程所用到的TX和RX緩存、TX和RX完成標(biāo)志:
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為L(zhǎng)PUART_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為L(zhǎng)PUART_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.編寫(xiě)中斷服務(wù)函數(shù):
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.編寫(xiě)實(shí)驗(yàn)樣例:
voidLPUART_RxTx_DMA_Test(void) { uint8_ti; for(i=0;i16;?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函數(shù)中配置好LPUART和DMA后,調(diào)用實(shí)驗(yàn)函數(shù)LPUART_RxTx_DMA_Test,可以得到如下結(jié)果:
2使用數(shù)據(jù)匹配寄存器匹配到指定字符后喚醒MCU
為進(jìn)一步降低系統(tǒng)功耗,MM32L0130系列的LPUART提供了一種接收到指定字符才能喚醒低功耗狀態(tài)的MCU的功能。用于喚醒的指定字符,由數(shù)據(jù)匹配寄存器確定:
2.1接收中斷配置寄存器
可以通過(guò)LPUART的LPUCON.RXEV寄存器配置喚醒事件為START位、一幀接收完成、一幀數(shù)據(jù)匹配或者RXD下降沿喚醒。
2.2 功能代碼實(shí)現(xiàn)
匹配指定字符喚醒MCU功能,需要在上期講解的LPUART喚醒低功耗模式中的MCU基礎(chǔ)上修改中斷事件配置、指定喚醒字符,具體代碼如下:
a.配置LPUART接收中斷事件為接收數(shù)據(jù)匹配成功:
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.編寫(xiě)中斷服務(wù)程序,判斷接收匹配事件并清除標(biāo)志:
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.編寫(xiě)試驗(yàn)樣例:
voidLPUART_Wakeup_Test(void) { uint8_ttemp,i; charstring1[]="LPUARTwakeupmcutest! "; charstring2[]="mcustop! "; charstring3[]="mcuwakeup! "; for(i=0;i
e.在main函數(shù)配置好LPUART后,調(diào)用實(shí)驗(yàn)函數(shù)LPUART_Wakeup_Test,可以得到如下結(jié)果:
審核編輯:湯梓紅
-
mcu
+關(guān)注
關(guān)注
146文章
17355瀏覽量
352788 -
收發(fā)器
+關(guān)注
關(guān)注
10文章
3468瀏覽量
106280 -
uart
+關(guān)注
關(guān)注
22文章
1245瀏覽量
101813 -
dma
+關(guān)注
關(guān)注
3文章
566瀏覽量
101019
原文標(biāo)題:靈動(dòng)微課堂 (第237講)|基于MM32L0130的LPUART應(yīng)用(2)
文章出處:【微信號(hào):MindMotion-MMCU,微信公眾號(hào):靈動(dòng)MM32MCU】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
基于MM32L0130的LPUART應(yīng)用(1)
![基于<b class='flag-5'>MM32L0130</b>的<b class='flag-5'>LPUART</b>應(yīng)用(1)](https://file.elecfans.com/web2/M00/7C/6D/pYYBAGN2--SAI32KAABC-lgLNuk190.png)
使用MM32L0130 IRM實(shí)現(xiàn)紅外發(fā)碼
基于MM32L0130的低功耗電子時(shí)鐘設(shè)計(jì)方案相關(guān)資料分享
基于MM32L0130的LPUART外設(shè)應(yīng)用簡(jiǎn)介
請(qǐng)問(wèn)有人使用IAR進(jìn)行過(guò)MM32L0130的開(kāi)發(fā)嗎?
使用MM32L0130片上IRM模塊實(shí)現(xiàn)紅外發(fā)碼
MM32L0130 RTC日歷和鬧鐘
基于MM32L0130的低功耗電子時(shí)鐘設(shè)計(jì)
基于MM32L0130的LPUART應(yīng)用(1)
![基于<b class='flag-5'>MM32L0130</b>的<b class='flag-5'>LPUART</b>應(yīng)用(1)](https://file1.elecfans.com/web2/M00/89/25/wKgZomR5tfaADD-JAALIntacw7w230.jpg)
基于MM32L0130的LPUART應(yīng)用(2)
![基于<b class='flag-5'>MM32L0130</b>的<b class='flag-5'>LPUART</b>應(yīng)用(<b class='flag-5'>2</b>)](https://file1.elecfans.com/web2/M00/89/25/wKgZomR5tpSAKF1iAAT2_iIp5GE462.jpg)
使用MM32L0130和HYS1254的電子秤方案驗(yàn)證
![使用<b class='flag-5'>MM32L0130</b>和HYS1254的電子秤方案驗(yàn)證](https://file1.elecfans.com/web2/M00/AA/66/wKgZomUuUISALETlAAPtXd_8wR0443.jpg)
評(píng)論