资料:
pcf8591_jj[1].pdf  
仿真:

照片:(相机像素问题,看不太清)
公开代码:

***********************LCD.h*******************************
#ifndef LCD_CHAR_1602_
#define LCD_CHAR_1602_
#include <intrins.h>
//Port Definitions**********************************************************
sbit LcdRs  = P2^4;
sbit LcdRw  = P2^5;
sbit LcdEn   = P2^6;
sfr  DBPort  = 0x80;  //P0=0x80,P1=0x90,P2=0xA0,P3=0xB0.数据端口
//内部等待函数**************************************************************************
unsigned char LCD_Wait(void)
{
 LcdRs=0;
 LcdRw=1; _nop_();
 LcdEn=1; _nop_();
 //while(DBPort&0x80);//在用Proteus仿真时,注意用屏蔽此语句,在调用GotoXY()时,会进入死循环,
       //可能在写该控制字时,该模块没有返回写入完备命令,即DBPort&0x80==0x80
       //实际硬件时打开此语句
 LcdEn=0;
 return DBPort;  
}
//向LCD写入命令或数据************************************************************
#define LCD_COMMAND   0      // Command
#define LCD_DATA   1      // Data
#define LCD_CLEAR_SCREEN 0x01      // 清屏
#define LCD_HOMING    0x02      // 光标返回原点
void LCD_Write(bit style, unsigned char input)
{
 LcdEn=0;
 LcdRs=style;
 LcdRw=0;  _nop_();
 DBPort=input; _nop_();//注意顺序
 LcdEn=1;  _nop_();//注意顺序
 LcdEn=0;  _nop_();
 LCD_Wait(); 
}
//设置显示模式************************************************************
#define LCD_SHOW   0x04    //显示开
#define LCD_HIDE   0x00    //显示关   
#define LCD_CURSOR   0x02  //显示光标
#define LCD_NO_CURSOR  0x00    //无光标       
#define LCD_FLASH   0x01    //光标闪动
#define LCD_NO_FLASH  0x00    //光标不闪动
void LCD_SetDisplay(unsigned char DisplayMode)
{
 LCD_Write(LCD_COMMAND, 0x08|DisplayMode); 
}
//设置输入模式************************************************************
#define LCD_AC_UP   0x02
#define LCD_AC_DOWN   0x00      // default
#define LCD_MOVE   0x01      // 画面可平移
#define LCD_NO_MOVE   0x00      //default
void LCD_SetInput(unsigned char InputMode)
{
 LCD_Write(LCD_COMMAND, 0x04|InputMode);
}
//移动光标或屏幕************************************************************
/*
#define LCD_CURSOR  0x02      
#define LCD_SCREEN  0x08
#define LCD_LEFT  0x00
#define LCD_RIGHT  0x04
void LCD_Move(unsigned char object, unsigned char direction)
{
 if(object==LCD_CURSOR)
  LCD_Write(LCD_COMMAND,0x10|direction);
 if(object==LCD_SCREEN)
  LCD_Write(LCD_COMMAND,0x18|direction);
}
*/
//初始化LCD************************************************************
void LCD_Initial()
{
 LcdEn=0;
 LCD_Write(LCD_COMMAND,0x38);           //8位数据端口,2行显示,5*7点阵
 LCD_Write(LCD_COMMAND,0x38);
 LCD_SetDisplay(LCD_SHOW|LCD_NO_CURSOR);    //开启显示, 无光标
 LCD_Write(LCD_COMMAND,LCD_CLEAR_SCREEN);   //清屏
 LCD_SetInput(LCD_AC_UP|LCD_NO_MOVE);       //AC递增, 画面不动
}
//************************************************************************
void GotoXY(unsigned char x, unsigned char y)
{
 if(y==0)
  LCD_Write(LCD_COMMAND,0x80|x);
 if(y==1)
  LCD_Write(LCD_COMMAND,0x80|(x-0x40));
}
void Print(unsigned char x, unsigned char y,unsigned char *str)
{
    GotoXY(x,y);
 while(*str!='\0')
 {
  LCD_Write(LCD_DATA,*str);
  str++;
 }
}
/*
void LCD_LoadChar(unsigned char user[8], unsigned char place)
{
 unsigned char i;
 LCD_Write(LCD_COMMAND,0x40|(place*8));
 for(i=0; i<8; i++)
  LCD_Write(LCD_DATA,user[i]);
}
*/
//************************************************************************
#endif
--------------------------------------PCF8591.h----------------------------------------
#ifndef _PCF8591_h_
#define _PCF8591_h_
#include<reg52.h>
#include<intrins.h>
#define channal0  0x00
#define channal1  0x01
#define channal2  0x02
#define channal3  0x03
sbit SCL=P1^1;
sbit SDA=P1^2;
 
#define SCL_0 SCL=0
#define SCL_1 SCL=1
#define SDA_0 SDA=0
#define SDA_1 SDA=1
 
