这是一个用89S52单片机或 89C52、89C51来读取AD值和控制数码管显示的电压表程序;AD转换单片机内部没有,用的是外部的ADC芯片ADC0809或ADC0808,芯片的具体介绍你可以百度一下;程序中定义了单片机和ADC0809芯片的接口:sbit ST=P3^0;
sbit OE=P3^1;
sbit EOC=P3^2;
sbit CLK=P3^3;ST:START: A/D转换启动脉冲输入端,输入一个正脉冲(至少100ns宽)使其启动(脉冲上升沿使0809复位,下降沿启动A/D转换)。 EOC: A/D转换结束信号,输出,当A/D转换结束时,此端输出一个高电平(转换期间一直为低电平)。 OE:数据输出允许信号,输入,高电平有效。当A/D转换结束时,此端输入一个高电平,才能打开输出三态门,输出数字量。 CLK:时钟脉冲输入端。要求时钟频率不高于640KHZ,单片要送出的CLK时序是用 TO定时中断完成的:void t0(void) interrupt 1 using 0
{
CLK=~CLK;//定时取反一次,制造脉冲
}
当EOC是高电平时,就是一次AD转换完成,单片机此时读ADC0809的值:if(EOC==1)
OE=1;
getdata=P0;
OE=0;
就是从P0口与ADC0809数据相连读出,读出8位的转换值 后存在getdata中,getdata再送入temp,temp再把采得的AD值转换为实际的电压值:temp=getdata235;//这是要根据实际电路的电阻而定
temp=temp/128;
后把实际电压值送入数码管扫描的缓冲数组,在T1中断中进行扫描显示:dispbuf[0]=10;
dispbuf[1]=10;
dispbuf[2]=10;
dispbuf[3]=10;
dispbuf[4]=10;
dispbuf[5]=0;
dispbuf[6]=0;
dispbuf[7]=0;
P1=dispcode[dispbuf[dispcount]]; //数码管的字段码
P2=dispbitcode[dispcount //扫描数码管的每一位 说得差不多了,估计没人会一句句程序的给你分析,何况只有10分。
说好200分的……
#include "reg52h"
const unsigned char LED7Code[]={ //共阴极7段显示
0x3F, // 0
0x06, // 1
0x5B, // 2
0x4F, // 3
0x66, // 4
0x6D, // 5
0x7D, // 6
0x07, // 7
0x7F, // 8
0x6F // 9
};
void delay(unsigned int i) /延时1014i+13 机器周期/
{ int j;
for(;i>0;i--)
for(j=0;j<125;j++);
}
void delayus(unsigned char i) /延时8i+10 机器周期/
{while(i>0)
i--;
}
sbit start=P3^0;
sbit clk=P3^3;
sbit eoc=P3^2;
sbit oe=P3^1;
sbit add1=P3^4;
sbit add2=P3^5;
sbit add3=P3^6;
sbit key1=P2^5;
sbit key2=P2^6;
main()
{
unsigned char i,j=0;
long U=0;
unsigned char flag=0; //循环与否标志
unsigned char key1_tmp=1,key2_tmp=1; //两个按键状态暂存
while(1)
{
add1=j%2;add2=0;add3=0; //通道地址
clk=1;
start=0;
start=1;
start=0; //启动转换
eoc=1;
clk=0; delayus(5); //clk信号下降沿对eoc信号线进行检测
while(!eoc)
{
clk=1; delayus(5);
clk=0; delayus(5);
eoc=1;
}
oe=1; //0808输出允许
P0=0xff; //单片机从P0口读取数据
U=P05L100/256;
for(i=0;i<100;i++)
{
P1=LED7Code[j%2]; P2=0xfe; delay(1); P1=0;
P1=LED7Code[U/100]|0x80; P2=0xfd; delay(1); P1=0; //|0x80目的是加小数点
P1=LED7Code[U%100/10]; P2=0xfb; delay(1); P1=0;
P1=LED7Code[U%10]; P2=0xf7; delay(1); P1=0;
key1=1; //按键1
if(!key1&&key1_tmp)
{flag=!flag;key1_tmp=key1;break;} //当按键1检测到下降沿时,循环标志置取反
key2=1; //按键2
if(!key2&&key2_tmp)
{j++;key2_tmp=key2;break;} //当按键2检测到下降沿时,通道地址加一
key1_tmp=key1;
key2_tmp=key2;
}
if(flag)
j++; //通道地址加一
}
}
行注释用 //
段注释用 /内容/
回答不对?
你看看adc0808,0809的使用笔记手册之类的吧,相对来说这个很简单的,就是时序 *** 作,给一个时钟给adc,选择通道,等待转换完成,读取数据,转换数据
我这里有protues+代码:(内容是串口通信,A机测量,B机数码管显示)
代码给你吧,protues 需要再说
#include <reg51h>
#define uint unsigned int
#define uchar unsigned char
#define PinData P0
sbit LED0 = P1^0;
sbit LED1 = P1^1;
sbit PinSTART = P1^5;
sbit PinOE = P1^6;
sbit PinEOC = P1^7;
sbit CLK = P3^4;
//短延时函数:ShortDelay()
void nNop(uchar i)
{
for(;i>0;i--) ;
}
//长延时函数:LongDelay()
void LongDelay(uint i)
{
uint j;
for(;i>0;i--)
{ for(j=1000;j>0;j--);}
}
//引脚初始化
void InitIO()
{
PinData = 0xff;
PinSTART = 1;
PinEOC = 1;
PinOE = 1;
CLK = 1;
}
//UART的初始化:模式1,8位,9600Bds
void InitSerial()
{
TMOD = 0x20 ; // Timer 1 in mode 2
TH1 = 0xF4; // 9600 Bds at 11059MHz
TL1 = 0xF4; // 9600 Bds at 11059MHz
TR1 = 1; // Timer 1 run
PCON = 0x00; // Timer 1 run
SCON = 0x50; // uart in mode 1 (8 bit), REN=1
}
//T0定时脉冲中断初始化
void init_uart()
{
TMOD=0x01;
TH0= (65536-4000)/256;
TL0= (65536-4000)%256;
TR0=1;
// ET0=1;
EA=1;
}
//等待A/D转换结束函数:WaitADCEnd()
void WaitADCEnd(void)
{
while(!PinEOC) ;
}
//读取A/D转换后的数据函数:ReadData()
uchar ReadData()
{
uchar tempt;
ET0=1;
PinSTART = 0;
//nNop(1);
PinSTART = 1;
PinSTART = 0;
WaitADCEnd();
PinOE =1;
nNop(2);
tempt = PinData & 0xff;
ET0=0;
return(tempt);
//PinOE =0;
}
//子机送数据给主机
void sendtomain(uchar temp)
{
SBUF = temp;
while(!TI);
TI=0;
}
void main()
{
uchar temp, tab;
InitIO();
init_uart();
InitSerial();
while(1)
{
temp = ReadData();
sendtomain(temp);
while(!RI);
tab = SBUF;
RI = 0;
if(tab == 0)
{
LED0 = 1;
LED1 = 0;
}
else if(tab == 1)
{
LED0 = 1;
LED1 = 1;
}
else
{
LED0 = 0;
LED1 = 1;
}
}
}
void clk(void) interrupt 1 using 0
{
TH0= (65536-4000)/256;
TL0= (65536-4000)%256;
CLK= ~CLK;
}
#include<reg51h>
#define PDATA P2
#define aver 2
#define uint unsigned int
#define uchar unsigned char
sbit Ledlow = P1^3;
sbit Ledhig = P1^4;
uchar table2 []={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
uchar table1 []={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};
//短延时函数:ShortDelay()
void nNop(uchar temp)
{
uint i;
for(i=0 ;i<temp; i++) ;
}
//UART初始化:模式1,8位,9600Bds at 11059MHz
void InitSerial()
{ // uart in mode 1 (8 bit), REN=1
TMOD = 0x20 ; // Timer 1 in mode 2
TH1 = 0xF4; // 9600 Bds at 11059MHz
TL1 = 0xF4; // 9600 Bds at 11059MHz
TR1 = 1;
PCON = 0x00; // Timer 1 run
SCON = 0x50;
}
//主机接受信息给从机
uchar recivefromslave()
{
uchar temp;
while(!RI);
temp=SBUF;
RI=0;
return(temp);
}
// 显示
void leddisp(uint temp )
{
uint i;
uint getdata1 = 0;
uint getdata2 = 0;
temp=tempaver;
getdata1=temp/100;
getdata2=temp/10;
getdata2=getdata2%10;
for(i=0;i<30;i++)
{
PDATA=table1[getdata1];
Ledlow =0;
Ledhig = 1;
nNop(1000);
Ledlow =0;
Ledhig = 0;
PDATA=table2[getdata2];
Ledlow =1;
Ledhig = 0;
nNop(1000);
Ledlow =0;
Ledhig = 0;
}
}
void main()
{
uint tab;
uint tempt;
Ledlow = 0;
Ledhig = 0;
PDATA = 0x00;
InitSerial();
while(1)
{
tempt = (uint) recivefromslave(); //接收从机采集的信息
leddisp(tempt); //显示信息
if(tempt<0x60) //判断信息
{
tab = 0;
}
else if(tempt>0xc0)
{
tab = 2;
}
else
{
tab = 1;
}
SBUF = (uchar)tab; //对采集信息进行控制
while(!TI);
TI = 0;
}
}
用几个电阻分压就可以了,把50v分成5v,1024等分,计算公式为x15k/150k50v/1024;x为单片机测量值,比如测得的数据位1024,那么他就是50v了测得的数据位256,那他就是25v了
//实验用程序 测试通过 STC15F2K60S2 @110592MHZ
#include "reg51h"
#include "intrinsh"
typedef unsigned char BYTE;
typedef unsigned int WORD;
sfr ADC_CONTR = 0xBC;
sfr ADC_RES = 0xBD;
sfr ADC_LOW2 = 0xBE;
sfr P1ASF = 0x9D;
BYTE ch = 0; //ADC回路数
/----------------------------
延时
----------------------------/
void Delay(WORD n){
WORD x;
while (n--){
x = 5000;
while (x--);
}
}
/----------------------------
ADC中断
----------------------------/
void adc_isr() interrupt 5 using 1{
ADC_CONTR &= !0x10;
P2=ADC_RES;
ADC_CONTR = 0x80 | 0x00 | 0x08 | ch;
}
/----------------------------
初始化ADC
----------------------------/
void InitADC(){
P1ASF = 0xff;
ADC_RES = 0;
ADC_CONTR = 0x80 | 0x00 | 0x08 | ch;;
Delay(2);
}
void main(){
InitADC(); //初始化ADC
IE = 0xa0;
while (1);
}
以上就是关于51单片机数字电压表P0口改到P1口程序怎么改全部的内容,包括:51单片机数字电压表P0口改到P1口程序怎么改、单片机双路数字电压表,之前一哥们给的程序如下可以实现循环测量显示IN0,IN1电压,现要求如下、51单片机数字电压表的C语言程序,求大神在每句话后面注释,让我能知道这句话什么意思,有什么用等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)