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 状态查询端口bit01 表示转换完成 */ #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 初始化方式0PA/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.02V3 .如果需要多通道采集修改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 次平均 */