51单片机 I2C与中断共存问题
时间:10-02
整理:3721RD
点击:
把显示函数display()放在定时器中断T0里,把AD(PCF8591)读取放在主函数的while(1)循环里,就出了问题,我在AD函数里做了EA=0;EA=1;的避免干扰 还是不行 以下为代码:
#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
uchar code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0xbf};
uchar discom[8];
uchar i;
uchar num0;
sbit sda=P2^1;
sbit scl=P2^0;
uchar ad;
void buzz()
{
P2=(P2&0x1f)|0xa0;
P0=0;
P2&=0x1f;
}
/**************************************************************************************
****************************************************************************************/
void delay()
{_nop_();}
void i2cinit()
{
scl=1;
delay();
sda=1;
delay();
}
void start()
{
EA=0;
sda=1;
delay();
scl=1;
delay();
sda=0;
delay();
EA=1;
}
void respons()
{
uchar i;
EA=0;
scl=1;
delay();
while((sda==1)&&(i<255))
i++;
scl=0;
delay();
EA=1;
}
void stop()
{
EA=0;
sda=0;
delay();
scl=1;
delay();
sda=1;
delay();
EA=1;
}
void writebyte(uchar date)
{
uchar i;
EA=0;
for(i=0;i<8;i++)
{
scl=0;
delay();
sda=(date<<i)&0x80;
delay();
scl=1;
delay();
}
scl=0;
delay();
sda=1;
delay();
EA=1;
}
uchar readbyte()
{
uchar i,temp;
EA=0;
scl=0;
delay();
for(i=0;i<8;i++)
{
temp=temp<<1;
scl=1;
delay();
if(sda)temp|=0x01;
scl=0;
delay();
}
EA=1;
return temp;
}
/**************************************************************************************
****************************************************************************************/
uchar read_add(uchar control)
{
uchar date;
EA=0;
start();
writebyte(0x90);
respons();
writebyte(control);
respons();
start();
writebyte(0x91);
respons();
date=readbyte();
stop();
EA=1;
return date;
}
void display()
{
P2=(P2&0x1f)|0xc0;
P0=1<<i;
P2&=0x1f;
P2=(P2&0x1f)|0xe0;
P0=table[discom];
P2&=0x1f;
if(i++==7)
i=0;
}
void timeinit()
{
TMOD=0x01;
TH0=(65536-1000)/256;
TL0=(65536-1000)%256;
EA=1;
ET0=1;
TR0=1;
}
void main()
{
buzz();
i2cinit();
timeinit();
while(1)
{
ad=read_add(0x43); //0100 0011 ??í¨μàμ¥??ê?è? ????í¨μàAIN3£o0011
discom[0]=ad/100;
discom[1]=ad%100/10;
discom[2]=ad%10;
discom[3]=10;
discom[4]=10;
discom[5]=10;
discom[6]=10;
discom[7]=10;
}
}
void t0() interrupt 1
{
TH0=(65536-1000)/256;
TL0=(65536-1000)%256;
num0++;
if(num0==2)
{
num0=0;
display();
}
}
试一下中断时间进行ad检测读取,while里进行显示看看能不能正常
那样是可以,但是如果必须要把显示放中断里 问题出在哪呢
那样的话你debug一下具体是测量不准确了还是显示不正常了
测量的问题,那个ad值读回来恒为128
感觉写了太多的EA=0;EA=1;导致了测量时序不对了,可以试一下只在while读ad的位置上下加EA=0,EA=1;试试
还是不行啊...我也感觉是只加一个就行,但只加一个显示的更乱了
今天拿别人的I2C程序试了一下就没有问题,可能我这个I2C还是时序有点问题,自己跑还行,加个中断就出问题了,我再研究研究。谢谢哈
不客气,互帮互助
互帮互助,不要客气