电路图如下:

1、简单描述ADC0809工作过程
ADC0809工作过程:
(1)把通道地址送到ADDA~ADDC上,选择一个模拟输入端。
(2)在通道地址信号有效期间,ALE上的上升沿把该地址锁存到内部地址锁存器。
(3)START引脚上的下降沿启动A/D转换。
(4)变换开始后EOC引脚呈现低电平,EOC重新变成高电平时表示转换结束。
(5)OE信号打开输出锁存器的三态门并送出转换结果。

2、在LCD1602上实现采样电压值的显示,输出参考下图(可自定义显示格式,但必须显示实际电压,精确到0.01V),修改程序。

编程思路:
1、首先程序开头:头文件申明,宏定义,端口定义,函数申明,变量定义

2、然后是主程序,在main()函数里面,首先对LCD1602显示屏和定时器0进行初始化,然后在while循环里面 输入转换通道数,开始转换,显示转换结果。

3、子函数的定义

3.1 输入转换通道号的函数adc_channel(bit ac,bit ab,bit aa)——分别对ADDC~ADDA赋值来选择一个模拟输入端。

3.2 ADC转换函数adc_change(void)——START下降沿启动转换,查询EOC为1时,因为ADC0809的输出数据连到P0口,

所以OE信号置1后,开始读P0 口,将读的数据赋给adc_data,最后OE置0。

3.3 定时器0控制ADC的CLK信号——定时器0的初始化 time_init():采用方式1,周期为200,启动定时器0,打开中断分开关和中断总开关;定时器0中断函数——因为采用的是方式1,所以要手动赋初值,然后clk信号取反,输出方波。

3.4 LCD显示信息函数display_data(uchar input)——显示器第一行利用dis_char函数分别显示转换数据的百、十、个位。第二行显示输入电压值,利用公式Vin=D500/256 将转换数据换成电压值,**这时一定要注意将Voltage的数据类型定义为long型 ,因为int型在计算D500可能会超过65536而溢出!!!**最后也利用dis_char函数分别显示电压的整数位和小数点后两位。

3.5 后面的延时函数delay(uint j),查忙函数check_busy(void),写控制指令函数 write_command(uchar com),写数据指令函数write_data(uchar dat),液晶屏初始化函数LCD_initial(void),输出字符串函数string(uchar ad,uchar *s),输出字符函数dis_char(uchar ad, uchar input) 因为是LCD1602显示器的一系列函数,所以就不说啦!!

代码如下:

