单片机实验——利用AD完成电压测量及显示
- 格式:doc
- 大小:27.50 KB
- 文档页数:6
·数字电压表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转换程序,数码管显示#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--);。
//内部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采集电压用数码管显示////////////////////////////////////////////////////////////////////////////////////////////////////// ///特点:/// ///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电压测试实验报告一、实验目的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)。
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++); }。
程序/*---------------------------------------------------------------------------------名称: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仿真)。
单片机实验——利用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
;**********************************************。