void delay(void);  //大约4.7us的延时
void i_start(void);//iic起始信号
void i_stop(void); //iic终止信号
bit i_clock(void);//主器件没写完一个字节8位以后,在第九个时钟周期,读取SDA数据线的信息,看是否被从器件拉低,来判断数据总线的状态
void ack(); //主器件发给从器件的应答信号,表明仍然需要从器件发送数据
void nack();//主器件发送的非应答信号,表明接收完了,不需要从器件再发了
bit i_send(unsigned char i_data);//写一个字节
unsigned char i_receive(void);//读一个字节
void PCF8591write(unsigned char dat); //PCF8591写函数,参数为需要D/A转换的数据
unsigned char PCF8591read(unsigned char channal);//PCF8591读函数 无参数
#endif
 while(1)
 {  
    vol=(float)PCF8591read(channal0)/255*5*10;
    voltage[0]=(unsigned char)vol/10+0x30;
    voltage[1]='.';
    voltage[2]=(unsigned char)vol%10+0x30;
    Print(0,0,"RG1:");
    Print(4,0,voltage);
    vol=(float)PCF8591read(channal1)/255*5*10;
    voltage[0]=(unsigned char)vol/10+0x30;
    voltage[1]='.';
    voltage[2]=(unsigned char)vol%10+0x30;
    Print(8,0,"NTC:");
    Print(12,0,voltage);
    vol=(float)PCF8591read(channal2)/255*5*10;
    voltage[0]=(unsigned char)vol/10+0x30;
    voltage[1]='.';
    voltage[2]=(unsigned char)vol%10+0x30;
    Print(0,1,"CH2:");
    Print(4,1,voltage);
    vol=(float)PCF8591read(channal3)/255*5*10;
    voltage[0]=(unsigned char)vol/10+0x30;
    voltage[1]='.';
    voltage[2]=(unsigned char)vol%10+0x30;
    Print(8,1,"CH3:");
    Print(12,1,voltage);
    //delay1(10000);
    //PCF8591write(255);
 }
 return 0;
}
#include<PCF8591.h>
void delay(void)
{ //延时5个时钟周期
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
}
void i_start(void)
{ //iic起始信号
SDA_1;
delay();
SCL_1; //iic时钟线置高电平
delay(); //需要这么长时间吗
SDA_0; //iic数据线置低电平
delay();
SCL_0; //iic数据线置低电平
delay();
}
void i_stop(void) //iic终止信号
{
SDA_0; //iic数据线置低电平
delay();
SCL_1; //iic时钟线置高电平
delay();
SDA_1; //iic数据线置高电平
delay();
SCL_0; //iic时钟线置低电平
delay();
}
bit i_clock(void)
{ //保持一个时钟周期,保证一位数据的有效传输,并且从数据线获取1bit信息并返回该bit信息
bit sample;
SCL_1; //iic时钟线置高电平,不允许数据线状态变化
delay();
sample=SDA;
_nop_(); //延时一个周期
_nop_(); //延时一个周期
SCL_0; //iic时钟线置低电平
delay();
return(sample); //返回从数据线读到的一bit信息
}
void ack()
{ //发送应答位
SCL_0; //iic时钟线置低电平
SDA_0; //iic数据线置低电平
delay(); //延时
SCL_1; //iic时钟线置高电平
delay();
SCL_0; //iic时钟线置低电平
delay();
SDA_1; //iic时数据置高电平
}
void nack()
{ //发送非应答位
SCL_0; //iic时钟线置低电平
SDA_1; //iic数据线置高电平
delay();
SCL_1; //iic时钟线置高电平
delay();
SCL_0; //iic时钟线置低电平
delay();
SDA_1; //iic数据线置高电平
}
bit i_send(unsigned char i_data)
{ //发送一byte数据,返回bit信息
unsigned char i;
for(i=8;i>0;i--)
{
SDA=(bit)(i_data & 0x80); //获取最高位
i_data=i_data<<1; //左移一位,用于依次获取下一位
i_clock(); //提供一个时钟脉冲
}
SDA_1; //iic数据线置高电平,用于接收应答位
return(~i_clock()); //返回接收的应答位
}
unsigned char i_receive(void)
{ //从iic接收一个字节数据,并返回该字节
unsigned char i_data=0; //i_data保存接收到的数据
unsigned char i;
for(i=8;i>0;i--)
{
i_data*=2; //每次将i_data右移1位,用来保存接收的1位信息
if(i_clock()) i_data++;
}
return(i_data); //返回接收的字节
}
void PCF8591write(unsigned char dat) //PCF8591写函数,参数为需要D/A转换的数据
{
i_start(); //发送开始
if(i_send(0x90)) //发送地址信息,然后判断接收的是应答位,还是非应答位
{
if(i_send(0x40)) //发送控制字
{
i_send(dat); //发送要转换的数据
i_stop(); //发送停止信号
delay();
}
}
}
unsigned char PCF8591read(unsigned char channal) //PCF8591读函数 无参数
{
unsigned char dat; //存放读取的数据
i_start(); //开始信号
if(i_send(0x90)) //发送地址信息,然后判断接收的是应答位,还是非应答位
{
if(i_send(channal)) //发送控制字。
{
i_start(); //从新发送开始信号
if(i_send(0x91)) //发送地址信息,然后判断接收的是应答位,还是非应答位
{
dat=i_receive(); //读取A/D转换后的结果,第一次读取的是寄存器中的初始值,所以还要再读一次
ack(); //发送应答信号
delay();
dat=i_receive(); //再次读取数据,读出的数据为上次转换的结果
nack(); //发送非应答位
i_stop(); //发送停止信号
return dat; //返回读出的数据
}
}
}
}
---------------------------main.c------------------------------------------------------------------
#include "reg52.h"
#include "lcd.h"
#include "pcf8591.h"
unsigned char voltage[5]={1,2,3};
void delay1(unsigned int tim)
{
while(tim--);
}
int main(void)
{ float vol;
LCD_Initial();

 
					
				
 
			
			
			
						
			 
					
				 我要赚赏金
 我要赚赏金 STM32
STM32 MCU
MCU 通讯及无线技术
通讯及无线技术 物联网技术
物联网技术 电子DIY
电子DIY 板卡试用
板卡试用 基础知识
基础知识 软件与操作系统
软件与操作系统 我爱生活
我爱生活 小e食堂
小e食堂