/** 功能描述:  程序运行后,实现ADC一个通道的数据采样,并将采样结果送LCD显示 **/
#include <reg52.h>
#include <intrins.h>
#include <stdio.h>
#define uchar unsigned char
#define uint unsigned int
#define lcd_out P1
#define adc_data_port  P0
/***********端口定义********************************/
sbit rs=P2^0;
sbit rw=P2^1;
sbit e=P2^2;
sbit ADCCLK=P2^6;
sbit START=P2^3;
sbit EOC=P2^4;
sbit OE=P2^5;
sbit ADDA=P3^0;
sbit ADDB=P3^1;
sbit ADDC=P3^2;
/***********函数申明***********************************/
void check_busy(void);
void write_command(uchar com);
void write_data(uchar dat);
void LCD_initial(void);
void string(uchar ad ,uchar *s);
void dis_char(uchar ad, uchar input);void display_data(uchar input);
void lcd_test(void);
void delay(uint);void adc_change(void);
void adc_channel(bit ac,bit ab,bit aa);
void time_init();uchar  adc_data=0;   //存放ADC转换结果
/***********主程序***********************/
void main(void)
{   LCD_initial();               //LCD1602 初始化time_init();while(1){adc_channel(0,0,1);adc_change();display_data(adc_data);    delay(500); }
}
//输入转换通道号
void adc_channel(bit ac,bit ab,bit aa)
{  ADDC=ac;ADDB=ab;ADDA=aa;}
//开始转换
void adc_change(void)
{OE=0;START=0;START=1;START=0;while(EOC==0);adc_data_port=0x0ff;OE=1;adc_data=adc_data_port;OE=0;
}
//定时器0控制ADC的CLK信号
void time_init(){TMOD=0x01;TH0=(65536-200)/256;TL0=(65536-200)%256;ET0=1;EA=1;TR0=1;
}
void timer0()interrupt 1
{   TH0=(65535-200)/256; TL0=(65535-200)%256; ADCCLK=~ADCCLK;
}
//LCD显示信息
void display_data(uchar input){long voltage;dis_char(0x0d,input/100+0x30);dis_char(0x0e,input/10%10+0x30);dis_char(0x0f,input%10+0x30);voltage = input;voltage = voltage*500/255;dis_char(0x4a,voltage/100+0x30);dis_char(0x4b,'.');dis_char(0x4c,voltage/10%10+0x30);dis_char(0x4d,voltage%10+0x30);dis_char(0x4e,'V');}
//1ms延时程序
void delay(uint j)
{uchar i=250;for(;j>0;j--){while(--i);i=249;    }
}
//查忙程序
void check_busy(void)
{uchar dt;do{dt=0xff;e=0;rs=0;   rw=1;e=1;dt=lcd_out;}while(dt&0x80);e=0;
}
//写控制指令
void write_command(uchar com)
{check_busy();e=0;rs=0;rw=0;lcd_out=com;e=1;_nop_();e=0;delay(1);
}
//写数据指令
void write_data(uchar dat)
{check_busy();e=0;rs=1;rw=0;lcd_out=dat;e=1;_nop_();e=0;delay(1);
}
//液晶屏初始化
void LCD_initial(void)
{write_command(0x38);//8位总线,双行显示,5X7的点阵字符write_command(0x0C);//开整体显示,光标关,无黑块write_command(0x06);//光标右移write_command(0x01);//清屏delay(1);string(0x00,"ADC0809 ch1=");   //显示字符串string(0x40,"Voltage = ");  //显示字符串
}
//输出字符串
void string(uchar ad,uchar *s)
{write_command(ad+0x80); //ad是显示位置信息while(*s>0){write_data(*s++);delay(100);}
}
// 输出字符void dis_char(uchar ad, uchar input){write_command(ad+0x80);write_data(input);delay(10);}

3、利用定时器1的定时中断,实现ADC通道3每隔1s转换一次,并将模拟电压值送LCD1602显示。

编程思路:
大体思路和第二问差不多。所以这里只说不同点。

这里增加了一个定时器1控制通道3转换时间为1s。

1、首先对定时计数器1进行初始化,因为要控制通道3的转换时间为1s=200us*5000。
所以利用定时器1的方式2,这时一定要注意!!! 因为Timer1工作在方式2,Timer0工作在方式1,所以在选择模式的时候一定要一起配置,即TMOD=0x21(如果分开在各自的子函数里面初始化TMOD=0x20,TMOD=0x01就会出错)。溢出周期为200,设置初值TH1=0-200,TL1=0-200。然后PT1=0(低级),这是因为定时器0中断控制ADC的CLK信号,所以PT0=1(高级)。程序里面有两个中断,最好分下高低级。最后启动定时器1,打开中断分开关和中断总开关。

2、定时器1中断函数里面来进行counter的软件计数,中断一次counter++。转换在主程序里面做,避免中断耗时太长。

3、主函数main() 先配置T0,T1的模式,TMOD=0x21,然后对LCD1602、T0和T1进行初始化。在while循环里面,先输入通道数,然后对中断函数中counter进判断,如果counter==5000,就开始AD转换,并把counter清零,同时也把数字和电压清屏,在显示器上给人一种1s变化一次的感觉。最后调用显示函数 将数字和电压显示出来。

代码如下:

