51单片机中PCF8591如何实现采集电压的功能?进一步转换到1602中显示出来呢?希望有程序教程 200

 我来答
zhxiufan
2017-12-21 · 知道合伙人软件行家
zhxiufan
知道合伙人软件行家
采纳数:14923 获赞数:38386
国家科技进步奖

向TA提问 私信TA
展开全部
#include<reg51.h>
#include <intrins.h>
#include <absacc.h>
#include<stddef.h>
#define uchar unsigned char
#define uint unsigned int
#define LCD1602_PORT P0

uchar code ledtab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xff}; //显示段码共阳
uchar keyval=0,time=0,mode; 
uchar disdat[16],num=0;
uint adchg=0;
uchar adval[4];
uchar code alarml[4]={10,20,30,40};
uchar code alarmh[4]={200,200,200,200};

uchar code disp[]="Four channels DC";

sbit lcd1602_rs=P2^0;
sbit lcd1602_rw=P2^1;
sbit lcd1602_e=P2^2;
sbit lcd1602_busy=P0^7;
sbit SDA=P1^7;
sbit SCL=P1^6;
sbit sound=P1^5;
sbit led1=P1^0;
sbit led2=P1^1;
sbit led3=P1^2;
sbit led4=P1^3;
sbit key=P3^2;

//--------------------------------
void i2c_start( void );  
void i2c_stop( void );  
void i2c_ack( void );  
void master_notAck();  
void i2c_writeByte( unsigned char byte);  
unsigned char i2c_readByte( void );  
void PCF8591_wirteCommand( unsigned char addr, unsigned char command );  
unsigned char i2c_readADResult( void );  
void PCF8591_displayADResult( unsigned int ADResult);  
  
void i2c_delay( void );  
void delay_xms(unsigned int );  

/******************************************************** 
**  函数名: void i2c_start( void ),i2c起始信号 
**输入参数:无 
**返回参数:无 
********************************************************/  
void i2c_start( void )  
{  
    SCL = 1;  
    SDA = 1;  
    i2c_delay();  
    SDA = 0;  
    i2c_delay();  
    SCL = 0;  
    i2c_delay();      
}  
  
/******************************************************** 
**  函数名: void i2c_stop( void ),i2c停止信号 
**输入参数:无 
**返回参数:无 
********************************************************/  
void i2c_stop( void )  
{  
    SDA = 0;  
    i2c_delay();  
    SCL = 1;  
    i2c_delay();  
    SDA = 1;  
    i2c_delay();      
}  
  
/******************************************************** 
**  函数名: void i2c_ack( void ),i2c应答信号(从机) 
**输入参数:无 
**返回参数:无 
********************************************************/  
void i2c_ack( void )  
{  
    int i = 0;  
    SCL = 0;  
    i2c_delay();  
    SDA = 1;   
    i2c_delay();  
    SCL = 1;  
    i2c_delay();  
    while(SDA == 1);  
    /*while((SDA == 1) && ((i++) < 10)) 
    { 
        _nop_(); 
    }*/   
}   
  
/******************************************************** 
**  函数名: void master_notAck( void ),主机非应答信号,在读取数据时 
**输入参数:无 
**返回参数:无 
********************************************************/  
void master_notAck( void )  
{  
    SCL = 0;  
    i2c_delay();  
    SDA = 1;  
    i2c_delay();  
    SCL = 1;  
    i2c_delay();  // 没下面四句程序读取不正常  
    SCL = 0;      //  
    i2c_delay();  //  
    SDA = 0;      //      
}  
  
/******************************************************** 
**  函数名: void i2c_writeByte,i2c写一个字节 
**输入参数:unsigned char byte 
**返回参数:无 
********************************************************/  
void i2c_writeByte( unsigned char byte )  
{  
    char loop;  
    for(loop = 0; loop < 8; loop++)  
    {  
        SCL = 0;  
        i2c_delay();  
        if((byte<<loop)&0x80)  //数据是从高位到低位传输  
        {  
            SDA = 1;  
        }  
        else  
        {  
            SDA = 0;  
        }  
        i2c_delay();  
        SCL = 1;  
        i2c_delay();          
    }  
}  
  
