什么是A/D 模数转换? 在工业检测系统和日常生活中许多物理量都是模拟量,比如温度、压力、位移、图像等,这些模拟量可以通过传感器变成与之对应的电压、电流等电模拟量。为实现数字系统对这些电模拟量进行检测、运算和控制,则需要一个模拟量和数字量之间相互转化的过程,即 A/D 模数转换。 什么是模拟量? 模拟量:在时间上或数值上都是连续的物理量称之为模拟量,把模拟量的信号称为模拟信号,如温度、压力、位移、图像等都是模拟量。 例如:热电偶在工作时输出的电压信号就属于模拟信号,因为在任何情况下被测温度都不可能发生突跳,所以测得的电压信号无论在时间上还是在数量上都是连续的。而且这个电压信号在连续变化过程中的任何一个取值都是具体的物理意义,即表示一个相应的温度。 什么是数字量? 数字量:在时间上或数值上都是离散的物理量称之为数字量,把数字量的信号称为数字信号。 例如:用电子电路记录从自动生产线上输出的零件数目时,每送出一个零件便给电子电路一个信号,使之记 1,而平时没有零件送出时加给电子电路的信号是 0。可见零件数目这个信号无论在时间上还是在数量上都是不连续的,因此他是一个数字信号,最小的数量单位就是 1个。 A/D转换的原理。 1、A/D 模拟数字转换主要将模拟电压成正比地转换成对应的数字量。A/D 模拟数字转换器分类和特点如下所示: ⑴并联比较型 特点:转换速度快,转换时间 10ns~1μ s,但电路比较复杂。 ⑵逐次逼近型 特点:转换速度适中,转换时间几μ s~100μ s,转换精度高,在转换速度和硬件复杂度之间达到一个很好的平衡。 ⑶双积分型 特点:转换速度慢,转换时间几百μ s~几ms,抗干扰能力最强。
STC15W4K 系列单片机内部集成 8 通道10 位高速电压输入逐次比较型模拟数字转换器,采样速度最高可达 300KHz(30 万次/秒),可将连续变化的模拟电压转换为相应的数字信号,常用于温度检测、电池电压检测、距离检测、按键扫描等。 以上为STC15W4K 系列单片机 A/D 模拟数字转换模块结构图。 查询法的流程图。 中断法流程图。
以下为逐次逼近型A/D转换的相关程序。 1.主函数先是对相关变量的定义,对相关IO口的初始化(设置为准双向口模式),串口1的初始化(设置分频数和计数器口以及波特率),ADC函数初始化(选择采样的引脚以及采样的周期)。然后就是while死循环,在循环里面可以选择中断法程序,每当数据刷新时即可进行输出。
int main(void)
{
uint16_t xdata i = 0;
uint16_t xdata USER_ADC_Isr_Result_Backup = 256;
MCU_GPIO_All_Init();
MCU_Uart_1_Init_Isr(0, 0, 115200);
MCU_Adc_Init_Isr(0, 0);
while (1)
{
if (USER_ADC_Isr_Result_Backup != USER_ADC_Isr_Result)
{
USER_ADC_Isr_Result_Backup = USER_ADC_Isr_Result;
MCU_Uart_1_SendString("STC15W4K32S4 ADC测试:");
MCU_Uart_1_SendData(USER_ADC_Isr_Result_Backup % 1000 / 100 + 0x30);
MCU_Uart_1_SendString(".");
MCU_Uart_1_SendData(USER_ADC_Isr_Result_Backup % 100 / 10 + 0x30);
MCU_Uart_1_SendData(USER_ADC_Isr_Result_Backup % 10 + 0x30);
MCU_Uart_1_SendString("V\r\n");
}
}
}
ADC初始化函数。
void MCU_Adc_Init_Isr(uint8_t MCU_ADC_Ch, uint8_t MCU_ADC_Spped)
{
P1ASF = _crol_(0x01, MCU_ADC_Ch);
switch (MCU_ADC_Spped)
{
case 0:
MCU_ADC_Spped = 0x00;
break;
case 1:
MCU_ADC_Spped = 0x20;
break;
case 2:
MCU_ADC_Spped = 0x40;
break;
case 3:
MCU_ADC_Spped = 0x60;
break;
default:
MCU_ADC_Spped = 0x00;
break;
}
ADC_CONTR = 0X00;
ADC_CONTR |= MCU_ADC_Spped;
ADC_CONTR |= MCU_ADC_Ch;
ADC_CONTR |= ADC_POWER;
ADC_RES = 0;
ADC_RESL = 0;
SoftWare_Dealy_MS(10);
ADC_CONTR |= ADC_START;
EADC = 1;
EA = 1;
}
ADC中断函数。
void MCU_Adc_Isr() interrupt 5
{
static uint16_t xdata ADC_Temp = 0;
static float xdata Voltage = 0;
ADC_CONTR &= ~ADC_FLAG;
ADC_Temp = (ADC_RES << 2) | (ADC_RESL & 0X03);
Voltage = ADC_Temp * 0.00488;
USER_ADC_Isr_Result = (uint16_t)(Voltage * 100.0);
ADC_RES = 0;
ADC_RESL = 0;
ADC_CONTR |= ADC_START;
}
测试 通过自制的单片机板对程序进行测试。 当ADC引脚未接任何外设时的电压大概在3.85V左右。 当ADC引脚通过导线接入地时,如图所示,引脚电压降低至接近0V。 当ADC引脚通过导线接入VCC时,如图所示,引脚电压提升至接近5V。
测试完毕,证明改程序是可行的。
|