[求助] 单片机pcf8591

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


#include
#include
#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;
          }
}
}
  • IMG_20130908_162806.jpg

回复评论 (3)

电位器不合适,给的变化量太大,,或者程序处理不了,,编程的问题?
一块期待高手,,,
点赞  2013-9-8 17:55

回复 楼主金大鹏 的帖子

很简单的问题,你用得是单端输入吧!我不知道你用得是内部AD还是外部AD器件,可以打断点看下取到的AD具体数值,当显示为零的时候,取到AD到底是多少,有没有溢出或者程序死在哪里!
点赞  2013-9-9 17:14

回复 板凳goalpeak 的帖子

恩,在特定的数字就会发生这个情况,
void keyscan()
{

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

  
}
void main()
{
        uint m,b;
    init();       
    while(1)
{
        keyscan();
        if(i==1)
        {
                b=(int)adchange(0x01);
                m=b*100/51;
                display1(m);
        }
        if(i==2)
          {       
                display1(0);
          }
}
}
把这部分换掉就没问题了,感觉逻辑一样啊
点赞  2013-9-10 09:22
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复