打印

看了一个月没找出问题的程序,但是确实有问题

[复制链接]
5018|24
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
I2c, sd, AD, TE, ST
本帖最后由 gonglong 于 2013-11-4 15:25 编辑

lcd1602程序没问题,主要是i2c程序有问题!!!!!
/**********************
以下为i2c.h代码
*************/
#ifndef _I2C_H
#define _I2C_H

#include<reg51.h>


#ifndef uchar
#define uchar unsigned char
#endif

#ifndef uint
#define uint unsigned int
#endif

sbit scl=P2^1;
sbit sda=P2^0;

void i2c_start();
void i2c_stop();
void i2c_ack();
void init();
void i2c_writebyte(uchar num);
void i2cwrite(uchar add,uchar dat);
uchar i2c_readbyte();
uchar i2cread(uchar add);
void I2C_Delay10us();
#endif
/*********************
以下为i2c.h代码
***************/

#include"i2c.h"

void  init()
{
        sda=1;
I2C_Delay10us();
        scl=1;
I2C_Delay10us();
}

void I2C_Delay10us()
{
        uchar a, b;
        for(b=1; b>0; b--)
        {
                for(a=2; a>0; a--);
        }
}

void i2c_start()
{                                      
        sda=1;
        I2C_Delay10us();
        scl=1;
        I2C_Delay10us();//建立时间
        sda=0;
        I2C_Delay10us();//保持时间
        scl=0;
        I2C_Delay10us();//保持时间        
}

void i2c_stop()
{
        sda=0;
        I2C_Delay10us();
        scl=1;
        I2C_Delay10us();
        sda=1;
        I2C_Delay10us();        
}

void i2c_ack()
{
        uchar i=0;
        scl=1;
        I2C_Delay10us();
        while((sda==1)&&(i<200))
        {
                i++;
        }
        scl=0;
        I2C_Delay10us();               
}

void i2c_writebyte(uchar num)
{
        uchar i;
        scl=0;
        for(i=0;i<8;i++)
        {
                sda = num >> 7;         //起始信号之后I2C_SCL=0,所以可以直接改变I2C_SDA信号
                num=num<<1;
        I2C_Delay10us();         
        scl=1;
        I2C_Delay10us();
        }
        scl=0;
        I2C_Delay10us();
        sda=1;
        I2C_Delay10us();                                


}
uchar i2c_readbyte()
{
        uchar i;
        uchar dat;
        sda=0;
        I2C_Delay10us();
        scl=0;
        I2C_Delay10us();
        for(i=0;i<8;i++)
        {
                scl=1;
                I2C_Delay10us();
                dat=dat<<1;
                if(sda)
                {
                        dat++;
                }
        }
        I2C_Delay10us();
        return dat;                                       
}

void i2cwrite(uchar add,uchar dat)
{
        i2c_start();
        i2c_writebyte(0xa0);
        i2c_ack();
        i2c_writebyte(add);
        i2c_ack();
        i2c_writebyte(dat);
        i2c_ack();
        i2c_stop();                                                
}

uchar i2cread(uchar add)
{
        uchar value;
        i2c_start();
        i2c_writebyte(0xa0);
        i2c_ack();
        i2c_writebyte(add);
        i2c_ack();
        i2c_start();
        i2c_writebyte(0xa1);
        i2c_ack();
        value=i2c_readbyte();
        i2c_stop();
        return value;               
}

/******
以下为主函数代码
***********/
#include<reg51.h>

#include"i2c.h"
#include"lcd.h"

sbit K1=P3^0;
sbit K2=P3^1;
sbit K3=P3^2;
sbit K4=P3^3;

uchar table1[]= "write:11";
uchar table2[]= " read:22";

void Delay10ms(unsigned int c)   //误差 0us
{
    unsigned char a, b;

        //--c已经在传递过来的时候已经赋值了,所以在for语句第一句就不用赋值了--//
    for (;c>0;c--)
        {
                for (b=38;b>0;b--)
                {
                        for (a=130;a>0;a--);
                }         
        }      
}

