单片机 ADC0809模数转换实验
电路图如下:
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模数转换实验相关推荐
- 单片机adc0809模数转换实验c语言,实验ADC0809-0832模数转换实验.doc
实验ADC0809-0832模数转换实验 实验十三 ADC0809模数转换实验 一.实验目的 1.掌握ADC0809模/数转换芯片与单片机的连接方法及ADC0809的典型应用. 2.掌握用查询方式.中 ...
- 单片机adc0809模数转换实验c语言,单片机ADC0809模数转换实验
修改记录: 由LED显示模数转换的结果,改变成由四位数码管显示电压值 ----------------------------------------------------------------- ...
- 单片机adc0809模数转换实验c语言,单片机C语言程序设计:ADC0809 数模转换与显示...
/* 名称:ADC0809 数模转换与显示 说明:ADC0809 采样通道 3 输入的 模拟量,转换后的结果显示在数码管上. */ #include #define uchar unsigned c ...
- 51单片机 ADC0809模数转换与显示+Proteus仿真
51单片机 ADC0809模数转换与显示+Proteus仿真 Proteus仿真 实例代码 /*********************************/ #include <reg52 ...
- 51单片机 | ADC模数转换实验
文章目录 一.ADC介绍 1.ADC简介 2.ADC 转换原理 二.XPT2046 芯片介绍 三.硬件设计 四.软件设计 1.ADC 读写函数 2.主函数 五.实验现象 前面我们介绍的都是对数字信 ...
- 51单片机——ADC模数转换实验
目录 一.功能描述 二.ADC介绍 2.1 逐次逼近型ADC转换原理 2.2 ADC的主要技术指标 三.XPT2046芯片介绍 3.1 XPT2046外部引脚 3.2 XPT2046的命令字 3.3 ...
- 单片机开发应用技术实验装置QY-DPJ13A
一.装置简介 QY-DPJ13A单片机开发应用技术综合实验装置由控制屏.实验挂箱.实验桌组成,可完成单片机的接口扩展.数据采集.数据显示.键盘控制.定时器.打印机接口等实验,配备有仿真器.装置设有电流 ...
- adc0809 c语言程序,ADC0809 模数转换 89C52单片机C语言程序(电压表)
很不错的程序哦! ADC0809 模数转换 89C52单片机C语言程序 阅读108 评论0 字号:大中小 /**********[数字电压温度表]***********/ #include #defi ...
- adc0804模数转换实验报告_51单片机ADC0804模数转换学习
51 单片机 ADC0804 模数转换学习 数模转换器 ADC0804 与单片机连接的原理图: 这 TX-1C 实验板上的 ADC0804 和单片机连接的电路原理图. 左边的是 ADC0804 ,右边 ...
最新文章
- Oracle学习:事务的基本概念
- How Tomcat Works(二十)
- 【Python】文件夹的常用操作
- Python学习入门7:python学习从基础到高手,再到就业
- Shape Number (最小表示法)
- ZZ:SDNLAB技术分享(一):ODL的SFC入门和Demo
- 的文件夹结构_用framework7开发APP:6.目录结构
- WIN7 X64 下 VS2008升级补丁 (显示隐藏按钮)
- 58 同城 iOS 客户端 iOS11 及 iPhone X 适配实践
- Kylin 对维度表的的要求
- 排序算法性能和使用场景总结
- SecureCRT 超级终端 不能输入命令
- 2021年北京高考成绩排名查询,2021年北京高考各高中成绩及本科升学率数据排名及分析...
- 计算机如何手动新建服务启动项,电脑开机设置怎么设置启动项
- 计算机英语200心得体会,学英语的心得体会作文200字作文:学习英语的感受的英语作文(100~120词)...
- 哀其不幸,怒其不争!
- Python数据分析案例08——预测泰坦尼克号乘员的生存(机器学习全流程)
- python 拼音识别_python识别一段由字母组成的字符串是否是拼音
- 为什么软件系统上云是大势所趋?
- 发票查验平台验证码识别
热门文章
- L	No 114514
- (已解决)关于 WARNING: Ignoring invalid distribution -pencv-python .... 警告信息的处理方法
- 洛谷P5207 [WC2019]远古计算机
- 秋读|10本热门图书(人工智能、编程开发、架构、区块链等)免费送!
- 【USB接口电涌是什么故障】
- 2024秋招行测测评所用题库总结+测评题目解答思路和总结+测评题库汇总
- 微信开发踩坑系列一之Native支付
- 张家界国家森林公园、天门山、凤凰古城深度游攻略
- 中秋节礼品回收的暴利猫腻
- java 分布式事务总结