打印

IIC总线和LCD驱动冲突,各位来看看.

[复制链接]
3603|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
单片小白菜|  楼主 | 2009-6-22 10:10 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

各位老大我最近在测试24C08程序的时候碰到一个问题...
我的IIC总线程序是丁丁写的程序,我在单独写加判断的时候程序一切正常.

主函数如下...在写的时候把这个I的值不停的送到2408然后再读出再判断.结果是很正常.

/*
void main(void)    // 主程序
{
    uint8 c1=0;
    uint16 i=0;
    while(1)
    {
        for(i=0;i<0xff;i++)
            {
                Write24c02(i,i);                         //写数据进24C08;
                c1=Read24c02(i);                        //读出写入的数据;
                if(c1==i)                            //判断写入的数据和读出的是否对.
                    {
                        P00=0;                           //P00 LED亮;
                        P01=1;                          //P01 熄灭;
                        BUZZ();                           //蜂鸣器响;
                    }                            //如果不相等;
                else
                    {
                        //BUZZ();
                        P00=1;                        //P01 LED熄灭;
                        P01=0;                        //P00 LED亮.
                    }
            }

     }
}
*/

但当我加上了LCD显示程序后.这结果就不正常了...
函数如下...

我向2408内部写入0X56读出来的却是0XFF...
我想这个是不是LCD和IIC总线冲突了,而我找遍了,也没找到这个冲突的地方.
而且把中断关了,也不能使这个读出的数据正常...


void main()
{
    uint16 a=0;
    uint8 b=0;
    Initial_Lcd();                            //初始化LCD.
    while(1)                            //循环.
       DISPLAY_LCD1();                            //调用显示程序.

}        




void DISPLAY_LCD1()
{

    Write24c02(0x10,Data1);                        //写数据进2408
    Delay(5);                             //延时;
    Data2=Read24c02(0x10);                        //读出数据;
    Display_One(0,0,Lcd_Data[Data1/16]);                //显示写入数据十位.
    Display_One(0,1,Lcd_Data[Data1%16]);                //显示写入数据个位.
    Display_One(0,3,Lcd_Data[Data2/16]);                //显示读出数据十位.
    Display_One(0,4,Lcd_Data[Data2%16]);                //显示读出数据个位.
}

请大家帮我分析一下这个原因....


下面附上源程序...




#include<AT89X52.H>
#include<intrins.h>
#define uint8  unsigned char
#define uint16 unsigned int
#define WriteDeviceAddress 0xA0
#define Read_Device_Address  0xA1
#define nop() _nop_()


sbit P00=P0^0;    //LED;
sbit P01=P0^1;

sbit SCL=P2^6;    //IIC
sbit SDA=P2^7;

sbit RS=P1^0;    //LCD
sbit RW=P1^1;
sbit EN=P1^2;
sbit P17=P1^7;

uint8 Data1=0x56;
uint8 Data2=0;
uint8 Lcd_Data[]=
{
        '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
};

#define LCD_DATA P0


//////////////////////////////////////////////////////////////////////////////////
//LCD驱动函数.

void Busy();//检测忙函数;
void Write_InLcdData(uint8 In_Data);//写数据函数;
void Write_Instruction(uint8 In_Data);//写指令函数;
void Dean_Lcd();//清屏函数;
void Initial_Lcd();//LCD初始化设置函数;
void Lcd_Set_Position(uint8 x);//把光标置指定位置函数;
void Display_One(uint8 y,uint8 x,uint8 In_Data);//在指定位置显示一个字符;
void Delay(uint16 i);
void DISPLAY_LCD1();   
void DelayMs(uint16 number);

//////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////
//IIC总线驱动函数.

void Start();
void Stop();
void NoAck();
bit TestAck();
Write8Bit(uint8 input);
void Write24c02(uint8 ch,uint8 address);
uint8 Read8Bit();
uint8 Read24c02(uint8 address);
void BUZZ();

//////////////////////////////////////////////////////////////////////////////////




/******************************************************************************************************************************
/******************************************************************************************************************************
/******************************************************************************************************************************
//第一个测试程序,没有运行LCD部分非常正常....

/*
void main(void)    // 主程序
{
    uint8 c1=0;
    uint16 i=0;
    while(1)
    {
        for(i=0;i<0xff;i++)
            {
                Write24c02(i,i);            //写数据进24C08;
                c1=Read24c02(i);            //读出写入的数据;
                if(c1==i)                //判断写入的数据和读出的是否对.
                    {
                        P00=0;               //P00 LED亮;
                        P01=1;              //P01 熄灭;
                        BUZZ();            //蜂鸣器响;
                    }                            
                else                    //如果不相等;
                    {
                        //BUZZ();
                        P00=1;            //P01 LED熄灭;
                        P01=0;            //P00 LED亮.
                    }
            }

     }
}
*/
************************************************************************************************************************************/
************************************************************************************************************************************/
************************************************************************************************************************************/



