单片机直流数字电压表,下面是0-5V的,请帮忙改下源程序,让电压表测到0-20v电压,用的是at89c51和adc0808

单片机直流数字电压表,下面是0-5V的,请帮忙改下源程序,让电压表测到0-20v电压,用的是at89c51和adc0808,第1张

假设,原程序是正确的。

那么,原来显示的数据范围是多少?

现在,要求显示的范围是多少?

假设,原程序是正确的。

那么,需要改动的,就是下面标注的几行:

……

WAIT:

CLR ST

SETB ST

CLR ST启动AD转换.

JNB EOC, $等待转换结束.

SETB OE

MOV ADC, P1 读取AD转换结果.

CLR OE

MOV A, ADC

---------------------------下面需要改动------------------------

MOV B, #100 AD转换结果转换成BCD码.

DIV AB

MOV LED_2, A

MOV A, B

MOV B, #10

DIV AB

MOV LED_1, A

MOV LED_0, B

---------------------------上面需要改动------------------------

CALL DISP

SJMP WAIT

……

不过,看来,原来的程序,好像不对。

不像是显示0~5V,好像是显示:0.00~2.55。

#include "reg51.h"

#define data_point P0

sbit EOC=P2^0

sbit ADDA=P2^1

sbit ADDB=P2^2

sbit ADDC=P2^3

sbit OE=P2^5

sbit START=P2^6

sbit CLK=P2^7

sbit ALE=P2^6

unsigned char disp[3]={0,0,0}

char code dispcode[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}

unsigned char t0count=0

unsigned int temp

double sum

unsigned char val_Integer //整数

unsigned int val_Decimal //小数

sbit k1 = P1^0

sbit k2 = P1^1

sbit k3 = P1^2

sbit k4 = P1^3

void delay(unsigned char ms)

{

unsigned char i

while(ms--)

for(i=0i<125i++)

}

void display()

{

disp[0]=disp[0]&0x7f

P3= disp[0]

k1 = 1

delay(2)

k1 = 0

P3= disp[1]

k2 = 1

delay(2)

k2 = 0

P3= disp[2]

k3 = 1

delay(2)

k3 = 0

P3= disp[3]

k4 = 1

delay(2)

k4 = 0

}

unsigned char ADC0808()

{

unsigned char d

ADDC=0

ADDB=0

ADDA=0

TR1=1

ALE=1ALE=0

START=1START=0

while(EOC==0)

OE=1

d=data_point

OE=0

TR1=1

return d

}

void covert(unsigned char x)

{

sum=x*0.0201378

val_Integer=(unsigned char)sum

val_Decimal=(unsigned int)((sum-val_Integer)*1000)

disp[3]=dispcode[val_Decimal%10]

disp[2]=dispcode[val_Decimal/10%10]

disp[1]=dispcode[val_Decimal/100]

disp[0]=dispcode[val_Integer]

}

void main()

{

TMOD=0x21

TH0=(65536-10000)/256

TL0=(65536-10000)%256

TH1=256-2

ET0=1

ET1=1

EA=1

TR0=1

OE=0

START=0

EOC=1

while(1)

{

display()

}

}

void time0() interrupt 1

{

TH0=(65536-10000)/256

TL0=(65536-10000)%256

t0count++

if(t0count==100)

{

t0count=0

covert(ADC0808())

}

}

void time1() interrupt 3

{

CLK=~CLK

}

/*************************************************/

#include <reg52.h>

#include <intrins.h>

#define uchar unsigned char

sbit CS=P3^5

sbit Clk=P1^6 //时钟

sbit DO=P3^7 //ADC0832输出引脚

sbit DI=P3^6 //ADC0832输入引脚

sbit key=P3^3 //按键

bit keydownflg// *** 作位的定义

bit adc_flg

uchar dat,channel

uchar key_buffer

uchar P2_buffer

uchar Beep_cnt

uchar disp_cnt

uchar count4ms

uchar disp_buff[5] //数码管显示缓存

uchar codeTab1[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xA7,0xA1,0x86,0x8E}//共阳数码表

