打印
[AVR单片机]

i/o口模拟I2C程序实现zlg7290键盘控制,i2c标志返回问题

[复制链接]
2122|11
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
我是模拟i2c写的,其中主机向从机发送数据时从机会返回标志位,但是不知道主机在接收数据时怎样写这个判断标志位,感觉主机不会返回吧,反正结果是如果判断就会卡死到那儿,不判断ack也不报错,数据也能正常发送,对i2c的理解太肤浅了,请大家谈谈经验,或者有什么讲i2c比较好的资料分享一下,谢谢了~~~~他通不过,我就硬让它通过了

@X69SBM4@}6FK4~NCM0X37H.jpg (32.7 KB )

@X69SBM4@}6FK4~NCM0X37H.jpg

相关帖子

沙发
qin552011373| | 2013-7-9 22:12 | 只看该作者
需要分享没有问题的源文件不?需要的话找我要

使用特权

评论回复
板凳
始于16|  楼主 | 2013-7-10 11:17 | 只看该作者
qin552011373 发表于 2013-7-9 22:12
需要分享没有问题的源文件不?需要的话找我要

恩,给分享一份吧,谢谢了

使用特权

评论回复
地板
ayb_ice| | 2013-7-10 16:57 | 只看该作者
谁接收数据就返回应答位,
这里的数据是指通信中的每个字节数据,
但主机接收最后一个数据返回非应答位,从机释放总线...

使用特权

评论回复
5
qin552011373| | 2013-7-11 10:15 | 只看该作者
始于16 发表于 2013-7-10 11:17
恩,给分享一份吧,谢谢了

晚上回去给你发  现在在公司

使用特权

评论回复
6
tsdwddp| | 2013-7-12 15:15 | 只看该作者
菜鸟路过
从机读时因为主机是模拟的时序,当然可以不判断应答位,但从机是标准的,时序是固定的,主机读时必须给应答为吧!

使用特权

评论回复
7
qin552011373| | 2013-7-12 17:49 | 只看该作者
/*
********************************************************************************
文件名:         IIC_config.h
内容描述:        IIC配置文件                       
作者:                筱禾
注解:               
日志:
        2012-10-19:创建文件
********************************************************************************
*/

#ifndef IIC_CONFIG_H_
#define IIC_CONFIG_H_

#define IIC_PORT PORTD
#define IIC_DDR         DDRD
#define IIC_PIN         PIND

#define IIC_SCL         BIT2
#define IIC_SDA  BIT3

#endif /* IIC_CONFIG_H_ */

使用特权

评论回复
8
qin552011373| | 2013-7-12 17:49 | 只看该作者
/*
********************************************************************************
文件名:         IIC.h
内容描述:        IIC函数头文件
作者:                筱禾
注解:               
日志:
        2012-10-18:创建文件
********************************************************************************
*/

#ifndef IIC_H_
#define IIC_H_

//函数原型声明
void IIC_Init(void);
void IIC_Delay(void);
void IIC_Start(void);
void IIC_Stop(void);
void IIC_Clock(void);
uint8 IIC_Ackn(void);
void IIC_WriteControl(uint8 u8_HardwareAddress, uint8 u8_ReadOrWrite);
void IIC_WriteByte(uint8 u8_Data);
uint8 IIC_ReadByte(void);
void IIC_WriteOneByteAddressDevice(uint8 u8_HardwareAddress, uint8 u8_MemoryAddress, uint8 u8_Data);
uint8 IIC_ReadOneByteAddressDevice(uint8 u8_HardwareAddress, uint8 u8_MemoryAddress);
void IIC_WriteTwoOneByteAddressDevice(uint8 u8_HardwareAddress, uint16 u16_MemoryAddress, uint8 u8_Data);
uint8 IIC_ReadTwoOneByteAddressDevice(uint8 u8_HardwareAddress, uint16 u16_MemoryAddress);

