【GD32L233C-START 评测】(4)Sleep低功耗模式下 LPTIMER唤醒触发ADC
[复制链接]
本帖最后由 wenyangzeng 于 2022-3-6 16:40 编辑
【GD32L233C-START 评测】(4)Sleep低功耗模式下 LPTIMER唤醒触发ADC
32位的LPTIMER定时器可以在除Standby模式外的所有低功耗模式下运行。可以将系统从低功耗模式唤醒。考虑到评估过程需要经常下载代码,而系统如果是工作在Deepsleep模式下,调试代码下载经常会失败,影响了调试效率,决定使用Sleep模式来评估低功耗。
使能 LPTIMER的CMPVM中断,系统大约每20秒唤醒一次,唤醒后执行一次过采样ADC、点亮LED1,并计算出当前ADC采样的温度数据从LPUART串口发送到终端,然后系统再次进入Sleep低功耗模式,LED1熄灭。
为了不破坏GD32L233C-START的PCB板结构,评估过程就跳过系统耗电电流的测试,主要是体验低功耗的配置方法和使用过程。
执行结果
代码
#include "gd32l23x.h"
#include "systick.h"
#include <stdio.h>
#include "gd32l233r_eval.h"
#define ADC_TEMP_CALIBRATION_VALUE REG16(0x1FFFF7F8)
#define LPUART_RDATA_ADDRESS ((uint32_t)&LPUART_RDATA)
uint16_t adc_value = 0U;
float temperature;
int32_t value;
uint8_t rxbuffer[256];
uint8_t tx_count = 0;
__IO uint8_t rx_count = 0;
__IO uint8_t receive_flag = 0;
__IO uint8_t ADC_EN=0;
void rcu_config(void);
void adc_config(void);
void lpuart_config(void);
void lptimer_config(void);
void nvic_config(void);
void Get_ADC(void);
int main(void)
{uint8_t i;
rcu_config();
systick_config();
gd_eval_led_init(LED1);
adc_config();
for(i=0;i<3;i++)
{
adc_software_trigger_enable(ADC_INSERTED_CHANNEL);
value = (int32_t)ADC_TEMP_CALIBRATION_VALUE;
}
lpuart_config();
lptimer_config();
nvic_config();
while(1) {
if(ADC_EN==1)
{
gd_eval_led_on(LED1);
Get_ADC();
ADC_EN=0;
pmu_flag_clear(PMU_FLAG_SRAM1_SLEEP);
pmu_to_sleepmode(PMU_LDNP_LOWDRIVE, WFI_CMD);
gd_eval_led_off(LED1);
}
}
}
void rcu_config(void)
{
rcu_periph_clock_enable(RCU_PMU);
rcu_periph_clock_enable(RCU_GPIOA);
rcu_periph_clock_enable(RCU_ADC);
rcu_adc_clock_config(RCU_ADCCK_APB2_DIV6);
rcu_osci_on(RCU_IRC32K);
rcu_osci_stab_wait(RCU_IRC32K);
rcu_lptimer_clock_config(RCU_LPTIMERSRC_IRC32K);
rcu_periph_clock_enable(RCU_LPTIMER);
}
void adc_config(void)
{
adc_channel_length_config(ADC_INSERTED_CHANNEL, 1);
adc_inserted_channel_config(0U, ADC_CHANNEL_16, ADC_SAMPLETIME_239POINT5);
adc_external_trigger_source_config(ADC_INSERTED_CHANNEL, ADC_EXTTRIG_INSERTED_NONE);
adc_data_alignment_config(ADC_DATAALIGN_RIGHT);
adc_special_function_config(ADC_SCAN_MODE, DISABLE);
adc_channel_16_to_19(ADC_TEMP_CHANNEL_SWITCH, ENABLE);
adc_external_trigger_config(ADC_INSERTED_CHANNEL, ENABLE);
adc_oversample_mode_config(ADC_OVERSAMPLING_ALL_CONVERT, ADC_OVERSAMPLING_SHIFT_8B, ADC_OVERSAMPLING_RATIO_MUL256);
adc_oversample_mode_enable();
adc_enable();
delay_1ms(1U);
adc_calibration_enable();
}
void lpuart_config(void)
{
rcu_periph_clock_enable(RCU_GPIOA);
rcu_periph_clock_enable(RCU_LPUART);
gpio_af_set(GPIOA, GPIO_AF_8, GPIO_PIN_2);
gpio_af_set(GPIOA, GPIO_AF_8, GPIO_PIN_3);
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);
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_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);
lpuart_enable();
}
void nvic_config(void)
{
nvic_irq_enable(LPTIMER_IRQn, 1U);
}
int fputc(int ch, FILE *f)
{
lpuart_data_transmit((uint8_t)ch);
while(RESET == lpuart_flag_get(LPUART_FLAG_TBE));
return ch;
}
void lptimer_config(void)
{
lptimer_parameter_struct lptimer_structure;
lptimer_deinit();
lptimer_struct_para_init(&lptimer_structure);
lptimer_structure.clocksource = LPTIMER_INTERNALCLK;
lptimer_structure.prescaler = LPTIMER_PSC_64;
lptimer_structure.triggermode = LPTIMER_TRIGGER_SOFTWARE;
lptimer_structure.countersource = LPTIMER_COUNTER_INTERNAL;
lptimer_init(&lptimer_structure);
lptimer_register_shadow_disable();
lptimer_timeout_disable();
lptimer_interrupt_flag_clear(LPTIMER_INT_FLAG_CMPVM);// | LPTIMER_INT_FLAG_CARM);
lptimer_interrupt_enable(LPTIMER_INT_CMPVM);// | LPTIMER_INT_CARM);
lptimer_countinue_start(9999U, 5000U);
while(lptimer_counter_read() == 0) {
}
}
void Get_ADC(void)
{
printf("\r\n Sleep wake up ");
adc_software_trigger_enable(ADC_INSERTED_CHANNEL);
value = (int32_t)ADC_TEMP_CALIBRATION_VALUE;
temperature = ((float)((int32_t)ADC_IDATA0-value ) * 3.3f / 4095 * 1000 / 4.3f) + 25;
printf("\r\n Current Temperature = %2.1f ", temperature);
printf("\r\n Sleep wake dn \r\n");
printf(" \r\n");
}
void LPTIMER_IRQHandler()
{
if(RESET != lptimer_interrupt_flag_get(LPTIMER_INT_FLAG_CMPVM)) {
lptimer_interrupt_flag_clear(LPTIMER_INT_FLAG_CMPVM);
ADC_EN=1;
SystemInit();
}
}
|