OpenVINOTM,给你看得见的未来!>>
电子产品世界 » 论坛首页 » DIY与开源设计 » 电子DIY » wdy3585MCU DIY进程帖--PCF8591(含照片)

共2条 1/1 1 跳转至

wdy3585MCU DIY进程帖--PCF8591(含照片)

助工
2011-12-22 15:20:35    评分

资料:
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;
}

-------------------------PCF8591.c------------------------------------------------------------------------------
#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();



关键词: wdy3585MCU     进程     --PCF8591         

专家
2011-12-22 19:44:43    评分
2楼
Good!代码还挺全的

共2条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]