【GD32L233C-START评测】19、低功耗串口(深度休眠唤醒、空闲中断不定长数据接收)
<p>相关文章:</p><p><a href="https://bbs.eeworld.com.cn/thread-1192456-1-1.html" target="_blank">【GD32L233C-START评测】1、优点与缺点都很明显的GD32L233C-START(开箱)</a></p>
<p><a href="https://bbs.eeworld.com.cn/thread-1192706-1-1.html" target="_blank">【GD32L233C-START评测】2、非阻塞方式点灯,blink,blink,blink……</a></p>
<p><a href="https://bbs.eeworld.com.cn/thread-1192810-1-1.html" target="_blank">【GD32L233C-START评测】3、pwm实现呼吸灯</a></p>
<p><a href="https://bbs.eeworld.com.cn/thread-1192835-1-1.html" target="_blank">【GD32L233C-START评测】4、串口不定长数据接收</a></p>
<p><a href="https://bbs.eeworld.com.cn/thread-1192861-1-1.html" target="_blank">【GD32L233C-START评测】5、Flash读写——使用内部Flash存储数据</a></p>
<p><a href="https://bbs.eeworld.com.cn/thread-1192917-1-1.html" target="_blank">【GD32L233C-START评测】6、硬件I2C驱动0.96吋OLED</a></p>
<p><a href="https://bbs.eeworld.com.cn/forum.php?mod=viewthread&tid=1193325&pid=3120335&page=1&extra=#pid3120335" target="_blank">【GD32L233C-START评测】7、硬件SPI1驱动RC522</a></p>
<p><a href="https://bbs.eeworld.com.cn/thread-1192936-1-1.html" target="_blank">【GD32L233C-START评测】8、获取MCU96位唯一ID、SRAM、FLASH大小</a></p>
<p><a href="https://bbs.eeworld.com.cn/thread-1192994-1-1.html" target="_blank">【GD32L233C-START评测】9、IAP程序升级——基于YMODEM协议</a></p>
<p><a href="https://bbs.eeworld.com.cn/thread-1193073-1-1.html" target="_blank">【GD32L233C-START评测】10、使用内部参考电压校准adc,adc采样更准确</a></p>
<p><a href="https://bbs.eeworld.com.cn/thread-1193079-1-1.html" target="_blank">【GD32L233C-START评测】11、GD32 ISP软件还不支持GD32L233</a></p>
<p><a href="https://bbs.eeworld.com.cn/thread-1193152-1-1.html" target="_blank">【GD32L233C-START评测】12、按键——外部中断</a></p>
<p><a href="https://bbs.eeworld.com.cn/thread-1193187-1-1.html" target="_blank">【GD32L233C-START评测】13、I2C驱动环境光和接近传感器RPR-0521RS</a></p>
<p><a href="https://bbs.eeworld.com.cn/thread-1193224-1-1.html" target="_blank">【GD32L233C-START评测】14、RT-Thread移植到GD32L233(内核,finsh移植)</a></p>
<p><a href="https://bbs.eeworld.com.cn/thread-1193244-1-1.html" target="_blank">【GD32L233C-START</a><a href="https://bbs.eeworld.com.cn/thread-1193224-1-1.html" target="_blank">评测</a><a href="https://bbs.eeworld.com.cn/thread-1193244-1-1.html" target="_blank">】15、RT-Thread消息队列、多线程使用</a></p>
<p><a href="https://bbs.eeworld.com.cn/thread-1193269-1-1.html" target="_blank">【GD32L233C-START评测】16、RT-Thread事件集从中断唤醒任务</a></p>
<p><a href="https://bbs.eeworld.com.cn/thread-1194428-1-1.html" target="_blank">【GD32L233C-START评测】17、CMSIS-RTOS2 RTX5移植到GD32L233(内核,多线程)</a></p>
<p><a href="https://bbs.eeworld.com.cn/thread-1197266-1-1.html" target="_blank">【GD32L233C-START评测】18、硬件SPI驱动(ST7735)1.8吋TFT LCD</a></p>
<p> </p>
<p><span style="font-size:26px;">1、GD32L233低功耗串口</span></p>
<p><span style="font-size:16px;"> 可以看出GD32L233系列都只有一个低功耗串口。</span></p>
<p> </p>
<p><span style="font-size:26px;">2、串口引脚复用</span></p>
<p><span style="font-size:16px;"> 使用PA2和PA3,复用功能为AF8。</span></p>
<p> </p>
<p><span style="font-size:26px;">3、开发板LPUART引脚</span></p>
<p> </p>
<p><span style="font-size:26px;">4、mcu从深度休眠唤醒条件</span></p>
<p><span style="font-size:16px;"> 可以看出唤醒的条件是外部中断或事件。</span></p>
<p> </p>
<p><span style="font-size:26px;">5、串口为什么能从休眠唤醒mcu</span></p>
<p><span style="font-size:16px;"> 可以看出,LPUART连接到了外部中断28上,属于外部中断,这正是串口为什么能从休眠唤醒mcu的原因。</span></p>
<p> </p>
<p><span style="font-size:26px;">6、串口从休眠唤醒方式</span></p>
<p></p>
<p> </p>
<p><span style="font-size:26px;">7、代码实现</span></p>
<pre>
<code>struct
{
uint8_t RecvBuff;
uint8_t RecvLen;
uint8_t Idle:1;
}LpSerialStr;//串口数据处理结构体</code></pre>
<pre>
<code>void LpuartInit(void)
{
rcu_lpuart_clock_config(RCU_LPUARTSRC_IRC16MDIV); //要进入休眠,时钟必须配置为IRC16M或LXTAL
rcu_periph_clock_enable(RCU_GPIOA);
rcu_periph_clock_enable(RCU_LPUART);
/* connect port to LPUART TX */
gpio_af_set(GPIOA, GPIO_AF_8, GPIO_PIN_2);
/* connect port to LPUART RX */
gpio_af_set(GPIOA, GPIO_AF_8, GPIO_PIN_3);
/* configure LPUART TX as alternate function push-pull */
gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_2);
gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_10MHZ, GPIO_PIN_2);
/* configure LPUART RX as alternate function push-pull */
gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_3);
gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_10MHZ, GPIO_PIN_3);
/* LPUART configure */
lpuart_deinit();
lpuart_word_length_set(LPUART_WL_8BIT);
lpuart_stop_bit_set(LPUART_STB_1BIT);
lpuart_parity_config(LPUART_PM_NONE);
lpuart_baudrate_set(115200U);
lpuart_receive_config(LPUART_RECEIVE_ENABLE);
lpuart_transmit_config(LPUART_TRANSMIT_ENABLE);
exti_init(EXTI_28, EXTI_INTERRUPT, EXTI_TRIG_BOTH); //外部中断28配置
nvic_irq_enable(LPUART_WKUP_IRQn, 0); //休眠唤醒中断使能
lpuart_wakeup_mode_config(LPUART_WUM_RBNE ); //唤醒方式,一定要在串口使能之前配置
lpuart_wakeup_enable();
lpuart_interrupt_enable(LPUART_INT_WU); //休眠唤醒中断
lpuart_enable();
lpuart_interrupt_enable(LPUART_INT_RBNE); //接收中断
while(RESET == lpuart_flag_get(LPUART_FLAG_IDLE)){};
lpuart_flag_clear(LPUART_FLAG_IDLE);
lpuart_interrupt_enable(LPUART_INT_IDLE); //空闲中断
nvic_irq_enable(LPUART_IRQn, 3); //低功耗串口中断使能
void LpSerialSend(uint8_t *data,uint8_t len);
LpSerialSend((uint8_t *)"enter\r\n",7);
rcu_periph_clock_enable(RCU_PMU);
pmu_to_deepsleepmode(PMU_LDNPDSP_LOWDRIVE, WFI_CMD, PMU_DEEPSLEEP);//进入休眠
void system_clock_reconfig(void);
system_clock_reconfig(); //
LpSerialSend((uint8_t *)"recover\r\n",9);
}
</code></pre>
<p> </p>
<pre>
<code>void LpSerialRecv(uint8_t data)//串口接收
{
if(LpSerialStr.RecvLen<200)
{
LpSerialStr.RecvBuff=data;
}
}
void LpSerialSend(uint8_t *data,uint8_t len)//串口发送
{
for(uint8_t i=0; i<len;i++)
{
while (RESET == lpuart_flag_get(LPUART_FLAG_TBE));
lpuart_data_transmit(data);
while (RESET == lpuart_flag_get(LPUART_FLAG_TC));//LPUART_FLAG_TBE
}
}
void LpSerialPro(void) //串口接收数据处理
{
uint8_t len;
if(LpSerialStr.Idle&&LpSerialStr.RecvLen)
{
LpSerialSend((uint8_t *)"Recv:",5);
sprintf((char *)len,"%d",LpSerialStr.RecvLen);
LpSerialSend(len,strlen((char *)len));
LpSerialSend((uint8_t *)"[",1);
LpSerialSend(LpSerialStr.RecvBuff,LpSerialStr.RecvLen);
LpSerialSend((uint8_t *)"]\r\n",3);
LpSerialStr.RecvLen=0;
LpSerialStr.Idle=0;
}
}</code></pre>
<p> </p>
<pre>
<code>void system_clock_reconfig(void)//唤醒后重新配置时钟
{
/* enable HXTAL */
RCU_CTL |= RCU_CTL_HXTALEN;
while(SUCCESS != rcu_osci_stab_wait(RCU_HXTAL)) {};
/* configure AHB */
rcu_ahb_clock_config(RCU_AHB_CKSYS_DIV1);
/* configure APB1, APB2 */
rcu_apb1_clock_config(RCU_APB1_CKAHB_DIV1);
rcu_apb2_clock_config(RCU_APB2_CKAHB_DIV1);
/* enable PLL */
RCU_CTL |= RCU_CTL_PLLEN;
/* select PLL as system clock */
RCU_CFG0 &= ~RCU_CFG0_SCS;
RCU_CFG0 |= RCU_CKSYSSRC_PLL;
}</code></pre>
<p> </p>
<pre>
<code>void LPUART_IRQHandler(void)//串口中断处理函数
{
if(RESET != lpuart_interrupt_flag_get(LPUART_INT_FLAG_RBNE)) //接收中断
{
LpSerialRecv(lpuart_data_receive());
}
if(RESET != lpuart_interrupt_flag_get(LPUART_INT_FLAG_IDLE)) //空闲中断
{
lpuart_interrupt_flag_clear(LPUART_INT_FLAG_IDLE);
LpSerialStr.Idle=1;
}
}
void LPUART_WKUP_IRQHandler(void) //串口唤醒中断处理函数
{
if(SET == lpuart_interrupt_flag_get(LPUART_INT_FLAG_WU))
{
lpuart_flag_clear(LPUART_FLAG_WU);
exti_flag_clear(EXTI_28);
}
}</code></pre>
<p><span style="font-size:26px;">8、现象</span></p>
<p><span style="font-size:16px;"> 打印“enter”提示进入休眠,接收到数据后唤醒,打印“recover”,唤醒后同时处理,唤醒时接收到的串口数据;</span></p>
<p><span style="font-size:16px;">之后,发送不定长数据,串口在接收完后,将接收到的数据再打印出来。</span></p>
<p> </p>
<p> </p>
<p> </p>
<p>学习一下,如果用普通串口,如usart1是相同配置吗</p>
<p>有测过休眠电流和唤醒电流各是多少吗?否则没任何意义。</p>
睡眠模式电流250uA GOOD
页:
[1]