摘要:对于电压或电流连续变化的信号,需要通过模数转换电路转换成单片机能够识别的数字电平信号。目前常见的方式有两种,一种是平行比较,一种是逐次比较。它具有成本低、元件简单、易于制作高精度转换器等优点,因此应用广泛。
你怎么敢说你不会采集单片机模拟量和数字量的关系?连续比较器ADC的概念是一个超级好的例子,与您分享STC内部ADC模块的寄存器。这里我们需要采集电池电压(我们用P1.0采集)= = P1M1 | = 0x01P1M0 & = ~ 0x01//P1.0引脚ADC 0 = ADC0 = = = = P1ASF | = 0x01= = = = CLK _ DIV | = 0x 20;= = = = ADC _ RES = 0;ADC _ RESL = 0;==ADC初始化= = = ADC _ CONTR = 0x88;==ADC读取数据底层驱动demo视频采集电压ADC代码ADC_Drive.c(还有一个自己写的滤波函数让数据稳定)基本上这个级别可以用ADC _ drive.h保存。
小码农压信使怎么敢说不会采集模拟信号->数字信号(ADC模块)
单片机模拟量和数字量的关系5V单片机的CPU电路是二进制的,运行过程中只有两种电压:高电平5V和低电平0V。对于电压或电流连续变化的信号,需要通过模数转换电路转换成单片机能够识别的数字电平信号。MP3是ADC采样保存的失真文件。
模拟到数字模拟到数字模拟,通常用一个比较器来负责转换。目前常见的方式有两种,一种是平行比较,一种是逐次比较。
* *并行比较器:* *速度更快,但使用了许多元件。成本会很高。所以实用性不是很广泛。
* *逐次比较器:* *通过反馈控制,经过多次运算,转换出结果。由于其成本低、元件简单、易于制作高精度转换器等优点,得到了广泛的应用。
逐次比较器ADC的概念就是一个超级好的例子分享给大家。先玩个游戏:狗蛋拿了一些花生,我告诉你,你要想吃,必须先猜对几个。我告诉你,最多255。当你猜的时候,我或多或少可以告诉你。那么,如何最快猜出花生的数量呢?我们猜测的时候,为了方便计算,多加了0.5个花生。= =第一步:= =猜255 ÷ 2 +0.5=128。狗蛋告诉你,太多了(0)。第二步:猜128 ÷ 2=64。狗蛋告诉你,①不见了。第三步:猜(128+64) ÷ 2=96。狗蛋告诉你还有(0)。第四步:猜(96+64) ÷ 2=80。狗蛋告诉你,①不见了。第五步:猜(96+80) ÷ 2=88。狗蛋告诉你,①不见了。第六步:猜(96+88) ÷ 2=92。狗蛋告诉你还有(0)。第七步:猜(9zhujipindao 88) ÷ 2=90。狗蛋告诉你还有(0)。第八步:猜(9小编 88) ÷ 2=89。狗蛋告诉你,猜对了(?) 。结果:如果不加0.5,实际计算公式会是88.50000.0000000085其实88.65比89小,所以取1四舍五入,89>88.65,取哪个?= 1 ;结果是0 101 1001 = 89 = 0x59
STC内部ADC模块的寄存器
1.ADC端口配置为ADC输入模式或高阻模式。
2.ADC控制寄存器:ADC_CONTR。控制电源、转换速度、标志位、起始位、通道选择[2:0]
3.ADC采样结果输出寄存器ADC_RES、ADC_RESL。可以是[1:0]+[7:0]或[7:0]+[1:0]。
4.ADC转换,中断相关寄存器IE
5.辅助寄存器AUXR1主要用于控制结果寄存器的存储格式。
这里我们需要采集电池电压(我们用P1.0来采集)。我准备用ADC0检测电池电压,根据老师的需要,然后在数码管上显示指示。因为我之前发表过一个关于数码管的博客,你可能还有一些印象,但是你不知道去看看真正的数码管。
P1M1 | = 0x01P1M0 & = ~ 0x01//P1.0引脚ADC0
P1ASF | = 0x01
CLK _ DIV | = 0x 20;
ADC _ RES = 0;ADC _ RESL = 0;
ADC初始化
//ADC初始化void ADC _ Init(){ P1 m1 | = 0x0f;P1M0 & = ~ 0x0f//P1.0引脚ADC 0 P1 ASF | = 0x0f;//P1 m1 | = 0x 02;//p1m 0 & = ~ 0x 02;//P1.1引脚ad C1//P1 ASF | = 0x 02;CLK _ DIV | = 0x 20;ADC _ RES = 0;ADC _ RESL = 0;} ADC _ CONTR = 0x88
ADC读取数据底层驱动程序
//ADC读数据底层驱动void ADC_Read_Data_Drive(){//转换前,将转换结果寄存器ADC_RES = 0清零;ADC _ RESL = 0;//开始转换ADC _ CONTR = 0x88//我用最慢的转换速度//直到ADC_FLAG为1while(!(ADC _ CONTR & 0x 10));//然后将数据传输到缓存变量。ADC_Read_Data = ADC_RES//转换前将转换结果寄存器清零。ADC _ RES = 0;ADC _ RESL = 0;//开始转换ADC _ CONTR = 0x88//我用最慢的转换速度//直到ADC_FLAG为1while(!(ADC _ CONTR & 0x 10));//然后将数据传输到缓存变量。ADC _ read _ data = ADC _ RES sac _ filter -> ADC _ result = 0;ADC _ filter -> ADC _ Min = ADC _ filter -> ADC _ Max = ADC _ Read _ Data;for(j = 0;jadc _ filter -> ADC _ Result+= ADC _ filter -> ADC _ Tmp;ADC _ filter -> ADC _ Min = ADC _ filter -> ADC _ Tmp;} else if(ADC _ filter -> ADC _ Tmp > ADC _ filter -> ADC _ Max){ ADC _ filter -> ADC _ Result+= ADC _ filter -> ADC _ Tmp;ADC _ filter -> ADC _ Max = ADC _ filter -> ADC _ Tmp;} else { ADC _ filter -> ADC _ Result+= ADC _ filter -> ADC _ Tmp;} } ADC _ filter -> ADC _ Result/= 4;ADC _ Filter _ Data+= ADC _ Filter -> ADC _ Result;} ADC _滤波器_数据/= 4;} ADC _ Drive . h # ifndef ADC _ Drive # define ADC _ Drive typedef struct ADC _ Filter _ Data { u16 ADC _ Min;//ADC最小值u16 ADC _ Max//ADC max u16 ADC _ Tmp;//ADC临时值u16 ADC _ Result//ADC结果} ADC _ Data//extern void ADC_Init()是外部声明的;extern void ADC _ Read _ Data _ Drive();extern void ADC _ Filter _ Data _ Drive();extern u16 xdata ADC _ Read _ Dataextern u16 xdata ADC _ Filter _ Data#endif
评论前必须登录!
注册