【复旦微车规MCU FM32FT0A测评】A/D数据采集与显示
[复制链接]
FM32FT0A配有2Msps 的12位SAR型ADC,可实现温度、电池单元等直流信号的检测。它最多可提供23个外部输入通道,即14个快速通道,可组成6个差分输入对,及9个慢速通道,仅支持单端输入。
为便于测试,它板载了一个微小的电位器,并连接到ADC_IN6,即引脚PC11,参见图1所示。
图1 连接关系
ADC基础配置的函数为:
static void MF_ADC_Common_Init(void)
{
/*ADC CONFIG*/
FL_ADC_CommonInitTypeDef CommonInitStruct;
CommonInitStruct.clockSource = FL_CMU_ADC_CLK_SOURCE_RCHF; /*配置ADC工作时钟源*/
CommonInitStruct.clockPrescaler = FL_ADC_CLK_PSC_DIV1; /*配置ADC工作时钟分频*/
CommonInitStruct.referenceSource = FL_ADC_REF_SOURCE_VDDA; /*配置ADC参考源*/
CommonInitStruct.bitWidth = FL_ADC_BIT_WIDTH_12B; /*配置ADC输出位宽*/
(void)FL_ADC_CommonInit(&CommonInitStruct);
}
ADC初始化的函数为:
static void MF_ADC_Init(void)
{
FL_GPIO_InitTypeDef GPIO_InitStruct;
FL_ADC_InitTypeDef defaultInitStruct;
GPIO_InitStruct.pin = FL_GPIO_PIN_11; /*配置GPIO的引脚号*/
GPIO_InitStruct.mode = FL_GPIO_MODE_ANALOG; /*配置GPIO的功能模式*/
GPIO_InitStruct.outputType = FL_GPIO_OUTPUT_PUSHPULL; /*配置GPIO的输出模式*/
GPIO_InitStruct.pull = FL_GPIO_BOTH_DISABLE; /*配置GPIO上拉下拉模式*/
GPIO_InitStruct.remapPin = FL_GPIO_PINREMAP_FUNCTON1; /*配置GPIO数字重定向功能*/
GPIO_InitStruct.driveStrength = FL_GPIO_DRIVESTRENGTH_X3; /*配置GPIO驱动能力*/
GPIO_InitStruct.analogSwitch = FL_DISABLE; /*配置GPIO模拟开关功能*/
(void)FL_GPIO_Init( GPIOC, &GPIO_InitStruct ); /*GPIO初始化*/
defaultInitStruct.conversionMode = FL_ADC_CONV_MODE_SINGLE; /*配置ADC转换模式*/
defaultInitStruct.autoMode = FL_ADC_SINGLE_CONV_MODE_AUTO; /*配置ADC转换流程,仅对单次转换有效*/
defaultInitStruct.waitMode = FL_ENABLE; /*配置ADC等待模式*/
defaultInitStruct.overrunMode = FL_ENABLE; /*配置ADC_Overrun模式*/
defaultInitStruct.scanDirection = FL_ADC_SEQ_SCAN_DIR_FORWARD; /*配置ADC扫描顺序*/
defaultInitStruct.externalTrigConv = FL_ADC_TRIGGER_EDGE_NONE; /*配置非软件触发使能及极性*/
defaultInitStruct.triggerSource = FL_ADC_TRGI_LUT0; /*配置ADC非软件触发源*/
defaultInitStruct.fastChannelTime = FL_ADC_FAST_CH_SAMPLING_TIME_4_ADCCLK; /*配置ADC快速通道采样时间*/
defaultInitStruct.lowChannelTime = FL_ADC_SLOW_CH_SAMPLING_TIME_192_ADCCLK; /*配置ADC慢速通道采样时间*/
defaultInitStruct.oversamplingMode = FL_DISABLE; /*配置ADC过采样模式*/
defaultInitStruct.overSampingMultiplier = FL_ADC_OVERSAMPLING_MUL_16X; /*配置ADC过采样率*/
defaultInitStruct.oversamplingShift = FL_ADC_OVERSAMPLING_SHIFT_4B; /*配置ADC过采样结果移位*/
(void)FL_ADC_Init(ADC,&defaultInitStruct ); /*ADC初始化*/
FL_ADC_EnableSequencerChannel(ADC, FL_ADC_INTERNAL_AVREF); /*通道选择*/
FL_ADC_EnableSequencerChannel(ADC, FL_ADC_EXTERNAL_CH6);
}
为便于观察,还配置了串口4来支持printf()函数的输出功能。
实现数据采集验证的主程序为:
int main(void)
{
/* 使能IWDT */
IWDT_Init(FL_IWDT_PERIOD_4000MS);
/* Initialize FL Driver Library */
/* SHOULD BE KEPT!!! */
FL_Init();
/* 使能SVD, 阈值4.157V(falling)~4.257V(rising) */
SVD_Init(SVD_MONTIOR_VDD, FL_SVD_WARNING_THRESHOLD_GROUP11, FL_SVD_REFERENCE_1P0V);
/* 确认SVD监测结果是否高于阈值,如否则持续等待 */
while(false == SVD_Result_Confirmed(SVD_HIGHER_THRESHOLD, 2000U/*us*/));
/* 使能BOR */
RMU_BOR_Init(FL_RMU_BOR_THRESHOLD_2P00V);
/* Initialize all configured peripherals */
/* SHOULD BE KEPT!!! */
MF_Config_Init();
MF_UART4_Init();
while(1)
{
/* 清狗 */
FL_IWDT_ReloadCounter(IWDT);
/* 电源掉电监测处理 */
PowerDownMonitoring();
/* 功能执行 */
GetVoltage = GetSingleChannelVoltage_POLL(FL_ADC_EXTERNAL_CH6);
printf("CH6:%d \r\n",GetVoltage);
FL_DelayMs(500);
}
}
经程序的编译和下载,其测试效果如图2和图3所示。其中图1是初始状态下的检测值,比较诧异的是12位精度,满量程时应是4095,它咋到了5000有余呢?
图2 初始状态
后经核准,原来这里输出的电压值,所使用的相关函数内容如下:
uint32_t GetSingleChannelVoltage_POLL(uint32_t channel)
{
uint32_t GetChannelVoltage = 0, GetAVREFSample = 0, GetVSample = 0;
uint8_t GetVSample_State, GetAVREFSample_State;
GetAVREFSample_State = GetAVREFSample_POLL(&GetAVREFSample);
GetVSample_State = GetSingleChannelSample_POLL(channel, &GetVSample);
if ((GetAVREFSample != 0x0) && (GetAVREFSample_State == 0x0) && (GetVSample_State == 0x0))
{
GetChannelVoltage = (uint32_t)(((uint64_t)GetVSample * (ADC_VREF)) / ((uint64_t)GetAVREFSample * 10)); /* 计算通道电压 */
}
/* 转换结果 */
return GetChannelVoltage;
}
当调节电位器后,可见到图2所示的检测值。继续调节,是可以达到零值的。
图3 调节后
在将串口通讯功能改为LCD屏显示后,相应的主程序为:
int main(void)
{
FL_Init();
MF_Config_Init();
OLED_INIT();
Lcd_Init();
LCD_Fill(0,0,LCD_W,LCD_H,WHITE);
LCD_ShowString(70,33,"FM32FT0A",RED,WHITE,32,0);
LCD_ShowString(70,73,"ch6= mV",RED,WHITE,32,0);
while(1)
{
GetVoltage = GetSingleChannelVoltage_POLL(FL_ADC_EXTERNAL_CH6);
LCD_ShowIntNum(134,73,GetVoltage,4,RED,WHITE,32);
FL_DelayMs(500);
}
}
经程序的编译和下载,其测试效果如图4所示。
图4 显示效果
出于显示频繁刷新的原因,原计划的波形绘制功能也就无从实现了,不免有些遗憾!
|