ADC——基于STC15W4K32S4

文章目录

  • ADC——基于STC15W5K32S4
    • 一、逼近式ADC原理
    • 二、STC15W4K32S4单片机的A/D结构
        • 1.P1口模拟功能控制寄存器P1ASF
        • 2. ADC控制寄存器ADC_CONTR
        • 3. ADC转换结果调整寄存器位——ADRJ
        • 4.A/D转换结果寄存器ADC_RES、ADC_RESL
        • 5.中断允许寄存器IE
    • 三、ADC转换编程
    • 四、代码
        • ADC初始化
        • 查询法读一次ADC结果
        • ADC键盘

ADC——基于STC15W5K32S4

将模拟信号转换成数字信号的电路,我们称其为模数转换器,简称A/D转换器或ADC(Analog-to-digital converter)。同理,将数字信号转换成模拟信号的电路称为数模转换器,简称D/A转换器或DAC,单片机能够存储的数据都是数字类型的。

一、逼近式ADC原理

在进行转化时,一般都需要经过采样、量化和编码三个步骤。A/D转换的过程是需要时间的,我们可以在连续变化的模拟量上按一定的时间规律取得对应的瞬时值,量化后以数字的形式输出,从而可以实现从模拟量到数字量的转化。
在这里插入图片描述

二、STC15W4K32S4单片机的A/D结构

在这里插入图片描述
STC15系列单片机ADC由多路选择开关、比较器、逐次比较寄存器、10位ADC、转换结果寄存器(ADC_RES和ADC_RESL)以及ADC_CONTR构成。

STC15系列单片机的ADC是逐次比较性ADC,逐次比较型ADC由一个比较器和D/A转换器构成,通过逐次比较逻辑,从最高位(MSB)开始,顺序地对每一输入电压与内置D/A转换器输出进行比较,经过多次比较,使转换所得的数字量逐次逼近输入模拟量对应值,逐次比较型A/D转换器具有速度高,功耗低等优点。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

1.P1口模拟功能控制寄存器P1ASF

在这里插入图片描述

2. ADC控制寄存器ADC_CONTR

在这里插入图片描述

3. ADC转换结果调整寄存器位——ADRJ

在这里插入图片描述

4.A/D转换结果寄存器ADC_RES、ADC_RESL

在这里插入图片描述
在这里插入图片描述

5.中断允许寄存器IE

在这里插入图片描述

三、ADC转换编程

  • 设置P1口中的相应口线作为AD转换模拟量输入通道(设置P1ASF寄存器);
  • 清除结果寄存器(ADC_RES、ADC_RESL为0);
  • 打开ADC电源(设置ADC_POWER位)
  • 适当延时,等ADC内部模拟电源稳定。一般延时1ms即可;
  • 选择ADC通道(设置ADC_CONTR中的CHS2-CHS0位);
  • 根据需要设置转换结果存储格式(设置CLK_DIV中ADRJ位);
  • 查询AD转换结束标志ADC_FLAG,判断AD转换是否完成,若完成,则读出AD转换结果(保存在ADC_RES和ADC_RESL寄存器中),并进行数据处理。
  • 采用中断方式,还需进行中断设置(中断允许和中断优先级);
  • 在中断服务程序中读取AD转换结果,并将ADC中断请求标志ADC_FLAG清零。

四、代码

ADC初始化
/*----------------------------
初始化ADC
----------------------------*/
void ADCinit(void)
{P1ASF = 0xff;		//P1做ADC               ADC_RES = 0;		//清除结果寄存器ADC_RESL = 0;ADC_CONTR = 0xE0;	//90T, ADC power ondelay_ms(5);                       //ADC上电并延时
}
查询法读一次ADC结果
//========================================================================
// 函数: u16	Get_ADC10bitResult(u8 channel)
// 描述: 查询法读一次ADC结果.
// 参数: channel: 选择要转换的ADC.
// 返回: 10位ADC结果.
// 版本: V1.0, 2012-10-22
//========================================================================
u16	Get_ADC10bitResult(u8 channel)	//channel = 0~7
{ADC_RES = 0;ADC_RESL = 0;ADC_CONTR = (ADC_CONTR & 0xe0) | 0x08 | channel; 	//start the ADCNOP(4);while((ADC_CONTR & 0x10) == 0)	;	//wait for ADC finishADC_CONTR &= ~0x10;		//清除ADC结束标志return	(((u16)ADC_RES << 2) | (ADC_RESL & 3));
}
ADC键盘

/***************** ADC键盘计算键码 *****************************
本ADC键盘方案在很多实际产品设计中, 验证了其稳定可靠, 即使按键使用导电膜,都很可靠.
16个键,理论上各个键对应的ADC值为 (1024 / 16) * k = 64 * k, k = 1 ~ 16, 特别的, k=16时,对应的ADC值是1023.
但是实际会有偏差,则判断时限制这个偏差, ADC_OFFSET为+-偏差, 则ADC值在 (64*k-ADC_OFFSET) 与 (64*k+ADC_OFFSET)之间为键有效.
间隔一定的时间,就采样一次ADC,比如10ms.
为了避免偶然的ADC值误判, 或者避免ADC在上升或下降时误判, 使用连续3次ADC值均在偏差范围内时, ADC值才认为有效.
以上算法, 能保证读键非常可靠.
**********************************************/
#define	ADC_OFFSET	16
void	CalculateAdcKey(u16 adc)
{u8	i;u16	j;if(adc < (64-ADC_OFFSET)){ADC_KeyState = 0;	//键状态归0ADC_KeyHoldCnt = 0;}j = 64;for(i=1; i<=16; i++){if((adc >= (j - ADC_OFFSET)) && (adc <= (j + ADC_OFFSET)))	break;	//判断是否在偏差范围内j += 64;}ADC_KeyState3 = ADC_KeyState2;ADC_KeyState2 = ADC_KeyState1;if(i > 16)	ADC_KeyState1 = 0;	//键无效else						//键有效{ADC_KeyState1 = i;if((ADC_KeyState3 == ADC_KeyState2) && (ADC_KeyState2 == ADC_KeyState1) &&(ADC_KeyState3 > 0) && (ADC_KeyState2 > 0) && (ADC_KeyState1 > 0)){if(ADC_KeyState == 0)	//第一次检测到{KeyCode  = i;	//保存键码ADC_KeyState = i;	//保存键状态ADC_KeyHoldCnt = 0;}if(ADC_KeyState == i)	//连续检测到同一键按着{if(++ADC_KeyHoldCnt >= 100)	//按下1秒后,以10次每秒的速度Repeat Key{ADC_KeyHoldCnt = 90;KeyCode  = i;	//保存键码}}else	ADC_KeyHoldCnt = 0;	//按下时间计数归0}}
}


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部