#endif /* IIC_H_ */

使用特权

评论回复
9
qin552011373| | 2013-7-12 17:50 | 只看该作者
/*
********************************************************************************
文件名:         IIC.c
内容描述:        IIC函数
作者:                筱禾
注解:               
日志:
        2012-10-19:创建文件
********************************************************************************
*/

#include "../../include.h"

#if EXTERNAL_MODULE_SD2405_MODE != 0

void IIC_Init(void)
{
        SETBIT(IIC_DDR, IIC_SCL);              // Set SCL to output
        SETBIT(IIC_DDR, IIC_SDA);                   // Set SDA to output
        SETBIT(IIC_PORT, IIC_SCL);             // Set SCL high
        SETBIT(IIC_PORT, IIC_SDA);            // Set SDA high
}

void IIC_Delay(void)
{
        TARGET_Delayus(1, 0);       
}

void IIC_Start( void )
{
        SETBIT(IIC_PORT, IIC_SCL);            // Set SCL High
        SETBIT(IIC_PORT, IIC_SDA);            // Set SDA High
        SETBIT(IIC_DDR, IIC_SDA);              // Set SDA to output
        CLRBIT(IIC_PORT, IIC_SDA);             // Clear SDA
}

void IIC_Stop( void )
{
        SETBIT(IIC_DDR, IIC_SDA);              // Set SDA to output
        CLRBIT(IIC_PORT, IIC_SDA);             // Clear SDA
        CLRBIT(IIC_PORT, IIC_SCL);             // Clear SCL
        SETBIT(IIC_PORT, IIC_SCL);             // Set SCL High
        IIC_Delay();
        SETBIT(IIC_PORT, IIC_SDA);                   // Set SDA High
}

void IIC_Clock( void )
{
        SETBIT(IIC_PORT, IIC_SCL);            // Set SCL high
        IIC_Delay();
        CLRBIT(IIC_PORT, IIC_SCL);             // Set SCL low
}

uint8 IIC_Ackn( void )
{
        uint8 Ackn = 0;                                                      // Temp RAM for Ackn flag
        CLRBIT(IIC_PORT, IIC_SCL);
        CLRBIT(IIC_DDR, IIC_SDA);                       // Set SDA to input
        SETBIT(IIC_PORT, IIC_SCL);                                       // Clock the ACK bit
        if (CHKBIT(IIC_PIN, IIC_SDA)) Ackn = 1;         // Check the ACK bit on SDA
        CLRBIT(IIC_PORT, IIC_SCL);                                     // Clear the clock
        return Ackn;                                                              // Return our ACK bit
}

