完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
`ADC,Analog-to-Digital Converter的缩写,是指将连续变量的模拟信号转换为离散的数字信号的器件。真实世界的模拟信号,例如温度、压力、声音或者图像等,需要转换成更容易储存、处理和发射的数字信号,ADC能够将模拟信号转换成数字信号。MM32L073有一个ADC,具有以下特征:
▷ 单周期扫描模式:A/D 转换在所有指定通道完成一个周期 (从低序号通道到高序号通道) 转换 ▷ 连续扫描模式:A/D 转换连续执行单周期扫描模式直到软件停止A/D转换
▷ 外部触发启动 ▷ timer 匹配
AMetal平台已经为客户封装好了相关的函数,用户根据实际项目需求直接用相关函数即可。要读取电压值,需要经过这几个步骤:读取指定通道的 ADC 转换值、对转换值做均值处理、获取转换精度、获取 ADC 参考电压、计算出转换值对应的电压值。 01 初始化 AMetal平台提供了ADC初始化函数,可以直接调用初始化函数。函数原型为: am_adc_handle_t am_mm32l073_adc_inst_init(void); 该函数在user_config目录下的am_hwconf_mm32l073_adc.c文件中定义,在am_mm32l073_inst_init.h中声明。因此使用ADC初始化函数时,需要包含头文件am_mm32l073_inst_init.h。 调用该函数初始化ADC时,需要定义一个am_adc_handle_t类型的变量,用于保存获取的ADC服务句柄,ADC初始化程序为: am_adc_handle_t adc_handle; adc_handle = am_mm32l073_adc_inst_init(); 使用前,一般需要修改引脚初始化函数;以ADC通道0为例,ADC_IN0为PIOA_0的复用功能,需把ADC平台初始化函数的更改为: static void __zlg_plfm_adc_init (void) { am_gpio_pin_cfg(PIOA_0, PIOA_0_ADC_IN0 | PIOA_0_AIN); am_clk_enable(CLK_ADC1); } 把解除ADC平台初始化函数的更改为: static void __zlg_plfm_adc_deinit (void) { am_gpio_pin_cfg(PIOA_0, PIOA_0_INPUT_FLOAT); am_clk_disable (CLK_ADC1); } 如需修改ADC的参考电压和转换精度等信息,可以直接调用宏。
表1 转换精度宏定义 AMetal提供了5个ADC相关的接口函数。
表2 ADC 通用接口函数 02 获取ADC通道的采样率 获取当前ADC通道的采样率。其函数原型为: int am_adc_rate_get( am_adc_handle_t handle, // ADC 实例句柄 int chan, // ADC 通道 uint32_t *p_rate); // 用于获取采样率的指针 获取到的采样率的单位为Samples/s。如果返回AM_OK,说明获取成功;如果返回-AM_EINVAL,说明因参数无效导致获取失败。 uint32_t rate; // 定义用于保存获取的采样率值的变量 am_adc_rate_get(adc0_handle, 7, &rate); // 获取 ADC0通道7的采样率 参数无效是由于handle不是标准的ADChandle或者通道号不支持造成的。 03 设置ADC通道的采样率 设置ADC通道的采样率。实际采样率可能与设置的采样率存在差异,实际采样率可由am_adc_rate_get()函数获取。注意,在一个ADC中,所有通道的采样率往往是一样的,因此设置其中一个通道的采样率时,可能会影响其它通道的采样率。其函数原型为: int am_adc_rate_set ( am_adc_handle_t handle, // ADC 实例句柄 int chan, // ADC 通道 uint32_t rate); // 设置的采样率,单位 Samples/s 如果返回 AM_OK,说明设置成功;如果返回-AM_EINVAL,说明因参数无效导致设置失败,其相应的代码如下: am_adc_rate_set(adc0_handle,7,1000000);//设置ADC0通道7的采样率为1Msamples/s 04 获取ADC通道的参考电压 获取ADC通道的参考电压,其函数原型为: int am_adc_vref_get( am_adc_handle_t handle, // ADC 实例句柄 int chan); // ADC 通道 如果返回值大于0,表示获取成功,其值即为参考电压(单位:mV);如果返回-AM_EINVAL,说明因参数无效导致获取失败,其相应的代码如下: int vref = am_adc_vref_get(adc0_handle, 7); // 获取通道 7 的参考电压 if (vref < 0 ) { // 获取失败 } 05 获取ADC通道的转换位数 获取ADC通道的转换位数,其函数原型为: int am_adc_bits_get( am_adc_handle_t handle, // ADC 实例句柄 int chan); // ADC 通道 如果返回值大于0,表示获取成功,其值即为转换位数;如果返回-AM_EINVAL,说明因参数无效导致获取失败,其相应的代码如下: int bits =am_adc_bits_get(adc0_handle, 7); // 获取通道7的转换位数 if (bits < 0 ) { // 获取失败 } 06 读取指定通道的电压值 直接读取ADC通道的电压值(单位:mV),该函数会等到电压值读取完毕后返回。其函数原型为: int am_adc_read_mv( am_adc_handle_t handle, // ADC实例句柄 int chan, // ADC 通道 am_adc_val_t *p_mv, // 存放电压值的缓冲区 uint32_t length); // 缓冲区的长度 其中 p_mv 是指向存放电压值的缓冲区,类型am_adc_val_t在am_adc.h中定义,即:typedef uint32_t am_adc_val_t;length 表示缓冲区的长度,决定了实际获取电压值的个数。如果返回AM_OK,表示读取通道电压值成功,相应缓冲区中已经填充好了读取到的电压值;如果返回-AM_EINVAL,说明因参数无效导致获取失败。其相应的代码如下: am_adc_val_t vol_buf[10]; // 存放电压值的缓冲区 am_adc_read_mv(adc0_handle, 7, vol_buf,10); // 读取ADC0通道7对应引脚的10次电压值 07 应用实例 在使用过程中,我们需要通过多次采样然后取平均值来减小误差,读取ADC采样值的函数原型为: int am_adc_read (am_adc_handle_t handle, int chan, void *p_val, uint32_t length);
采样完成后,我们需把p_val指向的数组里的值加起来,除以length,来得到多次采样的平均值: for (sum = 0, i = 0; i < length; i++) { sum += p_val ; } sum /= length; 得到平均值后,可用 AM_ADC_VAL_TO_MV()将它装换为电压值: adc_mv = AM_ADC_VAL_TO_MV(handle, chan,adc_code); 其中adc_mv为保存电压值的变量;handle为ADC的服务句柄;chan为ADC的通道编号;adc_code为多次采样额平均值。 每隔500ms读取ADC通道0的电压值并通过串口打印的应用范例如下: #include "ametal.h" #include "am_vdebug.h" #include "am_delay.h" #include "am_adc.h" #include "am_mm32l073_inst_init.h" static uint32_t __adc_code_get (am_adc_handle_t handle, int chan) //获取ADC转换值 { int i; uint32_t sum; uint16_t val_buf[12]; am_adc_read(handle, chan, val_buf,12); for (sum = 0, i = 0; i <12; i++) // 均值处理 { sum += val_buf; } return (sum /12); } void am_main () { am_adc_handle_t handle=am_mm32l073_adc_inst_init(); int adc_bits = am_adc_bits_get(handle , 1); // 获取ADC转换精度 int adc_vref = am_adc_vref_get(handle , 1); uint32_t adc_code; // 采样 Code 值 uint32_t adc_mv; // 采样电压 am_kprintf("The ADC value channel is %d: ",1); if (adc_bits < 0 || adc_bits >= 32) { am_kprintf("The ADC channel is error, Please check! "); return; } AM_DBG_INFO("demo mm32l073_core std adc int! "); while (1) { adc_code = __adc_code_get(handle, 1); adc_mv = AM_ADC_VAL_TO_MV(handle, 1,adc_code); //转换为 mv /* 串口输出采样电压值 */ am_kprintf("Sample : %d, Vol: %d mv ",adc_code,adc_mv); am_mdelay(500); } } 08 测试结果 |
|
相关推荐
|
|
只有小组成员才能发言,加入小组>>
2248个成员聚集在这个小组
加入小组灵动微电子MM32全系列MCU产品应用手册,库函数和例程和选型表
11665 浏览 3 评论
【MM32 eMiniBoard试用连载】+基于OLED12864的GUI---U8G2
5920 浏览 1 评论
【MM32 eMiniBoard试用连载】移植RT-Thread至MM32L373PS
10950 浏览 0 评论
【MM32 eMiniBoard测评报告】+ 开箱 + 初探
4571 浏览 1 评论
灵动微课堂(第106讲) | MM32 USB功能学习笔记 —— WinUSB设备
4296 浏览 1 评论
[MM32软件] MM32F002使用内部flash存储数据怎么操作?
964浏览 1评论
792浏览 0评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-23 16:40 , Processed in 0.766280 second(s), Total 69, Slave 51 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号