目录
前言
学嵌入式这行,人人都知模数转换、数模转换。adc就是模数转换器的英文简称。本文章旨在学习,如有错误,欢迎指正;内容部分来自网络、书籍、和各类手册,如若侵权请告知,马上删帖致歉!
一、adc的参数及基本步骤?
首先经过采样、量化、编码。如采样定理:当采样频率大于模拟信号频率max的两倍时,采样的值才能不失真的反映最原始的模拟信号数据。
adc的主要参数:转换精度、分辨率、转化误差、转换速度。
1.分辨率
数字量变化一个最小量时模拟信号的变化量,定义为满刻度与2n的比值,通常以数字信号的位数来表示。
2.转换速率
转换速率是单位时间内完成A/D转换的次数.
3.采样速率
采样速率是两次采样(两次转换)的间隔时间的倒数,为了保证转换的正确完成,一般采样速率必须小于等于转换速率,即采样时间大于等于转换时间。
二、读取转换电压
1.基本思想
adc的值是从0到4095的,adc接到GND,读出来必然是0,接到VCC必然是4095;需要事先定义好量程和分辨率。量程其实就是基准电压,以5V电压为基准,那么测量的范围就是0V~5V;分辨率就是测量的精度了,假如12位,12位二进制最大值为4095;这时候就可以知道0V=0,5V=4095了,把5V分为4095份就可以了;再配合相应的滤波算法,自然可以很好的写出转化的电压.
2.龙芯adc
源代码:ls1x‐drv/i2c/ads1015/ ads1015.c
头文件:ls1x‐drv/include/i2c/ ads1015.h
ADS1015 是否使用,在 bsp.h 中配置宏定义:
#define ADS1015_DRV
ADS1015 挂接在 I2C0 上,I2C 地址和通信速率定义如下(ads1015.c):
#define ADS1015_ADDRESS 0x48 /* 7 位地址 */
#define ADS1015_BAUDRATE 100000 /* 100K */
int ADS1015_read(void *dev, void *buf, int size, void *arg); 读数据
int ADS1015_ioctl(void *dev, int cmd, void *arg);
ADS1015_read:读取当前 ADC 转换结果,buf 是 unsigned short 类型。
ADS1015_ioctl:设置转换模式。
实用函数:
uint16_t get_ads1015_adc(void *bus, int channel); 读一个通道的 ADC 值
3.adc编程示例
uint16_t val;
float vin;
val = get_ads1015_adc(busI2C0, ADS1015_REG_CONFIG_MUX_SINGLE_0); // 读通道 0
vin = 0.002 * val; /* 0.002 是电压值校正系数 */
printf("ADS1015_IN0 = 0x%04X, voltage=%6.3f\r\n\r\n", val, vin);
ADS1015_ioctl(busI2C0, ADS1015_DISP_CONFIG_REG, NULL); // 显示
4.龙芯adc检测电压示例代码
#include <stdio.h>
#include "ls1b.h"
#include "mips.h"
//-------------------------------------------------------------------------------------------------
// BSP
//-------------------------------------------------------------------------------------------------
#include "bsp.h"
#ifdef BSP_USE_FB
#include "ls1x_fb.h"
#ifdef XPT2046_DRV
char LCD_display_mode[] = LCD_800x480;
#elif defined(GT1151_DRV)
char LCD_display_mode[] = LCD_800x480;
#else
#error "在bsp.h中选择配置 XPT2046_DRV 或者 GT1151_DRV"
"XPT2046_DRV: 用于800*480 横屏的触摸屏."
"GT1151_DRV: 用于480*800 竖屏的触摸屏."
"如果都不选择, 注释掉本 error 信息, 然后自定义: LCD_display_mode[]"
#endif
#endif
#include "ls1x_i2c_bus.h"
#include "i2c/ads1015.h"
#include "i2c/mcp4725.h"
#include "ls1b_gpio.h"
//-------------------------------------------------------------------------------------------------
// 主程序
//-------------------------------------------------------------------------------------------------
int main(void)
{
printk("\r\nmain() function.\r\n");
ls1x_drv_init(); /* Initialize device drivers */
ls1x_mcp4725_ioctl(busI2C0,IOCTL_MCP4725_DISP_CONFIG_REG,NULL);
ls1x_ads1015_ioctl(busI2C0,IOCTL_ADS1015_DISP_CONFIG_REG,NULL);
printk("\n");
char tbuf1[50]={0},tbuf2[50]={0},sbuf1[50]={0},sbuf2[50]={0},rt;
unsigned short dac=0, adc1=0, adc2=0;
float out_v,in_v1,in_v2;
//gpio_enable(47, DIR_OUT);
//gpio_write(47, 1);
/*
* 裸机主循环
*/
for (;;)
{
adc1 = get_ads1015_adc(busI2C0, ADS1015_REG_CONFIG_MUX_SINGLE_0);
adc2 = get_ads1015_adc(busI2C0, ADS1015_REG_CONFIG_MUX_SINGLE_1);
in_v1 = 4.096*2*adc1/4096;//采集电压的转换公式
in_v2 = 4.096*2*adc2/4096;//采集电压的转换公式
sprintf((char *)sbuf1,"ADS1015采集到的电压值: adc = %fV",in_v1);
sprintf((char *)sbuf2,"ADS1015采集到的电压值: adc = %fV",in_v2);
printk("%s\n%s\n\n",tbuf1,sbuf1);
printk("%s\n%s\n\n",tbuf2,sbuf1);
fb_textout(10, 60, "ADS1015 ADC GET");
fb_fillrect(10, 80, 480, 96, cidxBLACK);
fb_fillrect(10, 100, 500, 116, cidxBLACK);
fb_textout(10, 80, sbuf1);
fb_textout(10, 100, sbuf2);
delay_ms(500);
}
return 0;
}
总结
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/73676.html