main()
{
        
        uchar i,n=0;
        uchar num0=0,num1=0;
        LcdInit();
        init();

        LcdWriteCom(0x80);

        for(i=0;i<8;i++)
        {
                LcdWriteData( table1);                        
        }
        LcdWriteCom(0x80+0x40);
        for(i=0;i<8;i++)
        {
                LcdWriteData( table2);                        
        }
        while(1)
        {
        if(K1 == 0)
        {
        Delay10ms(1);
                if(K1 == 0)
                {
               
                        i2cwrite(2,num0);
                        while((K1 == 0)&&(n<50))
                                {
                                        n++;
                                        Delay10ms(1);        
                                }
                                n=0;
                }                                       
        }
        if(K2 == 0)
        {
         Delay10ms(1);
         if(K2 == 0)
                 {
                 num1=i2cread(2);
                         while((K2==0)&&(n<50))
                                {
                                        n++;
                                        Delay10ms(1);        
                                }
                                n=0;        
                }
        }
        if(K3 == 0)
        {
                Delay10ms(1);
                if(K3 == 0)
                {
                        num0++;
                }
                while((K3 == 0)&&(n<50))
                                {
                                        n++;
                                        Delay10ms(1);        
                                }
                                n=0;
                                if(num0==256)
                                {
                                        num0=0;
                                }                        
        }
        if(K4==0)
        {
                Delay10ms(1);
                if(K4==0)
                {
                        num0=0;
                }
                        while((K4==0)&&(n<50))
                                {
                                        n++;
                                        Delay10ms(1);        
                                }
                                n=0;
                        
        }                                                               
                LcdWriteCom(0x86);               
                LcdWriteData('0' + (num0/1000));//千位               
                LcdWriteData('0' + (num0%1000/100));//百位                                       
                LcdWriteData('0' + (num0%1000%100/10));//十位
                LcdWriteData('0' + (num0%1000%100%10));//个位

                LcdWriteCom(0x86 + 0x40);
                LcdWriteData('0' + (num1/1000));//千位               
                LcdWriteData('0' + (num1%1000/100));//百位                                       
                LcdWriteData('0' + (num1%1000%100/10));//十位
                LcdWriteData('0' + (num1%1000%100%10));//个位
}
}
/****************
Lcd.h代码
***************/
#ifndef __LCD_H_
#define __LCD_H_
/**********************************
当使用的是4位数据传输的时候定义,
使用8位取消这个定义
**********************************/
#define LCD1602_4PINS

/**********************************
包含头文件
**********************************/
#include<reg51.h>

//---重定义关键词---//
#ifndef uchar
#define uchar unsigned char
#endif

#ifndef uint
#define uint unsigned int
#endif

/**********************************
PIN口定义
**********************************/
#define LCD1602_DATAPINS P0
sbit LCD1602_E=P2^7;
sbit LCD1602_RW=P2^5;
sbit LCD1602_RS=P2^6;

/**********************************
函数声明
**********************************/
/*在51单片机12MHZ时钟下的延时函数*/
void Lcd1602_Delay1ms(uint c);   //误差 0us
/*LCD1602写入8位命令子函数*/
void LcdWriteCom(uchar com);
/*LCD1602写入8位数据子函数*/        
void LcdWriteData(uchar dat);
/*LCD1602初始化子程序*/               
void LcdInit();                                                  

#endif
/****************
Lcd.c代码
***************/
#include"lcd.h"

/*******************************************************************************
* 函 数 名         : Lcd1602_Delay1ms
* 函数功能                   : 延时函数,延时1ms
* 输    入         : c
* 输    出         : 无
* 说    名         : 该函数是在12MHZ晶振下,12分频单片机的延时。
*******************************************************************************/

void Lcd1602_Delay1ms(uint c)   //误差 0us
{
    uchar a,b;
        for (; c>0; c--)
        {
                 for (b=199;b>0;b--)
                 {
                          for(a=1;a>0;a--);
                 }      
        }
            
}

