51单片机数字电压表P0口改到P1口程序怎么改

51单片机数字电压表P0口改到P1口程序怎么改,第1张

这是一个用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语言程序,求大神在每句话后面注释,让我能知道这句话什么意思,有什么用等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

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

原文地址: http://outofmemory.cn/zz/9460865.html

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

发表评论

登录后才能评论

评论列表(0条)

保存