求助,Msp430G2的模拟I2C相关问题

2019-07-27 17:41发布

本人使用Msp430G2553来实现软件模拟I2C,不过在参考网上的例程下改写I2C程序后,一直无法得到应答,有使用示波器检测过时序,是没有问题的,所以特向各位大牛求救哈,求大牛们帮帮忙。
我的I2C程序:
头文件:
/*
* I2C.h
*
*  Created on: 2015-3-31
*      Author: vecio
*/

#ifndef I2C_H_
#define I2C_H_

#define I2C_DIR  P2DIR
#define I2C_OUT  P2OUT
#define I2C_IN   P2IN
#define I2C_SCL  BIT1     //SCL P2.1   I2C的时钟模拟口
#define I2C_SDA  BIT2     //SDA P2.2        I2C的数据模拟口

#define SDA_HIGH     I2C_OUT |= I2C_SDA//SDA = 1
#define SDA_LOW      I2C_OUT &= ~I2C_SDA//SDA = 0
#define SCL_HIGH     I2C_OUT |= I2C_SCL//SCL = 1
#define SCL_LOW      I2C_OUT &= ~I2C_SCL//SCL = 0

#define IIC_READ  0x0E      //定义读指令
#define IIC_WRITE 0x0E      //定义写指令

#define SET_SDA_IN   I2C_DIR &= ~I2C_SDA  //SET SDA IN
#define SET_SDA_OUT  I2C_DIR |= I2C_SDA   //SET SDA OUT

#define SDA_IN ( I2C_IN & I2C_SDA)  //READ SDA DATA

typedef unsigned char        uint8;
typedef signed char        int8;
typedef unsigned short        uint16;
typedef signed short        int16;
typedef unsigned long        uint32;
typedef signed long        int32;
typedef unsigned int        uint;

extern void delay_5us() ;
extern void I2C_Write(uint8 uint8_Addr,uint8 R_Data);
extern char I2C_Read(uint8 uint8_Addr);


#endif /* I2C_H_ */


C语言文件:
/*
* I2C.c
*
*  Created on: 2015-3-31
*      Author: vecio
*/
#include <msp430.h>
#include "I2C.h"
//uint8 Ack_Sign;

/*******************************************************************************
* Function:      delay_us
* Description:   延时1个机器周期
* Calls:
* Return:        void
******************************************************************************/
void delay_us(void)
{
        __no_operation();
}

/*******************************************************************************
* Function:      delay_us
* Description:   延时2个机器周期
* Calls:
* Return:        void
******************************************************************************/
void delay_2us(void)
{
        __no_operation();
        __no_operation();


}


/*******************************************************************************
* Function:      delay_us
* Description:   延时5个机器周期
* Calls:
* Return:        void
******************************************************************************/
void delay_5us(void)
{
        __no_operation();
        __no_operation();
        __no_operation();
        __no_operation();
        __no_operation();
}


/*******************************************************************************
* Function:      start
* Description:   起始位
* Calls:
* Return:        void
******************************************************************************/
void I2C_Start()
{
        SET_SDA_OUT;
        SCL_HIGH;                        //拉高时钟线
        delay_2us();
        SDA_LOW;                        //拉低数据线
        delay_2us();
        SCL_LOW;                        //拉低时钟线
        delay_2us();

}


/*******************************************************************************
* Function:      stop
* Description:   停止位
* Calls:
* Return:        void
******************************************************************************/
void I2C_Stop()
{
        SET_SDA_OUT;
        SCL_HIGH;                        //拉高时钟线
        delay_5us();
        SDA_LOW;                        //拉低数据线
        delay_5us();
        SDA_HIGH;                        //时钟线为高电平时,拉高数据线,产生停止信号
        delay_5us();
}

/*******************************************************************************
* Function:      ack
* Description:   应答标志
* Calls:
* Return:        Ack_Sign
******************************************************************************/
uint8 I2C_Ack()
{
        uint8 Ack_Sign;
        SET_SDA_OUT;
        SDA_HIGH;                        //释放数据总线,准备接收应答信号
        delay_5us();
        SCL_HIGH;                        //拉高时钟线
        delay_5us();
        Ack_Sign=SDA_IN;        //读取应答信号的状态
        delay_5us();
        SCL_LOW;                        //拉低时钟线
        delay_5us();
        return Ack_Sign;        //返回应答信号状态,0表示应答,1表示非应答

}

