单片机实验——利用AD完成电压测量及显示
ADC08_09电压测量实验(基于查询、中断两种方式的数据读取)
·数字电压表1.实验任务利用单片机STC89C52与ADC0809设计一个数字电压表,能够测量0-5V之间的直流电压值,两位数码显示。
2.现有元件模数转换器ADC0809,STC89C52单片机,两个共阴极数码管。
3.硬件设计3.1模数转换器ADC0809与单片机STC89C52的连接(1) ADC0809规格及引脚分配图如下图3-1所示:图3-1 ADC0809引脚图(2) STC89C52各个引脚分布如下图3-2所示:图3-2 STC89C52引脚图(3) 硬件连线(a) 把“单片机系统”区域中的P3.0与”模数转换模块ADC0809“区域中的ST端子用导线相连接。
(b) 把“单片机系统”区域中的P3.1与”模数转换模块ADC0809“区域中的ALE端子用导线相连接。
(c) 把“单片机系统”区域中的P3.2与”模数转换模块ADC0809“区域中的EOC端子用导线相连接。
(d) 把“单片机系统”区域中的P3.6与”模数转换模块ADC0809“区域中的OE端子用导线相连接。
(e) 把“单片机系统”区域中的P3.7与”模数转换模块ADC0809“区域中的CLK端子用导线相连接。
(f) 把“模数转换模块ADC0809”区域中的ADDA、ADDB、ADDC端子用导线连接到单片机的VCC端子上。
把“模数转换模块ADC0809”区域中IN7与外接输入电压相连。
(g) 把“单片机系统”区域中的P2.0-P2.7连接到“模数转换模块ADC0809”区域中D0D1D2D3D4D5D6D7端子上。
(h) 把“单片机系统”区域中的P1.0-P1.7连接到“数码管”区域中ABCDEFGH端子上,且在P1.0-P1.7上分别接上0.5KΩ的上拉电阻。
把“单片机系统”区域中的P0.0-P0.1分别连接到两个共阴极“数码管”的GND。
4. 电路原理图图4 电路原理图5. 程序设计内容由于ADC0809在进行A/D转换时需要CLK信号,而此时ADC0809的CLK是接在单片机的P3.7口,也就是要求从P3.7输出CLK信号供ADC0809使用。
电压采集,AD转换程序,数码管显示
电压采集,AD转换程序,数码管显示#include#includesbit ADC_CS=P3^5; //片选引脚,低电平有效sbit ADC_CLK=P3^4; //ADC0832芯片的时钟输入引脚sbit ADC_DO=P3^3; //数据信号输出引脚,用于将转换的数据输给单片机sbit ADC_DI=P3^3; //数据信号输入引脚,用于通道的选择控制#define DataPort P0 //定义数据端口程序中遇到DataPort 则用P0 替换sbit LATCH1=P2^2;//定义锁存使能端口段锁存sbit LATCH2=P2^3;// 位锁存void Delay(unsigned char x);unsigned char ReadADC(viod);unsigned char TempData[8]; //存储显示值的全局变量unsigned char code dofly_DuanMa[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x 7f,0x6f};// 显示段码值0~9unsigned char code dofly_WeiMa[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//分别对应相应的数码管点亮,即位码void Display(unsigned char FirstBit,unsigned char Num);void main(){unsigned char a;a=ReadADC();while(1){TempData[0]=dofly_DuanMa[a/100];//分解显示信息,如要显示68,则68/10=6 68%10=8TempData[1]=dofly_DuanMa[(a%100)/10];TempData[2]=dofly_DuanMa[(a%100)%10];Display(2,3);}}// 延时函数void Delay(unsigned char x){unsigned char i;for(i=0;i<x;i--);}// 把模拟电压转换成八位二进制数,并返回unsigned char ReadADC(unsigned char b){unsigned char i,ch;ch=0;ADC_CS=0; //片选引脚,低电平有效,ADC_DO=0; //DO为高阻状态for(i=0;i<10;i++); //稍做延时ADC_CLK=0;Delay(2); //以上那个为准备工作ADC_DI=1;ADC_CLK=1;Delay(2); //第一个脉冲,起始位ADC_CLK=0;Delay(2);ADC_DI=1;ADC_CLK=1;Delay(2); //第2个脉冲,DI=1表示双通道单极性输入ADC_CLK=0;Delay(2);ADC_DI=1;ADC_CLK=1;Delay(2); //第3个脉冲,DI=1表示表示选择CH1,马上准备读取转换数据ADC_CLK=1;Delay(2);ADC_CLK=0;Delay(2);for(i=0;i<8;i++){ADC_CLK=1;Delay(2);ADC_CLK=0;Delay(2);ch=(ch<<1)|ADC_DO;}ADC_CS=1; //取消片选,一个转换周期结束return(ch);}void Display(unsigned char FirstBit,unsigned char Num) {unsigned char i;for(i=0;i<num;i++){DataPort=0; //清空数据,防止有交替重影LATCH1=1; //段锁存LATCH1=0;DataPort=dofly_WeiMa[i+FirstBit]; //取位码LATCH2=1; //位锁存LATCH2=0;DataPort=T empData[i]; //取显示数据,段码LATCH1=1; //段锁存LATCH1=0;Delay(200); // 扫描间隙延时,时间太长会闪烁,太短会造成重影}}</num;i++)</x;i--);。
STM32内部AD采样实现简易电压表(同时显示直流电压波形)
//内部AD可显示正确的电压值。
oh ye ah!调了我两天呀!总算调出来了yeah!//我第一个想到的就是与大家一起分享我的程序。
oh ye ah!还请各位大侠多多指教呀!大家一起学习交流。
/*********************************************************************** ********* F ile N ame :main.c* A uthor :Wuhan R&DCente r, Em best* Dat e Fir st Is sued : 08/08/2008* Desc ripti on : Mai n pro grambody************************************************************************ ********//* Incl udes------------------------------------------------------------------*/#inclu de "s tm32f10x_l ib.h"#inc lude"stdio.h"//#inc lude"moni tor.h"/************ 用于定义ITMViewe r相关的I TM激励寄存器端口************************//*#d efine ITM_Port8(n) (*((vola tileunsig ned c har *)(0xE0000000+4*n)))#defi ne IT M_Por t16(n) (*((vo latil e uns igned shor t*)(0xE0000000+4*n)))#de fineITM_P ort32(n) (*((volat ile u nsign ed lo ng *)(0xE0000000+4*n)))#defi ne DE MCR (*((vo latil e uns igned long *)(0xE000EDFC)))#d efine TRCE NA 0x01000000*//*用于定义是否使用ITMViewe r*///#def ine D BG_IT M /* P rivat e typ edef-----------------------------------------------------------*//*Priva te de fine------------------------------------------------------------*/#d efine ADC1_DR_A ddres s ((u32)0x4001244C)fl oat A D_val ue;i nt AD_valu e1;//stat ic un signe d lon g tic ks;//unsi gnedcharClock1s;u8 adc_1[10]={0};//用来存放经AD C转换后的电压值的每一位数值。
STC单片机内部ADC采集电压用数码管显示
STC单片机内部ADC采集电压用数码管显示////////////////////////////////////////////////////////////////////////////////////////////////////// ///特点:/// ///1、数码管显示用中断方式/// ///2、STC12C5A60S2内ADC采样电压值,先采样30次然后去掉上下10个再取平均值/// ///3、采集数据用串口发送到PC /// ///------------------------------------------------------------------------shenzhen---iqss----2011/02/23--------/// //////////////////////////////////////////////////////////////////////////////////////////////////////#include <reg51.h>#define uchar unsigned char#define uint unsigned int#define segp P0#define scanp P2uchar code tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82, 0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e}; //不带点段驱动信号uchar code tab_d[]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10}; //带点段驱动uchar code scan[]={0xfe,0xfd,0xfb,0xf7}; //位扫描驱动信号uint display[4]={0,0,0,0}; //初始显示数字uint con=0, _data=0,data2=0; //con显示循环变量_data为ADC采样值临时变量data显示数据临时变量sfr P1ASF=0x9d; //下面五行为ADC定义sfr ADC_CONTR=0xbc;sfr ADC_RES=0xbd;sfr ADC_RESL=0xbe;sfr AUXR1=0xa2;void t0_t1_init(); //t0显示扫描定时器和t1串口比特率定时器初始化函数void adc_init(); //adc初始化函数void uart_out(uchar byte); //串口发送字节函数uint average(uint buffer[30]); //采样数据处理函数void AD(); //电压采样30次函数void delay1ms(uchar x); //延时函数void main(){t0_t1_init();adc_init();while(1){AD();}}/////////定时器初始化///////void t0_t1_init(){ SCON=0x50;PCON=0;TMOD=0x21;TH1=TL1=0xe6;TH0=0xf0;TL0=0x60;EA=ET0=1;// ES=1;TR1=1;TR0=1;}/////ADC初始化///////void adc_init(){ P1ASF=0x01; //启动P10为ADC模拟输入口把内部上拉电阻断开AUXR1 &= 0xfb; //adrj_0 高8位在ADC_RESADC_RES=0; //初值ADC_CONTR=0x80; //开启ADC电源SPEED_1_1,chs000(选择AD采样通道p10) delay1ms(2);// IE|=0xa0;}//////采集30次电压值//////void AD(){ char i;uint temp_buf[30]={0};for(i=0;i<30;i++){ ADC_CONTR |=0x08; //开启转换while((ADC_CONTR&0x10)==0);ADC_CONTR &=0xe7; //清除标志temp_buf[i]=ADC_RES; //取出数值到temp_buf}_data=average(temp_buf); //采样30次后的数据代入处理函数处理后返回处理后的数值,给下面用串口发送出去uart_out(_data);}/////先对整个数组的三十个值进行从小到大的排列,/////////再去掉最大5个和最少5个再求平均值;函数返回temp值///uint average(uint buffer[30]){uchar i,j;uint temp;for(i=1; i<30; i++)for(j=29; j>=i; --j){if(buffer[j-1] > buffer[j]){temp = buffer[j-1];buffer[j-1] = buffer[j];buffer[j] = temp;}}temp = 0;for(i=5; i<25; i++){temp += buffer[i];}temp = (uint)(((float)temp) / 20 + 0.5);return(temp);}///显示数据处理及扫描显示中断服务函数//// void t0_4ms(void) interrupt 1{data2=_data;data2=_data*19.53;display[3]=tab_d[data2/1000];display[2]=tab[(data2/100)%10];display[1]=tab[(data2/10)%10];display[0]=tab[data2%10];TH0=0xf0;TL0=0x60;if(++con==5) con=1;// segp=0xff;segp=display[con-1];scanp=scan[con-1];}///串口发送节字函数////void uart_out(uchar byte){ SBUF=byte;while(TI==0);TI=0;}///1ms延时////void delay1ms(uchar x){ uchar i,j;for(i=0;i<x;i++)for(j=0;j<250;j++); }。
STM32 ADC电压测试实验报告
STM32 ADC电压测试实验报告一、实验目的1.了解STM32的基本工作原理2. 通过实践来加深对ARM芯片级程序开发的理解3.利用STM32的ADC1通道0来采样外部电压值值,并在TFTLCD模块上显示出来二、实验原理STM32拥有1~3个ADC,这些ADC可以独立使用,也可以使用双重模式(提高采样率)。
STM32的ADC是12位逐次逼近型的模拟数字转换器。
它有18个通道,可测量16个外部和2个内部信号源。
各通道的A/D转换可以单次、连续、扫描或间断模式执行。
ADC的结果可以左对齐或右对齐方式存储在16位数据寄存器中接下来,我们介绍一下执行规则通道的单次转换,需要用到的ADC寄存器。
第一个要介绍的是ADC控制寄存器(ADC_CR1和ADC_CR2)。
ADC_CR1的各位描述如下:ADC_CR1的SCAN位,该位用于设置扫描模式,由软件设置和清除,如果设置为1,则使用扫描模式,如果为0,则关闭扫描模式,ADC_CR1[19:16]用于设置ADC的操作模式我们要使用的是独立模式,所以设置这几位为0就可以了。
第二个寄存器ADC_CR2,该寄存器的各位描述如下:ADCON位用于开关AD转换器。
而CONT位用于设置是否进行连续转换,我们使用单次转换,所以CONT位必须为0。
CAL和RSTCAL用于AD校准。
ALIGN用于设置数据对齐,我们使用右对齐,该位设置为0。
EXTSEL[2:0]用于选择启动规则转换组转换的外部事件,我们这里使用的是软件触发(SWSTART),所以设置这3个位为111。
第三个要介绍的是ADC采样事件寄存器(ADC_SMPR1和ADC_SMPR2),这两个寄存器用于设置通道0~17的采样时间,每个通道占用3个位对于每个要转换的通道,采样时间建议尽量长一点,以获得较高的准确度,但是这样会降低ADC的转换速率。
ADC的转换时间可以由下式计算:Tcovn=采样时间+12.5个周期第四个要介绍的是ADC规则序列寄存器(ADC_SQR1~3),第五个要介绍的是ADC规则数据寄存器(ADC_DR)。
课题九 AD简易数字电压表
void main() { ulong AD_ad=0; float AD_Data=0.0; lcd1602init(); //液晶初始化 while(1) { AD_ad = read1543(0); //0 - - - - 第0号通道 (0--10) AD_Data = ((float)AD_ad)*JiZhun_AD/1024+0.0005; AD_ad = AD_Data*1000; ad_result[4]=(AD_ad%10)+'0'; ad_result[3]=((AD_ad/10)%10)+'0'; ad_result[2]=((AD_ad/100)%10)+'0'; ad_result[1]='.'; ad_result[0]=(AD_ad/1000)+'0'; lcd_string(ad_result,1); //显示AD转换结果 lcd_string(bbb,2); } }
作业题
1、如何用TLC1543转换后的电压用LCD1602显 示出来。
#include<at89x52.h> #include<INTRINS.h> #define uint unsigned int #define uchar unsigned char #define ulong unsigned long #define CLOCK P2_4 #define D_IN P2_3 #define D_OUT P2_5 #define _CS P2_6 sbit en=P2^2; sbit rs=P2^0; sbit rw=P2^1; uchar ad_result[16]={0}; //AD转换结果 uchar bbb[]={"AD(TLC1543) TEST"}; float JiZhun_AD=2.5; void delay(uint z) { uint x,y; for (x=z;x>0;x--) for(y=110;y>0;y--); }
STC单片机内部ADC采集电压用数码管显示
STC单片机内部ADC采集电压用数码管显示////////////////////////////////////////////////////////////////////////////////////////////////////// ///特点:/// ///1、数码管显示用中断方式/// ///2、STC12C5A60S2内ADC采样电压值,先采样30次然后去掉上下10个再取平均值/// ///3、采集数据用串口发送到PC /// ///------------------------------------------------------------------------shenzhen---iqss----2011/02/23--------/// //////////////////////////////////////////////////////////////////////////////////////////////////////#include <reg51.h>#define uchar unsigned char#define uint unsigned int#define segp P0#define scanp P2uchar code tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82, 0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e}; //不带点段驱动信号uchar code tab_d[]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10}; //带点段驱动uchar code scan[]={0xfe,0xfd,0xfb,0xf7}; //位扫描驱动信号uint display[4]={0,0,0,0}; //初始显示数字uint con=0, _data=0,data2=0; //con显示循环变量_data为ADC采样值临时变量data显示数据临时变量sfr P1ASF=0x9d; //下面五行为ADC定义sfr ADC_CONTR=0xbc;sfr ADC_RES=0xbd;sfr ADC_RESL=0xbe;sfr AUXR1=0xa2;void t0_t1_init(); //t0显示扫描定时器和t1串口比特率定时器初始化函数void adc_init(); //adc初始化函数void uart_out(uchar byte); //串口发送字节函数uint average(uint buffer[30]); //采样数据处理函数void AD(); //电压采样30次函数void delay1ms(uchar x); //延时函数void main(){t0_t1_init();adc_init();while(1){AD();}}/////////定时器初始化///////void t0_t1_init(){ SCON=0x50;PCON=0;TMOD=0x21;TH1=TL1=0xe6;TH0=0xf0;TL0=0x60;EA=ET0=1;// ES=1;TR1=1;TR0=1;}/////ADC初始化///////void adc_init(){ P1ASF=0x01; //启动P10为ADC模拟输入口把内部上拉电阻断开AUXR1 &= 0xfb; //adrj_0 高8位在ADC_RESADC_RES=0; //初值ADC_CONTR=0x80; //开启ADC电源SPEED_1_1,chs000(选择AD采样通道p10) delay1ms(2);// IE|=0xa0;}//////采集30次电压值//////void AD(){ char i;uint temp_buf[30]={0};for(i=0;i<30;i++){ ADC_CONTR |=0x08; //开启转换while((ADC_CONTR&0x10)==0);ADC_CONTR &=0xe7; //清除标志temp_buf[i]=ADC_RES; //取出数值到temp_buf}_data=average(temp_buf); //采样30次后的数据代入处理函数处理后返回处理后的数值,给下面用串口发送出去uart_out(_data);}/////先对整个数组的三十个值进行从小到大的排列,/////////再去掉最大5个和最少5个再求平均值;函数返回temp值///uint average(uint buffer[30]){uchar i,j;uint temp;for(i=1; i<30; i++)for(j=29; j>=i; --j){if(buffer[j-1] > buffer[j]){temp = buffer[j-1];buffer[j-1] = buffer[j];buffer[j] = temp;}}temp = 0;for(i=5; i<25; i++){temp += buffer[i];}temp = (uint)(((float)temp) / 20 + 0.5);return(temp);}///显示数据处理及扫描显示中断服务函数//// void t0_4ms(void) interrupt 1{data2=_data;data2=_data*19.53;display[3]=tab_d[data2/1000];display[2]=tab[(data2/100)%10];display[1]=tab[(data2/10)%10];display[0]=tab[data2%10];TH0=0xf0;TL0=0x60;if(++con==5) con=1;// segp=0xff;segp=display[con-1];scanp=scan[con-1];}///串口发送节字函数////void uart_out(uchar byte){ SBUF=byte;while(TI==0);TI=0;}///1ms延时////void delay1ms(uchar x){ uchar i,j;for(i=0;i<x;i++)for(j=0;j<250;j++); }。
程序ADC0809模拟检测电压数码管显示
程序/*---------------------------------------------------------------------------------名称:ADC0808模拟检测电压数码管显示编写:人言者007日期:2013.5.20说明:ADC0808的其中两路去检测电压,电压范围0~5V, 电压用电阻器调节模拟出来。
检测到模拟电压转化为数字量后转变为16进制在数码管中显示,每两位数码管显示一路电压的数字量,声明:显示的数不是实际电压,只是与电压呈现性关系。
----------------------------------------------------------------------------------*/#include<reg52.h>#define uchar unsigned char#define uint unsigned intuchar temp,dianya0,dianya1;uchar code LED[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; //共阴数码管断码0~9~a~fuchar disbuff[4]; //显示缓冲器(数组)sbit clk=P3^3; // 芯sbit EOC=P3^2; // 片sbit OE=P3^0; // 引sbit start=P3^1; // 脚sbit adress_A=P3^4; // 定// 义void delay(uint z){while(z--);}void timer0init(){TMOD=0x01; //设置定时器0为工作方式1TH0=(65536-1)/256; //定时器0高八位赋值1us中断一次TL0=(65536-1)%256; //定时器0低八位赋值EA=1; //开总中断ET0=1; //开定时器0中断TR0=1; //启动定时器0void display(){// disbuff[0]=dianya%10; //个位// disbuff[1]=dianya/10%10; //十// disbuff[2]=dianya/100%10; //百// disbuff[3]=dianya/1000; // 千P2=0xfe; //打开第一个数码管P0=LED[disbuff[3]]; //给数码管送数据(段码)delay(60); //延时,防止数码管重影P2=0xfd; // 以P0=LED[disbuff[2]]; // 下delay(60); // 功P2=0xfb; // 能P0=LED[disbuff[1]]; // 类delay(60); // 同P2=0xf7;P0=LED[disbuff[0]];delay(60);}void main(){timer0init(); //定时器0初始化while(1){adress_A=0; //打开通道0delay(10); //延时等待芯片反应start=1; //开始ADC转换// while(!EOC); //等待转换完成标志(未知原因,此语句导致数码管不能显示)OE=1; //输出允许P1=0XFF; //输入前P1口需置1dianya0=P1; //AD转换完成,读取值OE=0; //关闭输出start=0; //关闭AD转换disbuff[0]=dianya0%16;//将二进制数据转换为16进制低位disbuff[1]=dianya0/16;//将二进制数据转换为16进制高位delay(10); //延时等待芯片反应adress_A=1; //打开通道1delay(10);start=1;OE=1;// while(!EOC);P1=0XFF;dianya1=P1;OE=0;start=0;disbuff[2]=dianya1%16;disbuff[3]=dianya1/16;display(); //显示}}void timer0() interrupt 1{TH0=(65536-1)/256; //重装初值TL0=(65536-1)%256;clk=~clk; //模拟给ADC0808提供时钟}硬件图(protues仿真)。
基于51单片机之ADC0808电压显示
基于 51 单片机之 ADC0808 电压显示
指导老师: 姓 名: 学 号: 班 级:
ADC0809 中文资料
ADC0809 是带有 8 位 A/D 转换器、8 路多路开关以及微处理机兼容的控 制逻辑的 CMOS 组件。它是 逐次逼近式 A/D 转换器,可以和单片机直接接口。
(1)ADC0809 的内部逻辑结构
数字量T 上跳沿时,所有内部寄存器清零;下跳沿时, 开始进行 A/D 转换;
在转换期间,ST 应保持低电平。EOC 为转换结束信号。当 EOC 为高电 平时,表明转换结束;否则,表明正在进行 A/D 转换。OE 为输出允许信号, 用于控制三条输出锁存器向单片机输出转换得到的数据。OE=1,输出转换得到 的数据;OE=0,输出数据线呈高阻状态。D7-D0 为数字量输出线。CLK 为 时钟输入信号线。因 ADC0809 的内部没有时钟电路,所需时钟信号必须由外 界提供,通常使用频率为 500KHZ,VREF(+),VREF(-)为参考电压输入。
由下图可知,ADC0809 由一个 8 路模拟开关、一个地址锁存与译码器、 一个 A/D 转换器和一个三态输出锁存器组成。多路开关可选通 8 个模拟通道, 允许 8 路模拟量分时输入,共用 A/D 转换器进行转换。三态输出锁器用于锁存 A/D 转换完的数字量,当 OE 端为高电平时,才可以从三态输出锁存器取走转 换完的数据。
(2). ADC0809 引脚结构
ADC0809 各脚功能如下: D7-D0:8 位数字量输出引脚。 IN0-IN7:8 位模拟量输入引脚。 VCC:+5V 工作电压。 GND:地。 REF(+):参考电压正端。 REF(-):参考电压负端。 START:A/D 转换启动信号输入端。 ALE:地址锁存允许信号输入端。 (以上两种信号用于启动 A/D 转换). EOC:转换结束信号输出引脚,开始转换时为低电平,当转换结束时为高电 平。 OE:输出允许控制端,用以打开三态数据输出锁存器。
实验七:内置ADC做数字电压表
因此:ADCSRA=0xc6; 使用 ADC 模块,最重要就是这两个寄存器的配置,实际上,单片机内部的模块的使用 方法与此大同小异,主要工作在于配置内部寄存器,这种方法一定要掌握。 另外,ADC 模块启动后,第一次转换的结果不准确应舍弃。 ADC 模块介绍到此,回到开发板,开发板上方有一个多圈电位器,接在 VCC 构成一个 分压器,如下图:
Vx 1024 ,AVCC 的实测电压为 4.69V,因此 AVCC
4690 N (mV ) 4.59 N (mV ) 。 1024
USB 电压为 5.0V,进入开发板时经过了一个 1N5819 防逆二极管,1N5819 导通压降约 0.3V,因此实际供电电压只有 4.7V 左右。实验时,不同电脑的 USB 电压略有不同,直接用 以上计算公式误差不大,如果要更高精度,自行用万用表测量 AVCC,修正计算公式。
Editor:*轩辕十四* Created date:2010-2-3
-2-
华南理工大学无线电爱好者协会
AVR-R&D
V2.1
QQ 群:63191815
• Bit 6 – ADSC: ADC 开始转换 在单次转换模式下,ADSC 置位将启动一次ADC 转换。在连续转换模式下,ADSC 置位 将启动首次转换。第一次转换( 在ADC 启动之后置位ADSC,或者在使能ADC 的同时置位 ADSC) 需要25 个ADC 时钟周期,而不是正常情况下的13 个。第一次转换执行ADC初始 化的工作。在转换进行过程中读取ADSC 的返回值为"1”,直到转换结束。ADSC 清零不产 生任何动作。这一位是转换标志位,通过置位来启动,并判断是否转换结束。 • Bit 5 – ADATE: ADC 自动触发使能 ADATE置位将启动ADC自动触发功能。触发信号的上跳沿启动ADC转换。触发信号源通过 SFIOR 寄存器的ADC 触发信号源选择位ADTS 设置。这里单次转换,不需要自动触发, 置0。 • Bit 4 – ADIF: ADC 中断标志 在ADC 转换结束,且数据寄存器被更新后, ADIF 置位。如果ADIE 及SREG 中的全局 中断使能位I 也置位,ADC 转换结束中断服务程序即得以执行,同时ADIF 硬件清零。此 外,还可以通过向此标志写1 来清ADIF。要注意的是,如果对ADCSRA 进行读-修改-写 操作,那么待处理的中断会被禁止。这也适用于SBI 及CBI 指令。本实验不需中断,置0。 • Bit 3 – ADIE: ADC 中断使能 若ADIE 及SREG 的位I 置位, ADC 转换结束中断即被使能。这里不需中断,置0。 • Bits 2:0 – ADPS2:0: ADC 预分频器选择位 由这几位来确定XTAL 与ADC 输入时钟之间的分频因子,决定ADC转换速度。转换速度为 ADC时钟/13,对于15ksps的转换速度,需要195kHz的时钟源,本实验晶振为12MHz,进行64 分频恰好。即ADPS2..0:110。
课程设计AD590单片机测量与显示
摘要所要设计的为AD590温度传感器,并通过A/D转换器输出数字信号,并通过单片机编程,最后通过LED显示器显示当前温度。
本文介绍了基于AD590与89c51单片机的一种温度搜集系统,该电路采纳ADC0809作为A/D转换元件,将AD590搜集的模拟温度信号转化为数字信号,传输到单片机内部,最后老是用共阴极LED显示出来,温度测量范围0℃~99℃,小数点后显示一名。
要求能够正确的显示温度传感器的温度。
利用3位LED模块显示,显示测量温度数值。
本系统要紧包括大模块:数据搜集模块、操纵模块、A/D转换模块、显示模块。
第一绘制出工作流程图,然后连接好硬件电路,写入汇编程序,并进行调试,最终设计完成了该系统的硬件电路。
在软件编程上,采纳了汇编语言进行编程,利用了显示模块程序、转换数据存取程序、A/D转换程序。
其结构框图如图1:图1关键字:电压放大 A/D 转换 LED显示单片机编程目录第1章设计方案 (3)1.1 AD590 (3)1.2 AD0809 (5)1.3 LED温度显示电路 (5)第2章程序设计 (6)2.1 程序框图 (6)2.2 程序 (7)第三章心得体会 (12)参考文献 (13)第一章设计方案1 AD590测量热力学温度、摄氏温度、两点温度差、多点最低温度、多点平均温度的具体电路,普遍应用于不同的温度操纵场合由于AD590精度高、价钱低、不需辅助电源、线性好,经常使用于测温和热电偶的冷端补偿。
AD590温度传感器是单片集成两头感温电流源,测温范围为-55℃~+150℃,其电源电压可在4V~6V范围转变,能够经受44V正向电压和20V反向电压,因此器件反接也可不能被损坏。
AD590产生的电流与绝对温度成正比,它有超级好的线性输出性能,温度每增加1℃,其电流增加1μA。
因此在室温25℃时,其输出电流Iout=(273+25)=298μA。
其线性表如表1:摄氏温度AD590电流经10KΩ电压0℃273.2 uA V10℃283.2 uA 2.832 V20℃293.2 uA 2.932 V30℃303.2 uA 3.032 V40℃313.2 uA 3.132 V50℃323.2 uA 3.232 V60℃333.2 uA 3.332 V100℃373.2 uA 3.732 V表1实验室所提供的电位器最大值为5伏,咱们需通过发达器放大,而依照输出电压通过单片机后,最终由LED 显示器显示相应的温度。
单片机实验——利用AD完成电压测量及显示
单片机实验——利用AD完成电压测量及显示1.实验目的(1)掌握A/D转换器的基本原理和使用方法。
(2)掌握二进制数和BCD码之间的数值转换方法。
2.预习要点(1)A/D转换器的基本原理和使用方法(2)二进制数和BCD码之间的数值转换方法3.实验设备计算机、单片机实验箱,万用表。
4.实验内容基本要求:利用电位器,在0~5V范围调节A/D转换器0809的输入端ADIN3的电压,在显示电路上显示00~50数值。
扩展要求:相同输入条件下,在显示电路上显示-25~+24的数值实验6ORG 0000HSJMP MAIN;****************************************************;主程序ORG 0030HMAIN:MOV SP,#70H;显示缓存区MOV 32H,#11 ;为了兼容之前的显示程序,所以就通过改变MOV 33H,#11 ;字型的方式让第3-8个数码管不亮,只显示前两位MOV 34H,#11MOV 35H,#11MOV 36H,#11MOV 37H,#11;初始化8155MOV DPTR,#0100HMOV A,#03HMOVX @DPTR,ALOOP:MOV DPTR,#6000H ;AD的地址,应接CS3MOV A,#00H ;选择通道0 IN0MOVX @DPTR,A ;启动AD,开始转换LCALL DELAY ;延时,等待转换完成,一般转换时间为100us左右LCALL ADCON ;读取数据并处理LCALL DISPLAY ;数码管显示SJMP LOOP;*****************************************;读取数据并处理子程序ADCON:MOVX A,@DPTR ;读取AD的输出XMOV B,#51 ;把00H-FFH之间的数据转换为0-50的数据DIV AB ;这个我会给大家讲讲,很简单的,这里就不注释了MOV 30H,AMOV A,BMOV B,#5DIV ABMOV 31H,ARET;*************************************;显示子程序DISPLAY:MOV R0,#30HMOV R3,#0FEHLD0:MOV DPTR,#0102H ;送字位MOV A,R3MOVX @DPTR,AMOV DPTR,#DTAB ;查表,送字形MOV A,@R0MOVC A,@A+DPTRMOV DPTR,#0101HMOVX @DPTR,ALCALL DELAYINC R0MOV A,R3JNB ACC.7,LD1RL AMOV R3,ALJMP LD0LD1:RET;***********************************************;字形表DTAB:DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH ;数字0-9DB 40H,00H ;40H为" - " 00H为不亮;**********************************************;延时1msDELAY:MOV R7,#02HDEL1:MOV R6,#0FFHDEL2:DJNZ R6,DEL2DJNZ R7,DEL1RET;**********************************************;显示子程序(另一种);这里给大家写本实验的另一种显示方法:;这种方法就是30H和31H分别写显示程序,显示完31H之后就;退出程序,很easy的啦,大家还可以多多试试自己编写别的程序;注:本子程序在主程序中并没有调用DISPLAY1:MOV DPTR,#0102HMOV A,#0BFHMOVX @DPTR,AMOV DPTR,#DTABMOV A,30HMOVC A,@A+DPTRMOV DPTR,#0101HMOVX @DPTR,ALCALL DELAYMOV DPTR,#0102HMOV A,#7FHMOVX @DPTR,AMOV DPTR,#DTABMOV A,31HMOVC A,@A+DPTRMOV DPTR,#0101HMOVX @DPTR,ALCALL DELAYRET;**********************************************;实验6扩展ORG 0000HSJMP MAIN;*********************************************;主程序ORG 0030HMAIN:MOV SP,#70H;显示缓存区MOV 32H,#11 ;为了兼容之前的显示程序,所以就通过改变MOV 33H,#11 ;字型的方式让第3-8个数码管不亮,只显示前两位MOV 34H,#11MOV 35H,#11MOV 36H,#11MOV 37H,#11;初始化8155MOV DPTR,#0100HMOV A,#03HMOVX @DPTR,ALOOP:MOV DPTR,#6000H ;;AD的地址,应接CS3MOV A,#00H ;选择通道0 IN0MOVX @DPTR,A ;启动AD,开始转换LCALL DELAY ;延时,等待转换完成,一般转换时间为100us左右LCALL ADCON ;读取数据并处理LCALL DISPLAY ;数码管显示SJMP LOOP;***************************************;AD数据读取并处理子程序ADCON:MOVX A,@DPTR ;读取AD的输出XCJNE A,#128,NEXT ;产生CyNEXT:JC NEXT1 ;判断要转化为0-25还是-25-0,然后决定要不要加负号CLR C ;因为后面用到减法,所以先要清零CySUBB A,#128MOV 30H,#11 ;为0-25之间,符号位什么都不显示SJMP NEXT2NEXT1:CLR C ;因为后面用到减法,所以先要清零CyMOV 62H,AMOV A,#128SUBB A,62HMOV 30H,#10 ;为-25-0之间,符号位显示负号NEXT2:MOV B,#51 ;下面是把0-128的数转换为0-25的数,十位存到31H 里,各位存到32H里DIV AB ;这个和实验6一样的MOV 31H,AMOV A,BMOV B,#5DIV ABMOV 32H,ARET;*************************************;显示子程序DISPLAY:MOV R0,#30HMOV R3,#0FEHLD0:MOV DPTR,#0102H ;送字位MOV A,R3MOVX @DPTR,AMOV DPTR,#DTAB ;查表,送字形MOV A,@R0MOVC A,@A+DPTRMOV DPTR,#0101HMOVX @DPTR,ALCALL DELAYINC R0MOV A,R3JNB ACC.7,LD1RL AMOV R3,ALJMP LD0LD1:RET;***********************************************;字形表DTAB:DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH ;数字0-9DB 40H,00H ;40H为“" 00H为不亮;**********************************************;延时1msDELAY:MOV R7,#02HDEL1:MOV R6,#0FFHDEL2:DJNZ R6,DEL2DJNZ R7,DEL1RET;**********************************************。
adc0809电压采样并用数码管显示
//P2=0xfb;P0=table[ad1] ;xiaoshudian=0;delay(2);
//P2=0xfd;P0=table[ad2] ;delay(2);
//P2=0xfe;P0=table[ad3] ;delay(2);
A;P0=table[ad0];delay(2);//送数码管显示
B;P0=table[ad1];xiaoshudian=0;delay(2);
C;P0=table[ad2];delay(2);
D;P0=table[ad3];delay(2);
}
}
步进0.01V,误差0.01V。
改进:1.可改用液晶显示,进而增加可显示范围
2.可加键盘,完成通道的步进
**********************************************************************************************************/
dispbuf[1]=(temp/100)%10;
dispbuf[0]=(temp/10)%10;
*/
ad0=(temp/1000)%10;//分离数据
ad1=(temp/100)%10;
ad2=(temp/10)%10;
ad3=(temp/1)%10;
/********************************************************************************************************************************
while(!eoc);//等待转换结束
[说明]使用AD采集电压显示在LCD
使用AD采集电压显示在LCD/********************************************************** ******************* 文件名:AD_CAIYANG.C* 功能:使用AD采集电压显示在LCD* 说明:转自网络,本人验证通过*********************************************************** *****************/#include<STC12C5A60S2.H>#define uint unsigned int#define uchar unsigned charsbit CS=P2^0; //LCD12864串行通信片选sbit SID=P2^1; //LCD12864串行通信数据口sbit SCLK=P2^2; //LCD12864串行通信同步时钟信号sbit PSB=P2^5; //LCD12864并/串选择:H并行 L串行unsigned int temp1,sh1,ge1,n1,m1;unsigned char ad_result_data[10]; //AD转换高八位unsigned char ad_result_low2[10]; //AD转换低八位unsigned char ad_result_total[10]; //AD转换总十位unsigned char ad_average_result; //AD转换十次的平均值unsigned char Ain,Vin;unsigned char b,t,R;char tp=0;unsigned char code ma1[6]={0xb5,0xe7,0xd1,0xb9,0xa1,0xc3}; //电压:unsigned char code ma2[]={"."};uchar code disp1[]={"提示: 按1 键进入"};uchar code disp2[]={"功能选择界面. "};unsigned char code num0[]={0xa3,0xb0};unsigned char code num1[]={0xa3,0xb1};unsigned char code num2[]={0xa3,0xb2};unsigned char code num3[]={0xa3,0xb3};unsigned char code num4[]={0xa3,0xb4};unsigned char code num5[]={0xa3,0xb5};unsigned char code num6[]={0xa3,0xb6};unsigned char code num7[]={0xa3,0xb7};unsigned char code num8[]={0xa3,0xb8};unsigned char code num9[]={0xa3,0xb9};//-------模块延时程序---------------------------- 1msvoid delay1ms(uint delay1ms) //STC11F60XE,22.1184M,延时1ms{uint i,j;for(;delay1ms>0;delay1ms--)for(i=0;i<7;i++)for(j=0;j<210;j++);}void delay(uint delay) //STC11F60XE,22.1184M,延时170us {uint i,j;for(;delay>0;delay--)for(i=0;i<124;i++);for(j=0;j<124;j++);}/*******************************************************AD转换程序*******************************************************/void AD_initiate() //初始化函数{ES=0;TMOD=0x21; //定时计数器方式控制寄存器,"自动重装,16位计数器".SCON=0x50; //串行控制寄存器,方便在串口助手那观察TH1=0xfa;TL1=0xfa;TR1=1;}void ADC_Power_On() //AD转换电{ADC_CONTR|=0x80;delay(5); //必要的延时}void get_ad_result() //取AD结果函数,它是十位AD转换,每十次平均,最后取低八位作为AD采样数据{uint i,q=0;for(i=0;i<10;i++){tp=0;ADC_RES=0; //高八位数据清零,STC12C5A60S2 AD数据寄存名与STC12C54××系列不同ADC_RESL=0; //低两位清零ADC_CONTR|=0x08; //启动AD转换while(!tp) //判断AD转换是否完成{tp=0x10;tp&=ADC_CONTR;}ADC_CONTR&=0xe7;ad_average_result=ADC_RES;q=q+ad_average_result;}ad_average_result=q/10;//ad_average_result=ad_average_result*4*5000/1024;}/************************AD转换结束***********************/void send_ad_result() //取AD结果函数发送到串口,方便调试{SBUF=n1;while(TI==0) ;TI=0;delay1ms(100);//SBUF=R>>4;}//---------------------电压采样程序-------------------------void caiyangP10() //测电压{P1M0|=0x01; //设P1_0为开漏模式如: P1_0= #00000000BP1M1|=0x01;ADC_CONTR=0xe0; //设置P1.0为输入AD转换口delay(2);get_ad_result(); //取转换数据Vin=ad_average_result;R=Vin;}/*-----------写控制字到LCD12864------------*/void write_cmd(uchar cmd){uchar i;uchar i_data;i_data=0xf8; //命令控制字:11111000写指令 11111010写数据 11111100读状态 11111110读数据CS=1; //片选置高,才能进行读写操作SCLK=0;/*----------写命令控制字-----------------*/for(i=0;i<8;i++) //循环八次,每次读取一位数据{SID=(bit)(i_data&0x80); //bit表示取其最高位SCLK=0;SCLK=1; //正跳变写入指令i_data=i_data<<1; //左移一位}/*---------------------------------------*//*----------写指令高四位-----------------*/i_data=cmd;i_data=i_data&0xf0; //把低四位置0for(i=0;i<8;i++) //循环八次,每次读取一位数据{SID=(bit)(i_data&0x80); //bit表示取其最高位SCLK=0;SCLK=1; //正跳变写入指令i_data=i_data<<1; //左移一位}/*---------------------------------------*//*----------写指令低四位-----------------*/i_data=cmd;i_data=i_data<<4; //左移四位,把低四位的数据移到高四位,再把低四位置0for(i=0;i<8;i++) //循环八次,每次读取一位数据{SID=(bit)(i_data&0x80); //bit表示取其最高位SCLK=0;SCLK=1; //正跳变写入指令i_data=i_data<<1; //左移一位}/*-----------------------------------------*/CS=0; //把片选置低delay1ms(5); //延时是因为没有进行忙检测,适当的延时可以不进行忙检测}/*-----------------------------------------*//*------------写数据到LCD12864-------------*/void write_dat(uchar dat){uchar i;uchar i_data;i_data=0xfa;CS=1;for(i=0;i<8;i++){SID=(bit)(i_data&0x80); SCLK=0;SCLK=1;i_data=i_data<<1;}i_data=dat;i_data=i_data&0xf0;for(i=0;i<8;i++){SID=(bit)(i_data&0x80); SCLK=0;SCLK=1;i_data=i_data<<1;}i_data=dat;i_data=i_data<<4;for(i=0;i<8;i++){SID=(bit)(i_data&0x80); SCLK=0;SCLK=1;i_data=i_data<<1;}CS=0;delay1ms(5);}/*-----------------------------------------*//*--------------显示坐标-------------------*/void lcd_pos(uchar x,uchar y) //汉字显示坐标,x为哪一行,y为哪一列{uchar pos;if(x==0)x=0x80; //第一行else if(x==1)x=0x90; //第二行else if(x==2)x=0x88; //第三行else if(x==3)x=0x98; //第四行pos=x+y; //显示哪一行(总共有4行)哪一竖(总共有8竖,每16列为1竖)write_cmd(pos);}/*-----------------------------------------*//*--------------显示8个汉字-------------------*/void disp_hanzi(uchar code *chn){uchar i;write_cmd(0x30); //基本指令操作方式for(i=0;i<16;i++) //16列*8个汉字=128(刚好)write_dat(chn[i]);}/*-----------------------------------------*//*--------------显示数字-------------------*/void disp_num(uchar code *chn){uchar i;write_cmd(0x30); //基本指令操作方式for(i=0;i<2;i++) //1个数字write_dat(chn[i]);}void disp_number(uchar num){switch(num){case 0: disp_num(num0);break;case 1: disp_num(num1);break;case 2: disp_num(num2);break;case 3: disp_num(num3);break;case 4: disp_num(num4);break;case 5: disp_num(num5);break;case 6: disp_num(num6);break;case 7: disp_num(num7);break;case 8: disp_num(num8);break;case 9: disp_num(num9);break;default: break;}}/*----------- --LCD初始化------------------*/void lcd_init(){PSB=0;write_cmd(0x30); //基本指令write_cmd(0x02); //地址归位write_cmd(0x06); //游标右移write_cmd(0x0c); //整体显示write_cmd(0x01); //清屏}/*-----------------------------------------*/void displayP10(){float ad1;//unsigned int temp1,sh1,ge1,n1,m1;//uchar code dis2[]={0x01,0x02,0x00};//ad1=x*7.8125; //电压修正uchar i;ad1=Vin*3.9608; //具体线性参数由输入电压值调整,该值的测量范围为0-10.00V,5V左右的测量比较准确,//两端的最大误差为70mv,其他一般在40mv以内temp1=(int)ad1;sh1=temp1/1000; //十位ge1=(temp1%1000)/100; //个位n1=((temp1%1000)%100)/10; //小数点后一位m1=((temp1%1000)%100)%10; //小数点后二位//write_cmd(0x01);write_cmd(0x30); //基本指令操作方式lcd_pos(0,0);for(i=0;i<6;i++) write_dat(ma1[i]);lcd_pos(0,3);disp_number(sh1);lcd_pos(0,4);disp_number(ge1);lcd_pos(0,5);for(i=0;i<2;i++) write_dat(ma2[i]);lcd_pos(0,6);disp_number(n1);lcd_pos(0,7);disp_number(m1);/*lcd_pos(2,0);disp_hanzi(disp1);lcd_pos(3,0);disp_hanzi(disp2);*/}void main(){EA=1;AD_initiate(); //初始化ADC_Power_On(); //开AD电源//init();lcd_init();delay(10);while(1){caiyangP10(); //测电压 send_ad_result();//Vin=Vin*4007;displayP10();delay(10);}}。
电压精准测量实验报告(3篇)
第1篇一、实验目的本实验旨在研究STM32L476单片机在电池供电较低情况下,如何通过HAL库编程和DMA多通道采集ADC,实现对外部电池电压的精准测量。
实验重点在于解决电池供电低于外部校准电压时,ADC采集不准确的问题,并通过内部基准修正技术提高测量精度。
二、实验原理1. ADC原理:模数转换器(ADC)将模拟信号转换为数字信号,用于测量电压等物理量。
STM32L476单片机内置12位ADC,能够将模拟电压转换为数字值。
2. DMA多通道采集:直接内存访问(DMA)是一种高速数据传输技术,允许ADC在单个转换周期内连续采集多个通道的数据,提高采集效率。
3. 内部基准修正:STM32L476单片机内部具有基准电压源,可以通过调整内部基准电压,修正因电池供电低导致的ADC采集误差。
三、实验设备1. STM32L476G-DISCOVERY开发板2. 3.6V电池3. 7.2V通信电池4. LCD点阵液晶屏5. 二极管6. 稳压芯片7. 万用表四、实验步骤1. 搭建实验电路:将电池、二极管、稳压芯片和STM32L476开发板连接成电路,确保电路稳定可靠。
2. 编程:a. 使用HAL库编程,配置ADC为12位单次转换模式。
b. 设置DMA为多通道采集模式,连续采集多个通道的电压数据。
c. 使用内部基准修正功能,调整内部基准电压,修正采集误差。
3. 测试:a. 使用万用表测量电池电压,确保实验条件符合要求。
b. 在不同电池电压下,观察LCD点阵液晶屏显示的电压值,验证测量精度。
c. 比较开启背光灯和关闭背光灯时的电压采集结果,分析误差原因。
五、实验结果与分析1. 电压采集结果:在电池电压为3.2V时,ADC采集到的电压值约为3.2V,测量精度较高。
2. 误差分析:a. 开启背光灯时,电压采集结果偏高,原因是背光灯电流较大,导致接入板子的电压降低。
b. 电池供电低于外部校准电压时,ADC采集误差较大,通过内部基准修正功能,可以有效降低误差。
实验六 并行AD实验(数字电压表实验)
实验六并行AD实验(数字电压表实验)一、实验目的与要求1、了解几种类型AD转换的原理;掌握使用ADC0809进行模数转换2、认真预习实验内容,做好准备工作,完成实验报告。
二、实验设备STAR系列实验仪一套、PC机一台、万用表一个。
三、实验内容1、ADC0809(G4区)(1) 模数转换器,8位精度,8路转换通道,1路并行输出(2) 转换时间100us,转换电压范围0~5V2、编写程序:制作一个电压表,测量0~5V,结果显示于数码管上。
四、实验原理图五、实验步骤2、调节0~5V电位器(D2区)输出电压,显示在LED(最右边2位)上的电压数字量会随之改变。
用万用表验证AD转换的结果。
六、演示程序.MODEL TINYADDR_0809 EQU 0F000HEXTRN Display8:NEAR.STACK 100.DATABUFFER DB 8 DUP(?)LastAD DB 0 ;上一次AD转换值.CODESTART: MOV AX,@DATAMOV DS,AXNOPXOR AL,ALJMP START6START1: MOV CX,50 ;采样五十次MOV BX,0 ;累计五十次的采样值START2: CALL AD0809XOR AH,AHADD BX,AXLOOP START2MOV AX,50XCHG AX,BXDIV BL ;五十次的平均值CMP AL,LastADJZ START3START6: MOV LastAD,ALCALL Display_DataLEA SI,BUFFERCALL Display8START3: CALL DLTimeJMP START1AD0809 PROC NEARPUSH CXMOV AL,0MOV DX,ADDR_0809OUT DX,ALMOV CX,200LOOP $ ;延时,等待AD转换完成MOV DX,ADDR_0809IN AL,DXPOP CXRETAD0809 ENDPDISPLAY_DATA PROC NEARMOV AH,ALAND AL,0FHMOV BUFFER + 4,ALMOV AL,AHAND AL,0F0HROR AL,4MOV BUFFER + 5,ALMOV AL,AHXOR AH,AHMOV BL,51 ;255/51 (16进制的1 = 1/51V)DIV BLOR AL,80H ;加上小数点MOV BUFFER + 2,ALMOV AL,10MUL AHDIV BLMOV BUFFER + 1,AL ;第一位小数MOV AL,10MUL AHDIV BLMOV BUFFER,AL ;第二位小数MOV buffer+3,10HMOV buffer+6,10HMOV buffer+7,10H ;消隐RETDISPLAY_DATA ENDPDLTime PROC NEARMOV CX,30000LOOP $RETDLTime ENDPEND START七、实验扩展及思考如何实现多路模拟量的数据采集、显示?。
《单片机原理与应用》实验报告09-ADC电压采样实验
《单片机原理与应用》实验报告实验序号:09 实验项目名称: AD实验学号姓名专业、班实验地点实验楼1#416 指导教师实验时间2015-15-09 一、实验目的1.了解KEIL C51 集成开发环境及软件仿真;2. 掌握单片机烧写方法;3. 认识AD芯片(PCF8591);4. 认识光敏电阻和热敏电阻。
二、实验设备(环境)及要求硬件:PC机,51单片机开发板;软件:PC机操作系统windows XP,KEIL C51集成开发环境。
三、实验内容与步骤利用PCF8591芯片,读取热敏电阻温度或光敏电阻的光照强度,把它显示上数码管上。
四、实验结果与数据处理五、分析与讨论当使热敏电阻温度或光敏电阻的光照强度改变时,数码管显示的数字即发生变化六、教师评语成绩签名:日期:/*=======================================================文件名: PCF8591_AD.c描述: AD采集温度,光照强度变化-----------------------------------------------------------------------------------------------------------*/#include <reg52.h>#include "digitron_drv.h"#include "IIC_drv.h"#include "PCF8591_AD_drv.h"/**********************************************功能:数码管显示输入参数:Data: 数据输出参数:无返回值:**********************************************/void Display(unsigned int Data1,unsigned int Data2){DigShowNumber(8,Data1/100,0);DigShowNumber(7,Data1%100/10,0);DigShowNumber(6,Data1%10,0);DigShowNumber(3,Data2/100,0);DigShowNumber(2,Data2%100/10,0);DigShowNumber(1,Data2%10,0);}/*---------------------------------------------------------------------------------------------------------*//**********************************************主函数**********************************************/void main(){unsigned char model;unsigned char hot,light;while(1){model=model_set(anlog_output_off,anlog_model_0,auto_increment_off,anlog_channel_0);hot = ReadIIC(0x90,model);model= model_set(anlog_output_off,anlog_model_0,auto_increment_off,anlog_channel_1);light = ReadIIC(0x90,model);Display(hot,light);}}。
8051F330ADC电压测量串口显示程序
8051F330ADC电压测量串⼝显⽰程序/************************************************************************************//* 实验平台:C8051F330核⼼板 + 外接电位器/* 功能说明:1、串⼝波特率设置为115200,使⽤外部晶振22.1184MHz;/* 2、程序将P1.5配置为模拟输⼊,⽤作AD转换。
/*/* 电位器的中⼼抽头⽤杜邦线连接P1.5,另外两端分别接3.3V与GND,/* 引脚浮空时,测量到的电压将会随机波动。
/* 3、测量到的电压值在串⼝输出中实时更新。
(单位mV);/************************************************************************************/#include "main.h"#define SYSCLK 22118400UL //采⽤外部晶振时,系统的时钟频率为22118400hz bit uartPrintFlag=0;unsigned int voltageData=0;/********************************************************************函数功能:延时函数。
⼊⼝参数:x:循环次数。
返回:⽆。
备注:⽆。
********************************************************************/void Delay (unsigned int x){while(--x);}//////////////////////////Pino Electronics////////////////////////////********************************************************************函数功能:将外部晶振配置为系统时钟。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
单片机实验——利用AD完成电压测量及显示
1.实验目的
(1)掌握A/D转换器的基本原理和使用方法。
(2)掌握二进制数和BCD码之间的数值转换方法。
2.预习要点
(1)A/D转换器的基本原理和使用方法
(2)二进制数和BCD码之间的数值转换方法
3.实验设备
计算机、单片机实验箱,万用表。
4.实验内容
基本要求:
利用电位器,在0~5V范围调节A/D转换器0809的输入端ADIN3的电压,在显示电路上显示00~50数值。
扩展要求:
相同输入条件下,在显示电路上显示-25~+24的数值
实验6
ORG 0000H
SJMP MAIN
;****************************************************
;主程序
ORG 0030H
MAIN:MOV SP,#70H
;显示缓存区
MOV 32H,#11 ;为了兼容之前的显示程序,所以就通过改变
MOV 33H,#11 ;字型的方式让第3-8个数码管不亮,只显示前两位
MOV 34H,#11
MOV 35H,#11
MOV 36H,#11
MOV 37H,#11
;初始化8155
MOV DPTR,#0100H
MOV A,#03H
MOVX @DPTR,A
LOOP:MOV DPTR,#6000H ;AD的地址,应接CS3
MOV A,#00H ;选择通道0 IN0
MOVX @DPTR,A ;启动AD,开始转换
LCALL DELAY ;延时,等待转换完成,一般转换时间为100us左右
LCALL ADCON ;读取数据并处理
LCALL DISPLAY ;数码管显示
SJMP LOOP
;*****************************************
;读取数据并处理子程序
ADCON:
MOVX A,@DPTR ;读取AD的输出X
MOV B,#51 ;把00H-FFH之间的数据转换为0-50的数据
DIV AB ;这个我会给大家讲讲,很简单的,这里就不注释了
MOV 30H,A
MOV A,B
MOV B,#5
DIV AB
MOV 31H,A
RET
;*************************************
;显示子程序
DISPLAY:
MOV R0,#30H
MOV R3,#0FEH
LD0:MOV DPTR,#0102H ;送字位
MOV A,R3
MOVX @DPTR,A
MOV DPTR,#DTAB ;查表,送字形
MOV A,@R0
MOVC A,@A+DPTR
MOV DPTR,#0101H
MOVX @DPTR,A
LCALL DELAY
INC R0
MOV A,R3
JNB ACC.7,LD1
RL A
MOV R3,A
LJMP LD0
LD1:RET
;***********************************************
;字形表
DTAB:
DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH ;数字0-9
DB 40H,00H ;40H为" - " 00H为不亮;**********************************************
;延时1ms
DELAY:
MOV R7,#02H
DEL1:MOV R6,#0FFH
DEL2:DJNZ R6,DEL2
DJNZ R7,DEL1
RET
;**********************************************
;显示子程序(另一种)
;这里给大家写本实验的另一种显示方法:
;这种方法就是30H和31H分别写显示程序,显示完31H之后就
;退出程序,很easy的啦,大家还可以多多试试自己编写别的程序
;注:本子程序在主程序中并没有调用
DISPLAY1:
MOV DPTR,#0102H
MOV A,#0BFH
MOVX @DPTR,A
MOV DPTR,#DTAB
MOV A,30H
MOVC A,@A+DPTR
MOV DPTR,#0101H
MOVX @DPTR,A
LCALL DELAY
MOV DPTR,#0102H
MOV A,#7FH
MOVX @DPTR,A
MOV DPTR,#DTAB
MOV A,31H
MOVC A,@A+DPTR
MOV DPTR,#0101H
MOVX @DPTR,A
LCALL DELAY
RET
;**********************************************
;实验6扩展
ORG 0000H
SJMP MAIN
;*********************************************
;主程序
ORG 0030H
MAIN:MOV SP,#70H
;显示缓存区
MOV 32H,#11 ;为了兼容之前的显示程序,所以就通过改变
MOV 33H,#11 ;字型的方式让第3-8个数码管不亮,只显示前两位
MOV 34H,#11
MOV 35H,#11
MOV 36H,#11
MOV 37H,#11
;初始化8155
MOV DPTR,#0100H
MOV A,#03H
MOVX @DPTR,A
LOOP:MOV DPTR,#6000H ;;AD的地址,应接CS3
MOV A,#00H ;选择通道0 IN0
MOVX @DPTR,A ;启动AD,开始转换
LCALL DELAY ;延时,等待转换完成,一般转换时间为100us左右
LCALL ADCON ;读取数据并处理
LCALL DISPLAY ;数码管显示
SJMP LOOP
;***************************************
;AD数据读取并处理子程序
ADCON:MOVX A,@DPTR ;读取AD的输出X
CJNE A,#128,NEXT ;产生Cy
NEXT:JC NEXT1 ;判断要转化为0-25还是-25-0,然后决定要不要加负号CLR C ;因为后面用到减法,所以先要清零Cy
SUBB A,#128
MOV 30H,#11 ;为0-25之间,符号位什么都不显示
SJMP NEXT2
NEXT1:CLR C ;因为后面用到减法,所以先要清零Cy
MOV 62H,A
MOV A,#128
SUBB A,62H
MOV 30H,#10 ;为-25-0之间,符号位显示负号
NEXT2:MOV B,#51 ;下面是把0-128的数转换为0-25的数,十位存到31H 里,各位存到32H里
DIV AB ;这个和实验6一样的
MOV 31H,A
MOV A,B
MOV B,#5
DIV AB
MOV 32H,A
RET
;*************************************
;显示子程序
DISPLAY:
MOV R0,#30H
MOV R3,#0FEH
LD0:MOV DPTR,#0102H ;送字位
MOV A,R3
MOVX @DPTR,A
MOV DPTR,#DTAB ;查表,送字形
MOV A,@R0
MOVC A,@A+DPTR
MOV DPTR,#0101H
MOVX @DPTR,A
LCALL DELAY
INC R0
MOV A,R3
JNB ACC.7,LD1
RL A
MOV R3,A
LJMP LD0
LD1:RET
;***********************************************
;字形表
DTAB:
DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH ;数字0-9
DB 40H,00H ;40H为“" 00H为不亮
;**********************************************
;延时1ms
DELAY:
MOV R7,#02H
DEL1:MOV R6,#0FFH
DEL2:DJNZ R6,DEL2
DJNZ R7,DEL1
RET
;**********************************************。