/** 功能描述:  程序运行后,实现ADC一个通道的数据采样,并将采样结果送LCD显示 **/
#include <reg52.h>
#include <intrins.h>
#include <stdio.h>
#define uchar unsigned char
#define uint unsigned int
#define lcd_out P1
#define adc_data_port  P0
/***********端口定义********************************/
sbit rs=P2^0;
sbit rw=P2^1;
sbit e=P2^2;
sbit ADCCLK=P2^6;
sbit START=P2^3;
sbit EOC=P2^4;
sbit OE=P2^5;
sbit ADDA=P3^0;
sbit ADDB=P3^1;
sbit ADDC=P3^2;
/***********函数申明***********************************/
void check_busy(void);
void write_command(uchar com);
void write_data(uchar dat);
void LCD_initial(void);
void string(uchar ad ,uchar *s);
void dis_char(uchar ad, uchar input);void display_data(uchar input);
void delay(uint);void adc_change(void);
void adc_channel(uchar ch);
void time0_init();
void time1_init();uchar  adc_data=0;   //存放ADC转换结果uint counter=0;//软件计数timer1中断次数uchar channel_num=0;//通道数
/***********主程序***********************/
void main(void)
{   TMOD=0x21;LCD_initial();                //LCD1602 初始化time0_init();time1_init();while(1){channel_num=3;adc_channel(channel_num);if(counter>=5000){counter=0;string(0x0d,"     ");//数字清屏string(0x4a,"     ");//电压清屏adc_change();      //开始转换}display_data(adc_data); }
}
//输入转换通道号
// set ADC channel
void adc_channel(uchar ch)
{ch = ch%0x07;ADDA=0;if(ch&0x01)ADDA=1;ADDB=0;if(ch&0x02)ADDB=1;ADDC=0;if(ch&0x04)ADDC=1;}
//开始转换
void adc_change(void)
{OE=0;START=0;START=1;START=0;while(EOC==0);adc_data_port=0x0ff;OE=1;adc_data=adc_data_port;OE=0;
}
//定时器1控制通道3转换时间
void time1_init(){TH1=0-200;TL1=0-200;PT1=0;ET1=1;EA=1;TR1=1;
}
void timer1() interrupt 3
{counter++;}
//定时器0控制ADC的CLK信号
void time0_init(){TH0=(65536-200)/256;TL0=(65536-200)%256;PT0=1;//设为高级ET0=1;EA=1;TR0=1;
}
void timer0()interrupt 1
{   TH0=(65535-200)/256; TL0=(65535-200)%256; ADCCLK=~ADCCLK;
}
//LCD显示信息
void display_data(uchar input){long voltage;dis_char(0x0a,channel_num+0x30);//显示通道数string(0x0b,"= ");//显示数字dis_char(0x0d,input/100+0x30);dis_char(0x0e,input/10%10+0x30);dis_char(0x0f,input%10+0x30);voltage = input;voltage = voltage*500/255;//显示电压dis_char(0x4a,voltage/100+0x30);dis_char(0x4b,'.');dis_char(0x4c,voltage/10%10+0x30);dis_char(0x4d,voltage%10+0x30);dis_char(0x4e,'V');}
//1ms延时程序
void delay(uint j)
{uchar i=250;for(;j>0;j--){while(--i);i=249;    }
}
//查忙程序
void check_busy(void)
{uchar dt;do{dt=0xff;e=0;rs=0;   rw=1;e=1;dt=lcd_out;}while(dt&0x80);e=0;
}
//写控制指令
void write_command(uchar com)
{check_busy();e=0;rs=0;rw=0;lcd_out=com;e=1;_nop_();e=0;delay(1);
}
//写数据指令
void write_data(uchar dat)
{check_busy();e=0;rs=1;rw=0;lcd_out=dat;e=1;_nop_();e=0;delay(1);
}
//液晶屏初始化
void LCD_initial(void)
{write_command(0x38);//8位总线,双行显示,5X7的点阵字符write_command(0x0C);//开整体显示,光标关,无黑块write_command(0x06);//光标右移write_command(0x01);//清屏delay(1);string(0x00,"ADC0809 ch");   //显示字符串string(0x40,"Voltage = ");  //显示字符串
}
//输出字符串
void string(uchar ad,uchar *s)
{write_command(ad+0x80); //ad是显示位置信息while(*s>0){write_data(*s++);delay(100);}
}
// 输出字符void dis_char(uchar ad, uchar input){write_command(ad+0x80);//ad是显示位置信息write_data(input);delay(10);}

单片机 ADC0809模数转换实验相关推荐

  1. 单片机adc0809模数转换实验c语言,实验ADC0809-0832模数转换实验.doc

    实验ADC0809-0832模数转换实验 实验十三 ADC0809模数转换实验 一.实验目的 1.掌握ADC0809模/数转换芯片与单片机的连接方法及ADC0809的典型应用. 2.掌握用查询方式.中 ...

  2. 单片机adc0809模数转换实验c语言,单片机ADC0809模数转换实验

    修改记录: 由LED显示模数转换的结果,改变成由四位数码管显示电压值 ----------------------------------------------------------------- ...

  3. 单片机adc0809模数转换实验c语言,单片机C语言程序设计:ADC0809 数模转换与显示...

    /*  名称:ADC0809 数模转换与显示 说明:ADC0809 采样通道 3 输入的 模拟量,转换后的结果显示在数码管上. */ #include #define uchar unsigned c ...

  4. 51单片机 ADC0809模数转换与显示+Proteus仿真

    51单片机 ADC0809模数转换与显示+Proteus仿真 Proteus仿真 实例代码 /*********************************/ #include <reg52 ...

  5. 51单片机 | ADC模数转换实验

    文章目录 一.ADC介绍 1.ADC简介 2.ADC 转换原理 二.XPT2046 芯片介绍 三.硬件设计 四.软件设计 1.ADC 读写函数 2.主函数 五.实验现象   前面我们介绍的都是对数字信 ...

  6. 51单片机——ADC模数转换实验

    目录 一.功能描述 二.ADC介绍 2.1 逐次逼近型ADC转换原理 2.2 ADC的主要技术指标 三.XPT2046芯片介绍 3.1 XPT2046外部引脚 3.2 XPT2046的命令字 3.3 ...

  7. 单片机开发应用技术实验装置QY-DPJ13A

    一.装置简介 QY-DPJ13A单片机开发应用技术综合实验装置由控制屏.实验挂箱.实验桌组成,可完成单片机的接口扩展.数据采集.数据显示.键盘控制.定时器.打印机接口等实验,配备有仿真器.装置设有电流 ...

  8. adc0809 c语言程序,ADC0809 模数转换 89C52单片机C语言程序(电压表)

    很不错的程序哦! ADC0809 模数转换 89C52单片机C语言程序 阅读108 评论0 字号:大中小 /**********[数字电压温度表]***********/ #include #defi ...

  9. adc0804模数转换实验报告_51单片机ADC0804模数转换学习

    51 单片机 ADC0804 模数转换学习 数模转换器 ADC0804 与单片机连接的原理图: 这 TX-1C 实验板上的 ADC0804 和单片机连接的电路原理图. 左边的是 ADC0804 ,右边 ...

最新文章

  1. Oracle学习:事务的基本概念
  2. How Tomcat Works(二十)
  3. 【Python】文件夹的常用操作
  4. Python学习入门7:python学习从基础到高手,再到就业
  5. Shape Number (最小表示法)
  6. ZZ:SDNLAB技术分享(一):ODL的SFC入门和Demo
  7. 的文件夹结构_用framework7开发APP:6.目录结构
  8. WIN7 X64 下 VS2008升级补丁 (显示隐藏按钮)
  9. 58 同城 iOS 客户端 iOS11 及 iPhone X 适配实践
  10. Kylin 对维度表的的要求
  11. 排序算法性能和使用场景总结
  12. SecureCRT 超级终端 不能输入命令
  13. 2021年北京高考成绩排名查询,2021年北京高考各高中成绩及本科升学率数据排名及分析...
  14. 计算机如何手动新建服务启动项,电脑开机设置怎么设置启动项
  15. 计算机英语200心得体会,学英语的心得体会作文200字作文:学习英语的感受的英语作文(100~120词)...
  16. 哀其不幸,怒其不争!
  17. Python数据分析案例08——预测泰坦尼克号乘员的生存(机器学习全流程)
  18. python 拼音识别_python识别一段由字母组成的字符串是否是拼音
  19. 为什么软件系统上云是大势所趋?
  20. 发票查验平台验证码识别

热门文章

  1. L No 114514
  2. (已解决)关于 WARNING: Ignoring invalid distribution -pencv-python .... 警告信息的处理方法
  3. 洛谷P5207 [WC2019]远古计算机
  4. 秋读|10本热门图书(人工智能、编程开发、架构、区块链等)免费送!
  5. 【USB接口电涌是什么故障】
  6. 2024秋招行测测评所用题库总结+测评题目解答思路和总结+测评题库汇总
  7. 微信开发踩坑系列一之Native支付
  8. 张家界国家森林公园、天门山、凤凰古城深度游攻略
  9. 中秋节礼品回收的暴利猫腻
  10. java 分布式事务总结