unsigned char i2c_readByte( void )  
{  
    int loop = 0;  
    unsigned char temp = 0;  
    unsigned char tempData = 0;  
    //SDA = 0;  
    for(loop = 7; loop >= 0; loop--)  
    {     
        SCL = 0;  
        i2c_delay();      
        temp = SDA;  
        i2c_delay();  
        SCL = 1;  
        i2c_delay();  
        tempData += (temp<<loop);  
        temp = 0;     
    }  
    return tempData;              
}  
  
/******************************************************** 
**  函数名: void PCF8591_wirteCommand( unsigned char addr, unsigned char command ),PCF8591写控制指令 
**输入参数:unsigned char addr, unsigned char command 
**返回参数:无 
********************************************************/  
void PCF8591_wirteCommand( unsigned char addr, unsigned char command )  
{                                     
    i2c_start();  
    i2c_writeByte(addr);  
    i2c_ack();  
    i2c_writeByte(command);  
    i2c_ack();  
    i2c_delay();      
    i2c_stop();  
}  
  
/******************************************************** 
**  函数名: unsigned char i2c_readADResult( void ),i2c读出一个字节 
**输入参数:无 
**返回参数:unsigned char 
********************************************************/  
unsigned char i2c_readADResult( void )  
{     
    unsigned char temp = 0;  
    i2c_start();  
    i2c_writeByte(0x91);  
    i2c_ack();  
    temp = i2c_readByte();  
    master_notAck();  
    i2c_stop();  
    return temp;      
}  
  
/************************************************************************ 
**函数名:void i2c_delay( void ),i2c专用延时 
**  功能:无 
**  参数: 无 
*************************************************************************/  
void i2c_delay( void )  
{  
    char loop;  
    for(loop = 0; loop < 5; loop++)  
    {  
        _nop_();  
    }  
}  
  
/************************************************************************ 
**函数名:void delay_xms( unsigned int x ) 
**  功能:延时xms 
**  参数: 无 
*************************************************************************/  
void delay_xms( unsigned int x )  
{  
    unsigned char j = 0;  
    while( x-- )  
    {  
        while( (j++) < 100 );  
        j = 0;  
    }  
}  
  
/************************************
 * 函数名称:lcd1602_CheckBusy()
 * 函数功能:状态查询
************************************
*/

void lcd1602_CheckBusy()
{
    do
    {
    lcd1602_busy=1;
    lcd1602_rs=0;
    lcd1602_rw=1;
    lcd1602_e=0;
    lcd1602_e=1;
    }
while(lcd1602_busy);
}

/*
***************************************
 * 函数名称: lcd1602_WriteCmd()
 * 函数功能:写命令
 * 入口参数:命令字
 * 出口参数:无
***************************************
*/

void lcd1602_WriteCmd(uchar cmd)
{
    lcd1602_CheckBusy();
lcd1602_rs=0;
lcd1602_rw=0;
lcd1602_e=1;
LCD1602_PORT=cmd;
lcd1602_e=0;
}

/*
*******************************************
 * 函数名称:lcd1602_WriteData()
 * 函数功能:写数据
 * 入口参数:c--待写数据
 * 出口参数:无
*********************************************
*/

void lcd1602_WriteData(uchar c)
{
    lcd1602_CheckBusy();
lcd1602_rs=1;
lcd1602_rw=0;
lcd1602_e=1;
LCD1602_PORT=c;
lcd1602_e=0;
}

/*
***********************************************
 * 函数名称:lcd1602_Init()
 * 函数功能:初始化LCD
 * 入口参数:无
 * 出口参数:无
***********************************************
*/

void lcd1602_Init()
{
    lcd1602_WriteCmd(0x38); //显示模式为8位2行5*7点阵
    lcd1602_WriteCmd(0x0f); //display enable,flag enable,flash enable,
    lcd1602_WriteCmd(0x06); //flag move to right,screen don't move
    lcd1602_WriteCmd(0x01); //clear screen
}

/*
************************************************
 * 函数名称:lcd1602_Display()
 * 函数功能: 字符显示
 * 入口参数:ptr--字符或字符串指针
 * 出口参数:无
 * 说    明:用户可通过以下方式来调用:
 *           1)lcd1602_Display("Hello,world!");
 *           2) INT8U 存储类型 txt[]="要显示的字符串";
 *              或者 INT8U 存储类型 txt[]={'t','x','t',..,'\0'};
 *              INT8U *ptr;
 *              ptr=&txt;
 *              lcd1602_Display(ptr);
 *              或 lcd1602_Display(txt);
 *              或 lcd1602_Display(&txt);
************************************************
*/