////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



第二测试程序...运行了LCD,结果不正常...
输入DATA1=0X56.
读出的DATA2=0XFF.


void main()
{
    uint16 a=0;
    uint8 b=0;
    Initial_Lcd();                        //初始化LCD.
    while(1)                        //循环.
       DISPLAY_LCD1();                        //调用显示程序.

}        




void DISPLAY_LCD1()
{

    Write24c02(0x10,Data1);                    //写数据进2408
    Delay(5);                         //延时;
    Data2=Read24c02(0x10);                    //读出数据;
    Display_One(0,0,Lcd_Data[Data1/16]);            //显示写入数据十位.
    Display_One(0,1,Lcd_Data[Data1%16]);            //显示写入数据个位.
    Display_One(0,3,Lcd_Data[Data2/16]);            //显示读出数据十位.
    Display_One(0,4,Lcd_Data[Data2%16]);            //显示读出数据个位.
}


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////




//下面为IIC总线驱动程序.

//定时函数
void DelayMs(uint16 number) 
{
    uint8 temp;
    for(;number!=0;number--) 
    {
        for(temp=112;temp!=0;temp--) ;
    }
}

//开始总线
void Start() 
{
    SDA=1;
    SCL=1;
    SDA=0;
    SCL=0;
}

//结束总线
void Stop() 
{
    SCL=0;
    SDA=0;
    SCL=1;
    SDA=1;
}


//发ACK0
void NoAck() 
{
    SDA=1;
    SCL=1;
    SCL=0;
}

//测试ACK
bit TestAck() 
{
    bit ErrorBit;
    SDA=1;
    SCL=1;
    ErrorBit=SDA;
    SCL=0;
    return(ErrorBit);
}

//写入8个bit到24c02
Write8Bit(uint8 input) 
{
    uint8 temp;
    for(temp=8;temp!=0;temp--) 
    {
        SDA=(bit)(input&0x80);
        SCL=1;
        SCL=0;
        input=input<<1;
    }
}

//写入一个字节到24c02中
void Write24c02(uint8 ch,uint8 address) 
{
    EA=0;
    Start();
    Write8Bit(WriteDeviceAddress);
    TestAck();
    Write8Bit(address);
    TestAck();
    Write8Bit(ch);
    TestAck();
    Stop();
    DelayMs(10);
    EA=1;
}

/////从24c02中读出8个bit  ;

uint8 Read8Bit() 
{
    uint8 temp,rbyte=0;
    for(temp=8;temp!=0;temp--) 
    {
        SCL=1;
        rbyte=rbyte<<1;
        rbyte=rbyte|((unsigned char)(SDA));
        SCL=0;
    }
    return(rbyte);
}

//从24c02中读出1个字节
uint8 Read24c02(uint8 address) 
{
    uint8 ch;
    EA=0;
    Start();
    Write8Bit(WriteDeviceAddress);
    TestAck();
    Write8Bit(address);
    TestAck();
    Start();
    Write8Bit(Read_Device_Address);
    TestAck();
    ch=Read8Bit();
    NoAck();
    Stop();
    EA=1;
    return(ch);
}



void BUZZ()
{
    P17=0;
    DelayMs(500);
    P17=1;
}

    
    
////////////////////////////////////////////////////////////////////////////////





//下面部分为LCD驱动函数.

////////////////////////////////////////////////////////////////////////////////

//函数名:Busy
//功能描述:检测LCD是否在忙的状态;
///////////////如果LCD处于忙则等侍;
//函数说明:
//调用函数:无;
//全局变量:无;
//输入:无;
//返回:无

////////////////////////////////////////////////////////////////////////////////

void Busy()
{
    uint8 i = 255;
    LCD_DATA=0xff;    
    RS=0;
    RW=1;
    EN=0;
    EN=0;
    _nop_();
    _nop_();    
    EN=1;
    while((i--)&&(LCD_DATA&0x80));
}


////////////////////////////////////////////////////////////////////////////////

//函数名:Write_Instruction
//功能描述:向LCD内部写入指令.
//函数说明:
//调用函数:Busy()检测忙函数;
//全局变量:无;
//输入:无In_Data
//返回:无;

////////////////////////////////////////////////////////////////////////////////