uchar code Tab[5]={0x7f,0xbf,0xdf,0xef,0xf7} //数码管位选表

uchar A_D(uchar CH) //AD函数

{

uchar i,adval,test //定义局部变量并初始化

adval=0x00

test=0x00

Clk=0//clk低电平

DI=1 //DI初始高电平在第一个时钟脉冲的下降沿前保持高电平,表示启动信号

_nop_()

CS=0 //片选

_nop_()

Clk=1//clk上升沿,起始位写入

_nop_()

if(CH==0x00) //选择通道0

{

Clk=0 //clk低电平

DI=1

_nop_()

Clk=1 //clk上升沿,通道0的第一位写入

_nop_()

Clk=0

DI=1

_nop_()

Clk=1 //clk上升沿,通道0的第二位写入

_nop_()

}

else

{

Clk=0

DI=1

_nop_()

Clk=1 //clk上升沿,通道1的第一位写入

_nop_()

Clk=0

DI=1

_nop_() //clk上升沿,通道1的第二位写入

Clk=1

_nop_()

}

Clk=0

DI=1

for(i=0i<8i++)//从高位向低位读取八位AD值

{

_nop_()

adval<<=1

Clk=1

_nop_()

Clk=0

if(DO)

adval|=0x01

else

adval|=0x00

}

for(i=0i<8i++)

{

test>>=1//从低位向高位读取八位AD值

if(DO)

test|=0x80

else

test|=0x00

_nop_()

Clk=1

_nop_()

Clk=0

}

if(adval==test)dat=test//判断两个读取值是否相等相等就把读取的数赋值给DAT

_nop_()

CS=1

DO=1

Clk=1

return dat

}

void FillDispBuffer(void) //数码管显示缓存函数

{

disp_buff[0]=channel //显示通道

disp_buff[1]=12//显示"C"

disp_buff[2]=dat/51 //显示个位

disp_buff[3]=dat%51*10/51 //显示十分位

disp_buff[4]=((dat%51)*10%51)*10/51 //显示百分位

}

void dealkey(void) //按键处理

{

if(keydownflg) return //keydownflg控制位为1,不对按键进行处理

key_buffer=P2

if((key_buffer&0x80)!=0x80) channel=0//选择通道0

if((key_buffer&0x40)!=0x40) channel=1//选择通道1

FillDispBuffer()//数码管显示缓存

Beep_cnt=0

keydownflg=1 //keydownflg控制位置1

}

void main(void) //主函数

{

P0=0xff //初始化

P2=0xff

dat=0x00

disp_cnt=0

count4ms=0

channel=0

TMOD=0x10

TH0=(65535-4000)/256

TL0=(65535-4000)%256

EA=1

TR0=1

ET0=1

while(1)

{

if(adc_flg) //ADC转换控制位,防止输入与输出产生冲突

{

adc_flg=0

A_D(channel) //ADC函数

FillDispBuffer() //数码管显示缓存

}

if(!key) //按键

dealkey()

}

}

void T0_service(void)interrupt 1 //定时器0中断子函数

{

TH0=(65535-4000)/256

TL0=(65535-4000)%256

P2_buffer=Tab[disp_cnt] //查表,数码管的位选择

if(keydownflg) //蜂鸣器0.4s的短时间鸣叫

{

P2_buffer=P2_buffer&0xfe

Beep_cnt++

if(Beep_cnt==100)keydownflg=0

}

P2=P2_buffer //数码管显示数字符号

if(disp_cnt==2) //第三位数码管显示小数点

P0=Tab1[disp_buff[disp_cnt]]&0x7f

else

P0=Tab1[disp_buff[disp_cnt]]

disp_cnt++ //

if(disp_cnt==5) disp_cnt=0

count4ms++

if(count4ms==50) //0.2s ADC转换一次

{

adc_flg=1

count4ms=0

}

}


欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/yw/12167378.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-21
下一篇2023-05-21

发表评论

登录后才能评论

评论列表(0条)

    保存