void lcd1602_Display(uchar *ptr,uchar ln)
{
    uchar data i=0;
uchar *data q;

q=ptr;
switch(ln)
{
case 0:
lcd1602_WriteCmd(0x80);
while(q!=NULL && (*q!='\0'))
    {
lcd1602_WriteData(*q);
q++;
i++;
    }
break;
case 1:
lcd1602_WriteCmd(0xc0);
while(q!=NULL && (*q!='\0'))
    {
lcd1602_WriteData(*q);
q++;
i++;
}
}
}

//--------------------------------
void dischg(uchar a)
{
uint x;
disdat[0]='H';
disdat[1]=2*a+0x30;
disdat[2]=' ';
x=(int)(100.0*(float)adval[2*a]/51.0);
disdat[3]=(x/100)%10+0x30;
disdat[4]='.';
disdat[5]=(x/10)%10+0x30;
disdat[6]=x%10+0x30;
disdat[7]=' ';
disdat[8]=' ';
disdat[9]='H';
disdat[10]=2*a+0x31;
disdat[11]=' ';
x=(int)(100.0*(float)adval[2*a+1]/51.0);
disdat[12]=(x/100)%10+0x30;
disdat[13]='.';
disdat[14]=(x/10)%10+0x30;
disdat[15]=x%10+0x30;
}
void ext0() interrupt 0
{
while(key==0);
if(mode==0 && keyval==0)mode=1;
else keyval++;
keyval%=5;
if(keyval<4)mode=1;
else mode=0;
}
void t0isr() interrupt 1
{
TH0=0x3c;
TL0=0xb0;
time++;
if(time>=10)
{
time=0;
if(adval[0]<alarml[0] || adval[0]>alarmh[0])led1=~led1;
else led1=1;
if(adval[1]<alarml[1] || adval[1]>alarmh[1])led2=~led2;
else led2=1;
if(adval[2]<alarml[2] || adval[2]>alarmh[2])led3=~led3;
else led3=1;
if(adval[3]<alarml[3] || adval[3]>alarmh[3])led4=~led4;
else led4=1;
}

}
main()
{
uchar i=0;
uint tmp;
TMOD=0x01;
TH0=0x3c;
TL0=0xb0;
TR0=1;
ET0=1;
EX0=1;
IT0=1;
EA=1;
sound=1;
    lcd1602_Init();
mode=0;
while(1)
{
    PCF8591_wirteCommand(0x90, i);  
    i2c_readADResult();      
    i2c_readADResult();      
    i2c_readADResult();      
    adval[i]=i2c_readADResult(); 
i++;
i%=4;
switch(mode)
{
case 0:
dischg(0);
lcd1602_Display(disdat,0);
dischg(1);
lcd1602_Display(disdat,1);
break;
case 1:
lcd1602_Display(disp,0);
disdat[0]='C';
disdat[1]='H';
disdat[2]=keyval+0x30;
disdat[3]=' ';
tmp=(int)(100.0*(float)adval[keyval]/51.0);
disdat[4]=(tmp/100)%10+0x30;
disdat[5]='.';
disdat[6]=(tmp/10)%10+0x30;
disdat[7]=tmp%10+0x30;
disdat[8]=' ';
if(adval[keyval]<alarml[keyval])
{
disdat[9]='L';
disdat[10]='O';
disdat[11]='W';
disdat[12]='E';
disdat[13]='R';
disdat[14]=' ';
}
else if(adval[keyval]>alarmh[keyval])
{
disdat[9]='O';
disdat[10]='V';
disdat[11]='E';
disdat[12]='R';
disdat[13]=' ';
disdat[14]=' ';
}
else {
disdat[9]='N';
disdat[10]='O';
disdat[11]='R';
disdat[12]='M';
disdat[13]='A';
disdat[14]='L';
}
disdat[15]=' ';
lcd1602_Display(disdat,1);
default:break;
}
delay_xms(100);
}
}
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式