void Write_Instruction(uint8 In_Data)
{
    Busy();
    RS=0;
    RW=0;
    LCD_DATA=In_Data;
    EN=0;
    EN=0;
    _nop_();
    _nop_();    
    EN=1;
}


////////////////////////////////////////////////////////////////////////////////

//函数名:Write_InLcdData
//功能描述:向LCD内部写入数据,让LCD显示字符或数字.
//函数说明:
//调用函数:Busy()检测忙函数;
//全局变量:无;
//输入:In_Data
//返回:无;

////////////////////////////////////////////////////////////////////////////////

void Write_InLcdData(uint8 In_Data)
{
    Busy();
    RS=1;
    RW=0;
    LCD_DATA=In_Data;
    EN=0;
    EN=0;
    _nop_();
    _nop_();    
    EN=1;
}

////////////////////////////////////////////////////////////////////////////////

//函数名:Dean_Lcd
//功能描述:清除LCD屏幕上的信息;
//函数说明:
//调用函数:Write_Instruction;写数据;
//全局变量:无;
//输入:无;
//返回:无;

////////////////////////////////////////////////////////////////////////////////

void Dean_Lcd()
{
    Write_Instruction(0x01);
}

////////////////////////////////////////////////////////////////////////////////

//函数名:Initial_Lcd;
//功能描述:LCD1602初始化;
//函数说明:写入0X38 0X08 0X06 0X01 0X0C设置LCD参数;
//调用函数:Write_Instruction;写指令;
//全局变量:无;
//输入:无;
//返回:无;

////////////////////////////////////////////////////////////////////////////////

void Initial_Lcd()
{
    Delay(38);
    Write_Instruction(0x38);
    Delay(38);
    Write_Instruction(0x38);
    Delay(5);
    Write_Instruction(0x38);
    Write_Instruction(0x08);
    Dean_Lcd();
    Write_Instruction(0x06);
    Write_Instruction(0x0c);
}

////////////////////////////////////////////////////////////////////////////////

//函数名:Lcd_Set_Position;
//功能描述:把把LCD光标定位在某一个位置;
//函数说明:
//调用函数:Write_Instruction;写指令;
//全局变量:无;
//输入:无;
//返回:无;

////////////////////////////////////////////////////////////////////////////////

/*
void Lcd_Set_Position(uint8 x)
{
    Write_Instruction(0x80+x);
}
*/
////////////////////////////////////////////////////////////////////////////////

//函数名:Display_One;
//功能描述:在LCD指定位置显示一个字符;
//函数说明:
//调用函数:Write_Instruction;写指令;write_InLcdData;写数据;
//全局变量:无;
//输入:无;
//返回:无;

////////////////////////////////////////////////////////////////////////////////
void Display_One(uint8 y,uint8 x,uint8 In_Data)
{
    y&=0x01;
    x&=0x0f;
    if(y)
        {
            x+=0x40;
        }
    x+=0x80;
    Write_Instruction(x);
    Write_InLcdData(In_Data);
}



void Delay(uint16 i)
{
    uint8 j,k;
    for(;i>0;i--)
        {
            for(j=247;j<0;j--)
                {
                    for(k=100;k>0;k--);
                }
        }
}

相关帖子

沙发
电子空对穴| | 2009-6-22 16:49 | 只看该作者

好长,好烦

使用特权

评论回复
板凳
ayb_ice| | 2009-6-22 20:46 | 只看该作者

好长,好烦

使用特权

评论回复
地板
naren| | 2009-6-22 20:56 | 只看该作者

将第二个程序的写I2C输入参数反过来!

原代码:
    Write24c02(0x10,Data1);                    //写数据进2408
    Delay(5);                         //延时;
    Data2=Read24c02(0x10);                    //读出数据;

修改后:
    Write24c02(Data1,0x10);                    //写数据进2408
    Delay(5);                         //延时;
    Data2=Read24c02(0x10);                    //读出数据;

使用特权

评论回复
5
耕在此行| | 2009-6-24 07:52 | 只看该作者

呵呵 太长啰

不想看了

使用特权

评论回复
6
mcufan001| | 2009-6-24 16:33 | 只看该作者

4楼眼尖,IIC指定地址写入数据的参数传递错了,地址和数据颠

4楼眼尖,IIC指定地址写入数据的参数传递错了,地址和数据颠倒了

使用特权

评论回复
7
naren| | 2009-6-26 17:59 | 只看该作者

其实是近视眼,呵呵

有两个程序作对比,比较容易判断

使用特权

评论回复
8
沈洁| | 2009-6-28 12:22 | 只看该作者

确实帮他看还不如自己从新写一遍呢

: 呵呵 太长啰 

不想看了 
 

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

8

主题

13

帖子

1

粉丝