/*******************************************************************************
* Function:      test_ack
* Description:   测试ACK
* Calls:
* Return:        1或者0
******************************************************************************/
uint8 TestAck()
{
        uint8 Error_Bit;
        SET_SDA_OUT;
        SDA_HIGH;
        delay_5us();
        SCL_LOW;
        delay_5us();
        Error_Bit = SDA_IN;
        SCL_LOW;
        delay_5us();
        if(Error_Bit == 0x00)
        {
                return 0;
        }
        else
                return 1;

}

/*******************************************************************************
* Function:      i2c_write_byte(uint8 wr)
* Description:   写入一个8bit数据
* Calls:
* Return:        void
******************************************************************************/
void I2C_Write_byte(uint8 Wr)
{
        uint8 c,Read_1,Read_2;
        SET_SDA_OUT;
        Read_1 = Wr;
        for (c=0;c<8;c++)
        {
                SCL_LOW;
                delay_5us();
                Read_2 = Read_1;
                Read_2 = Read_2&(0x80);  //写最高位的数据
                delay_5us();

                if(Read_2 == (0x80) )
                {
                        SDA_HIGH;
                }
                else
                {
                        SDA_LOW;
                }
                delay_5us();
                SCL_HIGH;                                //拉高时钟线,将数写入到设备中
                delay_5us();
                SCL_LOW;                                //拉低时钟线,允许改变数据线的状态
                delay_5us();
                Read_1 = Read_1 << 1 ;  //数据左移一位,把次高位放在最高位,为写入次高位做准备
        }
}

/*******************************************************************************
* Function:      iic_read_byte()
* Description:   读出一个8bit数据
* Calls:
* Return:        R_Data
******************************************************************************/
uint8 I2C_Read_byte()
{
        uint8 L;
        uint8 R_Data;
        SET_SDA_IN;
        SCL_LOW;
        for(L=0;L<8;L++)
        {
                R_Data = R_Data << 1 ;  //将缓冲字节的数据左移一位,准备读取数据
                SDA_HIGH;
                delay_5us();
                SCL_LOW;
                delay_5us();
                SCL_HIGH;
                delay_5us();
                if(SDA_IN == 1)
                {
                        R_Data = R_Data | (0x01) ;         //如果数据线为高电平,则给缓冲字节的最低位写一
                        delay_5us();
                }
        }
        return (R_Data);                          //返回读取的一个字节数据

}

/*******************************************************************************
* Function:      iic_write(uint8 uint8_add,uint8 rdata)
* Description:   按任意地址写入一字节数据
* Calls:
* Return:        void
******************************************************************************/
void I2C_Write(uint8 uint8_Addr,uint8 R_Data)
{
        uint8 t;
        t = (IIC_WRITE << 1 );
        I2C_Start();                                //产生起始信号
        I2C_Write_byte(t);                        //写入设备地址(写)
        I2C_Ack();                                        //等待设备应答
        I2C_Write_byte(uint8_Addr);        //写入要操作的单元地址
        I2C_Ack();                                        //等待设备应答
        I2C_Write_byte(R_Data);                //写入数据
        I2C_Ack();                                        //等待设备应答
        I2C_Stop();                                        //产生停止信号

}

/*******************************************************************************
* Function:      iic_read(uint8 uint8_add)
* Description:   按地址读出一字节数据
* Calls:
* Return:        x
******************************************************************************/
char I2C_Read(uint8 uint8_Addr)
{
        uint8 t,x;
        t=(IIC_READ << 1 ) ;
        I2C_Start();                                        //产生起始信号
        I2C_Write_byte(t);                                //写入设备地址(写)
        I2C_Ack();                                                //等待设备的应答
        I2C_Write_byte(uint8_Addr) ;        //写入要操作的单元地址
        I2C_Ack();                                                //等待设备应答

        t=((IIC_READ << 1) | 0x01) ;
        I2C_Start();                                        //产生起始信号
        I2C_Write_byte(t);                                //写入设备地址(读)
        I2C_Ack();                                                //等待设备的应答
        x = I2C_Read_byte();                        //写入数据
        I2C_Ack();                                                //等待设备的应答
        I2C_Stop();                                                //产生停止信号
        return x;                                                //返回读取的一个字节数据

}





求大家帮帮忙哈
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。