void IIC_WriteControl( uint8 u8_HardwareAddress, uint8 u8_ReadOrWrite )
{
        // *** Send the I2C device Control code *** //
        CLRBIT(IIC_PORT, IIC_SCL);                                                                                        // Clear SCL clock
        if( (u8_HardwareAddress & 0x80) == 0x80) SETBIT(IIC_PORT, IIC_SDA);          // Set I2C SDA PIN
        else CLRBIT(IIC_PORT, IIC_SDA);                                                                                        // Clear I2C SDA PIN
        IIC_Clock();                                                                                                      // Clock I2C bit
        if( (u8_HardwareAddress & 0x40) == 0x40) SETBIT(IIC_PORT, IIC_SDA);          // Set I2C SDA PIN
        else CLRBIT(IIC_PORT, IIC_SDA);                                                                                        // Clear I2C SDA PIN
        IIC_Clock();                                                                                                      // Clock I2C bit
        if( (u8_HardwareAddress & 0x20) == 0x20) SETBIT(IIC_PORT, IIC_SDA);          // Set I2C SDA PIN
        else CLRBIT(IIC_PORT, IIC_SDA);                                                                              // Clear I2C SDA PIN
        IIC_Clock();                                                                                                      // Clock I2C bit
        if( (u8_HardwareAddress & 0x10) == 0x10) SETBIT(IIC_PORT, IIC_SDA);          // Set I2C SDA PIN
        else CLRBIT(IIC_PORT, IIC_SDA);                                                                                  // Clear I2C SDA PIN
        IIC_Clock();                                                                                                      // Clock I2C bit
        // *** Send the I2C Control byte chip selects bits *** //
        if( (u8_HardwareAddress & 0x08) == 0x08) SETBIT(IIC_PORT, IIC_SDA);          // Set I2C SDA PIN
        else CLRBIT(IIC_PORT, IIC_SDA);                                                                                        // Clear I2C SDA PIN
        IIC_Clock();                                                                                                      // Clock I2C bit
        if( (u8_HardwareAddress & 0x04) == 0x04) SETBIT(IIC_PORT, IIC_SDA);          // Set I2C SDA PIN
        else CLRBIT(IIC_PORT, IIC_SDA);                                                                                        // Clear I2C SDA PIN
        IIC_Clock();                                                                                                      // Clock I2C bit
        if( (u8_HardwareAddress & 0x02) == 0x02) SETBIT(IIC_PORT, IIC_SDA);          // Set I2C SDA PIN
        else CLRBIT(IIC_PORT, IIC_SDA);                                                                                       // Clear I2C SDA PIN
        IIC_Clock();                                                                                                      // Clock I2C bit
        // *** Set or Clear the read / write bit for I2C control *** //
        if(u8_ReadOrWrite) SETBIT(IIC_PORT, IIC_SDA);                                                       // Set I2C SDA PIN
        else CLRBIT(IIC_PORT, IIC_SDA);                                                                                      // Clear I2C SDA PIN
        IIC_Clock();                                                                                                      // Clock I2C bit
        IIC_Ackn();                                                                                                                              // Check for acknowledge from I2C device       
}

void IIC_WriteByte( uint8 u8_Data )
{
        uint8 i;
        SETBIT(IIC_DDR, IIC_SDA);                                                                        // Set SDA to output
        CLRBIT(IIC_PORT, IIC_SCL);
        for(i = 0; i < 8; i++)                                                                                // Loop for our 8 bits
        {
                // Set or Clear SDA pin
                if((u8_Data & 0x80) == 0x80) SETBIT(IIC_PORT, IIC_SDA);        // Set I2C SDA PIN
                else CLRBIT(IIC_PORT, IIC_SDA);                                                        // Clear I2C SDA PIN
                SETBIT(IIC_PORT, IIC_SCL);                                                 // Set SCL High, Clock data
                u8_Data = u8_Data << 1;                                                                        // Shift data in buffer right one
                CLRBIT(IIC_PORT, IIC_SCL);                                                 // Clear SCL
        }
        IIC_Ackn();                                                                                                // Check for acknowledge from I2C device       
}

uint8 IIC_ReadByte(void)
{
        uint8 i,buff = 0;
        for (i = 0; i < 8; i++)
        {
                buff = buff << 1;
                CLRBIT(IIC_DDR, IIC_SDA);                                                           // Set SDA to input
                SETBIT(IIC_PORT, IIC_SCL);                                                                    // Set SCL High,Clock bit out
                if (CHKBIT(IIC_PIN, IIC_SDA)) buff = buff | 0x01;                // Read data on SDA pin
                CLRBIT(IIC_PORT, IIC_SCL);                                                                    // Clear SCL
        }
        return buff;                                                                                                // Return our I2C byte
}

void IIC_WriteOneByteAddressDevice(uint8 u8_HardwareAddress, uint8 u8_MemoryAddress, uint8 u8_Data)
{
        uint16 c;                                                                                              // Temp Ram used for write delay
       
        IIC_Start();                                                                                                 // Set I2C start condition
        IIC_WriteControl(u8_HardwareAddress, 0);                        // Send the EEPROM control Byte
        IIC_WriteByte(u8_MemoryAddress);                                                      // Send the EEPROM internal Address
        IIC_WriteByte(u8_Data);                                                                              // Send the EEPROM Data
        IIC_Stop();                                                                                                        // Set I2C Stop condition       
        for(c = 0; c < 1000; c++);                                                      // Delay for EEPROM Write       
}

