本帖最后由 jinglixixi 于 2022-11-30 09:46 编辑
在MM32L0136片内,有一个 12 位模数转换器(ADC),转换时间为1us,多达 15 个外部输入通道和1个内部输入通道。其 转换范围:0 ∼ VDDA, 支持采样时间和分辨率配置,含 片上温度传感器和 片上电压传感器。 在UART2的帮助下,可对相应的通道进行数据采集。 为便于学习,可参考官方的例程。该例程是对引脚PA1所对应的通道1进行数据采集,通过USB转TTL模块来观察数据采集的结果,其效果如图1所示。
图1 采集效果
该程序设计的比较有意思,它不是采用以往的单纯循环采集并输出采集结果,而是将串口的通讯功能也结合其中。 一次只显示一个采集结果,然后便等待有一个串口的输入,如果不是分析程序而是单纯地按提示按下一个按键是不起如何作用的。 因此,UART2是必须接全的,即: PA2 - UART2_TX PA3 - UART2_RX
当PA1接GND时,其检测值最小只能到10;当PA1接3.3V时,其检测值则可达到4096,见图2所示。
图2 测试效果
此外,由图3所示的ADC电路图可知PA1是与开发板上的电位器RV3相连接的,通过它可通过模拟电位信号。 图3 ADC电路
图4 RV3的位置
在使用RV3的情况下,其最小检测值为0,最大检测值为4095,见图5所示。 图5 RV3调节测试
该测试的主程序为: int main(void)
{
BOARD_Init();
printf("adc_basic example.\r\n");
app_adc_init();
printf("press any key to start the conversion.\r\n");
while (1)
{
/* type any key into the terminal to trigger the conversion. */
getchar();
/* satrt the one channel conversion. */
printf("app_adc_run_conv() start...\r\n");
printf("adc_val= %u\r\n", (unsigned)(app_adc_run_conv() & 0xFFF));
printf("app_adc_run_conv() done.\r\n\r\n");
}
}
所采用的初始化函数为: void app_adc_init(void)
{
/* pins and clock are already in the pin_init.c and clock_init.c. */
/* setup the converter. */
ADC_Init_Type adc_init;
adc_init.Resolution = ADC_Resolution_12b;
adc_init.ClockDiv = ADC_ClockDiv_16;
adc_init.ConvMode = ADC_ConvMode_SingleSlot;
adc_init.Align = ADC_Align_Right;
ADC_Init(BOARD_ADC_PORT, &adc_init);
ADC_Enable(BOARD_ADC_PORT, true); /* power on the converter. */
ADC_EnableTempSensor(BOARD_ADC_PORT, true); /* enable the temperature sensor. */
/* setup the sequence, a regular conversion with only one channel. */
ADC_RegSeqConf_Type adc_regseq_conf;
adc_regseq_conf.SeqSlots = 1u << BOARD_ADC_CHN_NUM;
adc_regseq_conf.SeqDirection = ADC_RegSeqDirection_LowFirst;
ADC_EnableRegSeq(BOARD_ADC_PORT, &adc_regseq_conf);
/* set channel sample time. */
ADC_SetChnSampleTime(BOARD_ADC_PORT, BOARD_ADC_CHN_NUM, ADC_SampleTime_Alt7);
}
数据采集的函数为: uint32_t app_adc_run_conv(void)
{
uint32_t data;
uint32_t flags;
uint32_t adc_channel; /* keep the actual hardware conversion channel number. */
/* software tirgger the conversion. */
ADC_DoSwTrigger(BOARD_ADC_PORT, true);
/* wait while the conversion is ongoing. */
while( 0u == (ADC_GetStatus(BOARD_ADC_PORT) & ADC_STATUS_CONV_SEQ_DONE) )
{}
ADC_ClearStatus(BOARD_ADC_PORT, ADC_STATUS_CONV_SEQ_DONE);
data = ADC_GetConvResult(BOARD_ADC_PORT, &adc_channel, &flags);
if (0u == (flags & ADC_CONV_RESULT_FLAG_VALID) )
{
data = 0u; /* the data is unavailable when the VALID flag is not on. */
}
return data;
}
在为它添加了LCD屏的显示功能后,它可形成一个检测电压的检测仪表,见图6所示。此外,还可为它添加一个温度传感器来检测温度的测控。 图6 电压检测
实现LCD屏显示电压的程序为: int main(void)
{
uint32_t dat;
BOARD_Init();
app_slcd_init();
app_adc_init();
while (1)
{
dat=(unsigned)(app_adc_run_conv() & 0xFFF);
dat=3300*dat/4095;
LCD_DisplayNumberV(dat,0,0);
app_delay(500);
}
}
|