/*******************************************************************************
* 函 数 名         : LcdWriteCom
* 函数功能                   : 向LCD写入一个字节的命令
* 输    入         : com
* 输    出         : 无
*******************************************************************************/
#ifndef         LCD1602_4PINS         //当没有定义这个LCD1602_4PINS时
void LcdWriteCom(uchar com)          //写入命令
{
        LCD1602_E = 0;     //使能
        LCD1602_RS = 0;           //选择发送命令
        LCD1602_RW = 0;           //选择写入
        
        LCD1602_DATAPINS = com;     //放入命令
        Lcd1602_Delay1ms(1);                //等待数据稳定

        LCD1602_E = 1;                  //写入时序
        Lcd1602_Delay1ms(5);          //保持时间
        LCD1602_E = 0;
}
#else
void LcdWriteCom(uchar com)          //写入命令
{
        LCD1602_E = 0;         //使能清零
        LCD1602_RS = 0;         //选择写入命令
        LCD1602_RW = 0;         //选择写入

        LCD1602_DATAPINS = com;        //由于4位的接线是接到P0口的高四位,所以传送高四位不用改
        Lcd1602_Delay1ms(1);

        LCD1602_E = 1;         //写入时序
        Lcd1602_Delay1ms(5);
        LCD1602_E = 0;

//        Lcd1602_Delay1ms(1);
        LCD1602_DATAPINS = com << 4; //发送低四位
        Lcd1602_Delay1ms(1);

        LCD1602_E = 1;         //写入时序
        Lcd1602_Delay1ms(5);
        LCD1602_E = 0;
}
#endif
/*******************************************************************************
* 函 数 名         : LcdWriteData
* 函数功能                   : 向LCD写入一个字节的数据
* 输    入         : dat
* 输    出         : 无
*******************************************************************************/                  
#ifndef         LCD1602_4PINS                  
void LcdWriteData(uchar dat)                        //写入数据
{
        LCD1602_E = 0;        //使能清零
        LCD1602_RS = 1;        //选择输入数据
        LCD1602_RW = 0;        //选择写入

        LCD1602_DATAPINS = dat; //写入数据
        Lcd1602_Delay1ms(1);

        LCD1602_E = 1;   //写入时序
        Lcd1602_Delay1ms(5);   //保持时间
        LCD1602_E = 0;
}
#else
void LcdWriteData(uchar dat)                        //写入数据
{
        LCD1602_E = 0;          //使能清零
        LCD1602_RS = 1;          //选择写入数据
        LCD1602_RW = 0;          //选择写入

        LCD1602_DATAPINS = dat;        //由于4位的接线是接到P0口的高四位,所以传送高四位不用改
        Lcd1602_Delay1ms(1);

        LCD1602_E = 1;          //写入时序
        Lcd1602_Delay1ms(5);
        LCD1602_E = 0;

        LCD1602_DATAPINS = dat << 4; //写入低四位
        Lcd1602_Delay1ms(1);

        LCD1602_E = 1;          //写入时序
        Lcd1602_Delay1ms(5);
        LCD1602_E = 0;
}
#endif











相关帖子

沙发
金融小数| | 2013-11-4 10:45 | 只看该作者
问题很多,楼主看出来了吗?:lol

使用特权

评论回复
板凳
ayb_ice| | 2013-11-4 11:17 | 只看该作者
本帖最后由 ayb_ice 于 2013-11-4 13:37 编辑

就这,还一个月没有发现问题啊

这下面代码就有问题啊
        for(i=0;i<8;i++)
        {
                sda = num >> 7;         //起始信号之后I2C_SCL=0,所以可以直接改变I2C_SDA信号
                num=num<<1;
        I2C_Delay10us();         
        scl=1;
        I2C_Delay10us();
        }

使用特权

