168|2

1529

帖子

1

TA的资源

五彩晶圆(初级)

楼主
 

【复旦微车规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 显示效果

 

出于显示频繁刷新的原因,原计划的波形绘制功能也就无从实现了,不免有些遗憾!

此帖出自汽车电子论坛

最新回复

嘿嘿,人家获取的是电压真实值。 话说,它没有对采样值进行滤波处理吗?   详情 回复 发表于 昨天 09:56
点赞 关注(1)

回复
举报

137

帖子

0

TA的资源

一粒金砂(中级)

沙发
 

嘿嘿,人家获取的是电压真实值。

话说,它没有对采样值进行滤波处理吗?

此帖出自汽车电子论坛

点评

应该是没有,估计它也不好实现,因为复位频繁难以支撑。  详情 回复 发表于 昨天 10:30
 
 

回复

1529

帖子

1

TA的资源

五彩晶圆(初级)

板凳
 
lemonboard 发表于 2025-1-26 09:56 嘿嘿,人家获取的是电压真实值。 话说,它没有对采样值进行滤波处理吗?

应该是没有,估计它也不好实现,因为复位频繁难以支撑。

此帖出自汽车电子论坛
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/7 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表