欢迎光临
我们一直在努力

8088 单板机 + ADC0808 的 C 语言版本程序

/*———————————————————-
程序名称:ADC0808 电压采集与数码管显示(C语言版)
硬件平台:8088 单板机 + ADC0808 + 8255
功能描述:采集 IN0 通道电压,转换为数字量后计算电压值,
通过 4 位数码管动态显示(单位:0.01V)
———————————————————-*/

#include <dos.h>
#include <conio.h>

/* 端口地址定义(根据实际硬件连接修改) */
#define ADC_BASE 0x80 /* ADC0808 片选端口(WR启动,RD读取) */
#define ADC_EOC 0x82 /* EOC 状态查询端口(bit0=1 表示转换完成) */
#define DISP_SEG 0x88 /* 数码管段码输出端口(8255 PA口) */
#define DISP_BIT 0x8A /* 数码管位选输出端口(8255 PB口) */
#define CTRL_8255 0x8C /* 8255 控制端口 */

/* 共阴数码管段码表(0-9) */
unsigned char code SegCode[10] = {
0x3F, 0x06, 0x5B, 0x4F, 0x66,
0x6D, 0x7D, 0x07, 0x7F, 0x6F
};

unsigned char AdcValue; /* ADC 原始值 0~255 */
unsigned int Voltage; /* 电压值(单位:0.01V),例如 500 = 5.00V */

/* 函数声明 */
void Init8255(void);
unsigned char ReadADC(unsigned char channel);
void DisplayVoltage(unsigned int voltage);
void Delay(unsigned int count);
void DelayShort(void);

/*———————————————————-
主函数
———————————————————-*/
void main(void)
{
Init8255(); /* 初始化 8255 */

while (!kbhit()) /* 按任意键退出循环 */
{
AdcValue = ReadADC(0); /* 读取通道 IN0 */

/* 电压换算公式:
Voltage(0.01V) = (AdcValue * 500) / 256
500 = 5.00V × 100 (转换为 0.01V 单位)
*/
Voltage = (unsigned int)((unsigned long)AdcValue * 500 / 256);

DisplayVoltage(Voltage); /* 数码管显示电压值 */

Delay(0xFFFF); /* 采样间隔控制 */
}
}

/*———————————————————-
8255 初始化:方式0,PA/PB 输出,PC 输入
———————————————————-*/
void Init8255(void)
{
outp(CTRL_8255, 0x82); /* 10000010B */
}

/*———————————————————-
读取指定 ADC 通道的转换结果(查询方式)
参数:channel = 0~7(选择 IN0~IN7)
返回:8 位 ADC 值(0~255)
———————————————————-*/
unsigned char ReadADC(unsigned char channel)
{
unsigned char result;

/* 1. 启动 ADC0808 转换 */
/* 注意:通道选择需通过 A、B、C 地址线实现,
这里简化处理,假设通道由硬件连线固定为 IN0 */
outp(ADC_BASE, 0x00); /* 写任意数据产生 START 脉冲 */

/* 2. 等待 EOC 变高(转换完成) */
while ((inp(ADC_EOC) & 0x01) == 0)
; /* 循环查询 */

/* 3. 读取转换结果 */
result = inp(ADC_BASE);

return result;
}

/*———————————————————-
数码管动态显示电压值(4 位显示,范围 0.00V ~ 5.00V)
输入:voltage(单位 0.01V,例如 500 表示 5.00V)
———————————————————-*/
void DisplayVoltage(unsigned int voltage)
{
unsigned char digit[4]; /* 存储 4 位显示数字 */
unsigned char i;
unsigned int temp;

/* 拆分 voltage 为 4 位数字
例如 voltage = 500
digit[0] = 5 (整数部分)
digit[1] = 0 (小数第一位)
digit[2] = 0 (小数第二位)
digit[3] = 0 (未使用,显示 0 或不显示)
*/
digit[0] = voltage / 100; /* 百位(整数部分 0~5) */
temp = voltage % 100;
digit[1] = temp / 10; /* 十位(小数第一位) */
digit[2] = temp % 10; /* 个位(小数第二位) */
digit[3] = 0; /* 第四位可显示单位 'U' 或熄灭 */

/* 动态扫描显示(每位显示约 2ms) */
for (i = 0; i < 4; i++)
{
/* 输出段码 */
outp(DISP_SEG, SegCode[digit[i]]);

/* 输出位选(假设共阴数码管,高电平选通) */
outp(DISP_BIT, (unsigned char)(1 << i));

DelayShort(); /* 短暂延时保持显示 */

/* 消隐(可选,防止重影) */
outp(DISP_SEG, 0x00);
}
}

/*———————————————————-
长延时函数(用于控制采样频率)
———————————————————-*/
void Delay(unsigned int count)
{
unsigned int i;
for (i = 0; i < count; i++)
; /* 空循环延时 */
}

/*———————————————————-
短延时函数(用于数码管扫描)
———————————————————-*/
void DelayShort(void)
{
unsigned int i;
for (i = 0; i < 100; i++)
;
}

使用说明与注意事项

1. 端口地址修改

根据你的实际硬件连接,修改开头的端口定义:

#define ADC_BASE 0x80 /* ADC0808 片选端口 */
#define ADC_EOC 0x82 /* EOC 状态端口(bit0) */
#define DISP_SEG 0x88 /* 数码管段码端口 */
#define DISP_BIT 0x8A /* 数码管位选端口 */
#define CTRL_8255 0x8C /* 8255 控制端口 */

2.电压换算精度说明

  • ADC 分辨率:5V / 256 ≈ 19.53 mV

  • 显示分辨率:0.01V

  • 最大误差:±19.53 mV(约 ±0.02V)

3 .如果需要多通道采集

修改 ReadADC 函数,增加通道选择逻辑:

unsigned char ReadADC(unsigned char channel)
{
/* 通过 8255 PC 口输出通道地址(A、B、C 引脚) */
unsigned char addr = channel & 0x07;
outp(ADC_ADDR, addr); /* 假设 ADC_ADDR 端口接 A/B/C 地址线 */

outp(ADC_BASE, 0x00); /* 启动转换 */
while ((inp(ADC_EOC) & 0x01) == 0);
return inp(ADC_BASE);
}

4. 软件滤波(提高稳定性)

在主循环中增加多次采样取平均:

unsigned int sum = 0;
unsigned char i;
for (i = 0; i < 8; i++)
sum += ReadADC(0);
AdcValue = sum / 8; /* 8 次平均 */

赞(0)
未经允许不得转载:171主机测评 » 8088 单板机 + ADC0808 的 C 语言版本程序
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址