评论回复
地板
ningling_21| | 2013-11-4 11:21 | 只看该作者
问题太多了,所以看不出来.
void i2c_ack()
{
        uchar i=0;
        scl=1;
        I2C_Delay10us();
        while((sda==1)&&(i<200))
        {
                i++;
        }
        scl=0;
        I2C_Delay10us();               
}

使用特权

评论回复
5
ballack_linux| | 2013-11-4 14:27 | 只看该作者
楼主 一大段代码这样贴上来,没几个人会仔细看的 ,建议如下:
1、测试I2C驱动程序
2、测试1602驱动程序
3、联调
不知楼主是否是这样做的 ,如果前两步已经做了,那么完全没有必要把那部分代码贴出来,
而且你也没描述清楚是什么问题,具体问题要具体分析,你把遇到的问题描述出来才方便解决!!

使用特权

评论回复
6
gonglong|  楼主 | 2013-11-4 15:26 | 只看该作者
金融小数 发表于 2013-11-4 10:45
问题很多,楼主看出来了吗?

:'(没看出来啊

使用特权

评论回复
7
gonglong|  楼主 | 2013-11-4 15:26 | 只看该作者
ayb_ice 发表于 2013-11-4 11:17
就这,还一个月没有发现问题啊

这下面代码就有问题啊

什么问题啊???:dizzy:

使用特权

评论回复
8
gonglong|  楼主 | 2013-11-4 15:27 | 只看该作者
ayb_ice 发表于 2013-11-4 11:17
就这,还一个月没有发现问题啊

这下面代码就有问题啊

问题在哪??:dizzy:

使用特权

评论回复
9
gonglong|  楼主 | 2013-11-4 15:27 | 只看该作者
ayb_ice 发表于 2013-11-4 11:17
就这,还一个月没有发现问题啊

这下面代码就有问题啊

问题在哪??:dizzy:

使用特权

评论回复
10
gonglong|  楼主 | 2013-11-4 15:30 | 只看该作者
ballack_linux 发表于 2013-11-4 14:27
楼主 一大段代码这样贴上来,没几个人会仔细看的 ,建议如下:
1、测试I2C驱动程序
2、测试1602驱动程序

问题出在i2c.c的程序中,读写功能没有实现

使用特权

评论回复
11
guangbiao| | 2013-11-4 15:42 | 只看该作者
用示波器盯着SCL/SDA线看。。。再调试运行。。。注意外挂的I2C器件的片选引脚配置正确。。。。

使用特权

评论回复
12
ayb_ice| | 2013-11-4 16:14 | 只看该作者
RT:

未命名.PNG (4.7 KB )

未命名.PNG

使用特权

评论回复
13
joyme| | 2013-11-4 16:39 | 只看该作者
太大意了!
      for(i=0;i<8;i++)
        {
                sda = num >> 7;         
                num=num<<1;
                I2C_Delay10us();         
                scl=1;
                I2C_Delay10us();
                scl = 0;                   //没有这句无法开始下一位数据的传输
        }

使用特权

评论回复
14
江枫渔火| | 2013-11-4 16:45 | 只看该作者
应该不是什么大事~

使用特权

评论回复
15
很忙| | 2013-11-4 16:56 | 只看该作者
都是人才啊。

使用特权

评论回复
16
yinhexi| | 2013-11-4 18:05 | 只看该作者
紧盯时序图写代码!

使用特权

评论回复
17
风云再起| | 2013-11-4 18:14 | 只看该作者
这里果然是大神多多啊!!!!!!

使用特权

评论回复
18
eydj2008| | 2013-11-4 19:05 | 只看该作者
一句一句写 就不错出错了。 开始是这样的有可能二个月 都不能解决一个问题。

使用特权

评论回复
19
黄小俊| | 2013-11-4 21:04 | 只看该作者
,眼花缭乱的

使用特权

评论回复
20
gcxzhz| | 2013-11-4 22:16 | 只看该作者
yinhexi 发表于 2013-11-4 18:05
紧盯时序图写代码!

正解

使用特权

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

本版积分规则

7

主题

17

帖子

1

粉丝