uint8 IIC_ReadOneByteAddressDevice(uint8 u8_HardwareAddress, uint8 u8_MemoryAddress)
{
        uint8 Temp;                                                                                                           // Temp RAM for EEPROM Read
       
        IIC_Start();                                                                                                   // Set I2C start condition
        IIC_WriteControl(u8_HardwareAddress, 0);                            // Send the EEPROM control Byte
        IIC_WriteByte(u8_MemoryAddress);                                                        // Send the EEPROM internal Address
        IIC_Start();                                                                                                   // Set I2C start condition
        IIC_WriteControl(u8_HardwareAddress, 1);                            // Send the EEPROM control Byte
        Temp = IIC_ReadByte();                                                                        // Read data from EEPROM
        IIC_Stop();                                                                                                          // Set I2C Stop condition
        return Temp;                                                                                                // Return data from EEPROM
}

void IIC_WriteTwoOneByteAddressDevice(uint8 u8_HardwareAddress, uint16 u16_MemoryAddress, uint8 u8_Data)
{
        uint16 c;       
                                                                                                                      // Temp Ram used for write delay
        uint8 u8_HighAddress;
        uint8 u8_LowAddress;
        u8_HighAddress = u16_MemoryAddress / 256;
        u8_LowAddress = u16_MemoryAddress % 256;
        IIC_Start();                                                                                                 // Set I2C start condition
        IIC_WriteControl(u8_HardwareAddress, 0);                            // Send the EEPROM control Byte
        IIC_WriteByte(u8_HighAddress);
        IIC_WriteByte(u8_LowAddress);                                                              // Send the EEPROM internal Address
        IIC_WriteByte(u8_Data);                                                                              // Send the EEPROM Data
        IIC_Stop();                                                                                                        // Set I2C Stop condition       
        for(c = 0; c < 1000; c++);                                                      // Delay for EEPROM Write
       
}

uint8 IIC_ReadTwoOneByteAddressDevice(uint8 u8_HardwareAddress, uint16 u16_MemoryAddress)
{
        uint8 Temp;                                                                                                           // Temp RAM for EEPROM Read
        uint8 u8_HighAddress;
        uint8 u8_LowAddress;
       
        u8_HighAddress = u16_MemoryAddress / 256;
        u8_LowAddress = u16_MemoryAddress % 256;
        IIC_Start();                                                                                                   // Set I2C start condition
        IIC_WriteControl(u8_HardwareAddress, 0);                                        // Send the EEPROM control Byte
        IIC_WriteByte(u8_HighAddress);
        IIC_WriteByte(u8_LowAddress);                                                                // Send the EEPROM internal Address
        IIC_Start();                                                                                                   // Set I2C start condition
        IIC_WriteControl(u8_HighAddress, 1);                                                // Send the EEPROM control Byte
        Temp = IIC_ReadByte();                                                                        // Read data from EEPROM
        IIC_Stop();                                                                                                          // Set I2C Stop condition
        return Temp;                                                                                                // Return data from EEPROM
}

#endif

使用特权

评论回复
10
qin552011373| | 2013-7-12 17:50 | 只看该作者
仅供参考   这个是调试通过的   我这里没问题的

使用特权

评论回复
11
始于16|  楼主 | 2013-7-27 17:11 | 只看该作者
谢谢了~~~

使用特权

评论回复
12
qin552011373| | 2013-7-27 23:01 | 只看该作者
始于16 发表于 2013-7-27 17:11
谢谢了~~~

不用客气  调试出来就好

使用特权

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

本版积分规则

9

主题

58

帖子

0

粉丝