51单片机中PCF8591如何实现采集电压的功能?进一步转换到1602中显示出来呢?希望有程序教程 200
1个回答
展开全部
#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);
}
}
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询
广告 您可能关注的内容 |