单片机pcf8591

2019-03-24 18:39发布

//pcf8591实现一个电位器的ad转换,通过数码管显示;两个按键控制工作,停止;
IMG_20130908_163523.jpg
遇到的问题是:可以正常开始工作,转动电位器就会偶然导致工作停止,即显示为0(我设置在停止时全显示0);
可以通过按开始键重新工作;


#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
uchar code duan[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,
                   0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef};
uchar code we[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf};


sbit wela=P2^7;
sbit dula=P2^6;

sbit sda=P2^0;
sbit scl=P2^1;
sbit key1=P3^6;
sbit key2=P3^7;
uint temp;
void delay(){;;}
void delayms(uint x)
{
        uint i,j;
        for(i=x;i>0;i--)
        for(j=120;j>0;j--);
}
//数码管
void display(uchar pos,uchar dat)
{
        P0=we[pos];  wela=1;wela=0;
        P0=duan[dat];dula=1;dula=1;
        delayms(5);
}
void display1(uint dat)
{
        uchar a,b,c,d;
        a=0;
        b=dat/100;
        c=dat%100/10;
        d=dat%10;
        display(0,a);
        display(1,b+10);
        display(2,c);
        display(3,d);
}

//初始化
void init()
{
        sda=1;delay();
        scl=1;delay();
       
}
//iic
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 writebyte(uchar dat)
{
        uchar i,flag;
        flag=dat;
        for(i=0;i<8;i++)
        {
                flag<<=1;
                scl=0;delay();
                sda=CY;delay();
                scl=1;delay();
        }
        scl=0;delay();
        sda=1;delay();
}
uchar readbyte()
{
        uchar i,dat;
        scl=0;delay();
        sda=1;delay();
        for(i=0;i<8;i++)
        {
                scl=1;delay();
                dat=(dat<<1)|sda;
                scl=0;delay();
        }
        return dat;
}

//pcf8591
uchar adchange(uchar ctl)
{
        uchar dat;
        start();
        writebyte(0x90);
        respons();
        writebyte(ctl);
        respons();
        start();
        writebyte(0x91);
        respons();
        dat=readbyte();
        stop();
        return dat;
}

uchar keyscan()
{
        uchar i;
        if(key1==0)
                {       
                        delayms(10);
                        if(key1==0)
                        {
                                i=1;
                                while(!key1);
                        }
                }
        if(key2==0)
                {       
                        delayms(10);
                        if(key2==0)
                        {
                                i=2;
                                while(!key2);
                        }
                }

    return i;
}
void main()
{
        uint m,b;
        uchar flag=1;
    init();       
    while(1)
{
        if(flag==1)
        {
                b=(int)adchange(0x01);
                m=b*100/51;
                display1(m);
            if(keyscan()==2)flag=2;
          
        }
        if(flag==2)
          {       
                display1(0);
            if(keyscan()==1)flag=1;
          }
}
} 此帖出自小平头技术问答
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
3条回答
goalpeak
2019-03-25 03:17
很简单的问题,你用得是单端输入吧!我不知道你用得是内部AD还是外部AD器件,可以打断点看下取到的AD具体数值,当显示为零的时候,取到AD到底是多少,有没有溢出或者程序死在哪里!

一周热门 更多>