找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1714|回复: 3
打印 上一主题 下一主题
收起左侧

有没大神看看这个基于pcf8591控制程序有问题没,小弟万分感谢

[复制链接]
跳转到指定楼层
楼主
#include <reg51.h>         //输入0-5V电压,根据ad值大小决定三个数码管显示,p1.0是控制电动机的。
#define uchar unsigned char
#define uint unsigned int
#define  PCF8591 0x90    //PCF8591 地址


sbit SCL=P2^1;         //串行时钟输入端
sbit SDA=P2^0;   //串行数据输入端
sbit LSA=P2^2;//138译码器的3位 控制动态数码管的  
sbit LSB=P2^3;
sbit LSC=P2^4;
sbit led=P1^0;

char disp[3];
uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};      //数显管字模


void delay()   //延时4-5个微秒
{;;}



void start()//开始信号
{
SDA=1;
    delay();
  SCL=1;
    delay();
  SDA=0;
    delay();
}

void stop()      //停止信号
{
SDA=0;
    delay();
  SCL=1;
    delay();
  SDA=1;
    delay();
}


void respons()//应答   相当于一个智能的延时函数
{
        uchar i;
  SCL=1;
    delay();
  while((SDA==1)&&(i<250))
           i++;
      SCL=0;
    delay();
}

void init()      //初始化
{
  SDA=1;
    delay();
  SCL=1;
    delay();   
}

uchar read_byte()
{
   uchar i,k;
        SCL=0;
    delay();
  SDA=1;
    delay();
  for(i=0;i<8;i++)
   {
         SCL=1;
            delay();
          k=(k<<1)|SDA;//先左移一位,再在最低位接受当前位
             SCL=0;
            delay();
  }
return k;

}

void write_byte(uchar date)       //写一字节数据
{
       uchar i,temp;
     temp=date;
        for(i=0;i<8;i++)
   {
         temp=temp<<1; //左移一位 移出的一位在CY中
          SCL=0;                      //只有在scl=0时sda能变化值
                delay();
          SDA=CY;
           delay();
          SCL=1;
            delay();            
  }   
  SCL=0;
    delay();
  SDA=1;
    delay();
}


uchar read_add(uchar control)
{
  uchar date;
       start();
  write_byte(PCF8591);
      respons();
        write_byte(control);
      respons();
        start();
  write_byte(PCF8591+1);       //把最后一位变成1,读
     respons();
        date=read_byte();
stop();
   return date;

}


void DigDisplay()
{
        char i;
        for(i=0;i<3;i++)
        {
                switch(i)         //位选,选择点亮的数码管,
                {
                        case(0):
                                LSA=0;LSB=0;LSC=0; break;//显示第0位
                        case(1):
                                LSA=1;LSB=0;LSC=0; break;//显示第1位
                        case(2):
                                LSA=0;LSB=1;LSC=0; break;//显示第2位       
                }
                P1=disp[i];//发送数据
                delay(); //间隔一段时间扫描       
                P1=0x00;//消隐
        }               
}



void main()
{      
  uchar temp0,temp1,temp2,i;
     init();
   while(1)
  {            for(i=0;i<5;i++)
         {
                     temp0=read_add(0x00);           //通道0
                 }
                 delay();
                 for(i=0;i<5;i++)
                 {
                     temp1=read_add(0x01);           //通道1
                 }
                 delay();
                 for(i=0;i<5;i++)
                 {
                     temp2=read_add(0x10);           //通道2
                 }
                 if(temp0>=22)
                 {
                     led=1;
                         if(temp1>=100&&temp1<=150)
                         {
                             disp[0]=table[0];
                                 disp[1]=table[0];
                                 disp[2]=table[0];
                         }
                         else if(150<temp1&&temp1<160)
                              {
                                  disp[0]=table[temp1-150];
                                      disp[1]=table[0];
                                      disp[2]=table[1];
                              }
                              else if(temp1<100&&temp2>100)
                                   {
                                       disp[0]=table[9];
                                           disp[1]=table[1];
                                           disp[2]=table[0];
                                   }
                                   else         if(temp1>=160)
                                   {
                                       disp[0]=table[9];
                                           disp[1]=table[0];
                                           disp[2]=table[1];
                                   }
                                           else
                                           {
                                               disp[0]=table[2];
                                           disp[1]=table[2];
                                           disp[2]=table[2];
                                           }
                 }
                 else
                 {
                     led=0;
                         disp[0]=table[0];
                         disp[1]=table[0];
                     disp[2]=table[0];
                 }
                 DigDisplay();
  }                 

}



分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:111634 发表于 2018-6-1 07:18 | 只看该作者
冗长程序一般是没人看的!你自己可用keil运行查错。
回复

使用道具 举报

板凳
ID:337248 发表于 2018-6-1 12:44 | 只看该作者
zl2168 发表于 2018-6-1 07:18
冗长程序一般是没人看的!你自己可用keil运行查错。

老哥:可以看下主程序吗
回复

使用道具 举报

地板
ID:111634 发表于 2018-6-1 22:37 | 只看该作者
sbwz 发表于 2018-6-1 12:44
老哥:可以看下主程序吗

可介绍你一个PCF8591AD案例,自己去理解体会,对照查错吧!
实例85  PCF8591 I2C串行A-D(1602显示)

Proteus仿真一下,确认有效。
实例85 PCF8591 I2C串行A-D.rar (57.96 KB, 下载次数: 5)
以上摘自张志良编著《80C51单片机仿真设计实例教程——基于Keil CProteus》清华大学出版社ISBN 978-7-302-41682-1书中电路和程序设计有详细说明,程序语句条条有注解。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表