打印
[STM8]

STM8L模拟I2C能读不能写

[复制链接]
2315|10
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
_Hanking|  楼主 | 2014-1-15 16:28 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
求助:参考风驰STM8的模拟I2C程序,结果能正确读出存储器中数据但是写不进去
     写保护位WP位低电平,存储器为16K的


#ifndef _I2C_H
#define _I2C_H
#include "stm8l15x.h"

#define I2C_PIN  GPIOC
#define I2C_SCL  GPIO_Pin_1
#define I2C_SDA  GPIO_Pin_0
#define Set_I2C_SCL_HIGHT    GPIO_SetBits(I2C_PIN, I2C_SCL)
#define Set_I2C_SCL_LOW      GPIO_ResetBits(I2C_PIN, I2C_SCL)
#define Set_I2C_SDA_HIGHT    GPIO_SetBits(I2C_PIN, I2C_SDA)
#define Set_I2C_SDA_LOW      GPIO_ResetBits(I2C_PIN, I2C_SDA)
#define Get_I2C_SDA          GPIO_ReadInputDataBit(I2C_PIN, I2C_SDA)
#define Set_I2C_SCL_Out      GPIO_Init(I2C_PIN, I2C_SCL, GPIO_Mode_Out_OD_HiZ_Slow)
#define Set_I2C_SDA_Out      GPIO_Init(I2C_PIN, I2C_SDA, GPIO_Mode_Out_OD_HiZ_Slow)
#define Set_I2C_SDA_In       GPIO_Init(I2C_PIN, I2C_SDA, GPIO_Mode_In_PU_No_IT )

void Soft_I2C_Int(void);
void Soft_I2C_Start(void);
void Soft_I2C_Stop(void);
void Soft_I2C_Ack(void);
void Soft_I2C_NAck(void);
void Soft_I2C_Send_Byte(uint8_t Byte);
uint8_t Soft_I2C_Read_Byte(void);
static void delay_us(uint8_t time);

void writebyte(uint8_t Adress,uint16_t adr,uint8_t data);
uint8_t readbyte(uint8_t Adress,uint16_t adr);
//uint8_t Sendi2cByte(uint8_t Adress,uint16_t adr,uint8_t *Data,uint8_t Num);
//uint8_t Readi2cByte(uint8_t Adress,uint16_t adr,uint8_t *Data,uint8_t Num);
//uint8_t Read7660(uint8_t Adress,uint8_t adr);
//uint8_t write7660(uint8_t Adress,uint8_t adr,uint8_t data);

#endif



#include "i2c.h"

void Soft_I2C_Int(void)
{
        Set_I2C_SCL_Out;
        Set_I2C_SDA_Out;
        Set_I2C_SCL_HIGHT;
        Set_I2C_SDA_HIGHT;
}
/*********************************************************
* 名称: Soft_I2C_Start
* 功能: 模拟I2C的起始条件
* 形参: 无        
* 返回: 无
* 说明: 标准的I2C协议I2C起始条件:SCL为高时,SDA由高变低
               
*********************************************************/
void Soft_I2C_Start(void)
{
        Set_I2C_SDA_Out;
        Set_I2C_SCL_HIGHT;
        Set_I2C_SDA_HIGHT;
        delay_us(5);
        Set_I2C_SDA_LOW;
        //标准的I2C协议I2C起始条件:SCL为高时,SDA由高变低
        delay_us(5);
        Set_I2C_SCL_LOW;//钳住I2C总线,准备发送或接收数据
}
/*********************************************************
* 名称: Soft_I2C_Stop
* 功能: 模拟I2C的停止条件
* 形参: 无        
* 返回: 无
* 说明: 标准的I2C协议I2C停止条件:SCL为高时,SDA由低变高
               
*********************************************************/
void Soft_I2C_Stop(void)
{
        Set_I2C_SDA_Out;
        Set_I2C_SCL_HIGHT;
        Set_I2C_SDA_LOW;
        delay_us(5);
        Set_I2C_SDA_HIGHT;
        //标准的I2C协议I2C停止条件:SCL为高时,SDA由低变高
        delay_us(5);
}

/*********************************************************
* 名称: Soft_I2C_Ack()
* 功能: 模拟I2C的应答
* 形参: 无        
* 返回: 无
* 说明: 根据标准的I2C协议,从I2C从器件读1个byte后
         也就是在第9个CLK的时候,I2C主设备的SDA要变低
         表示I2C主器件已经接收完一个字节byte,I2C从器件
         继续发送数据
               
*********************************************************/
void Soft_I2C_Ack(void)
{
        Set_I2C_SCL_LOW;
        Set_I2C_SDA_Out;
        Set_I2C_SDA_LOW;
        delay_us(5);
        Set_I2C_SCL_HIGHT;
        delay_us(5);
        Set_I2C_SCL_LOW;

}
/*********************************************************
* 名称: Soft_I2C_NAck
* 功能: 模拟I2C的不应答
* 形参: 无        
* 返回: 无
* 说明:
               
*********************************************************/
void Soft_I2C_NAck(void)
{
        Set_I2C_SCL_LOW;
        Set_I2C_SDA_Out;
        Set_I2C_SDA_HIGHT;
        delay_us(5);
        Set_I2C_SCL_HIGHT;
        delay_us(5);
        Set_I2C_SCL_LOW;
}
/*********************************************************
* 名称: Soft_I2C_Send_Byte
* 功能: 模拟I2C主器件向从器件发送一个字节
* 形参: Byte        
* 返回: 无
* 说明:
               
*********************************************************/
void Soft_I2C_Send_Byte(uint8_t Byte)
{
  uint8_t bit;
  Set_I2C_SDA_Out;
  Set_I2C_SCL_LOW;
  for(bit=0;bit<8;bit++)
  {
    if((Byte&0x80)>>7)Set_I2C_SDA_HIGHT;
    else Set_I2C_SDA_LOW;
    Byte<<=1;
    delay_us(5);
    Set_I2C_SCL_HIGHT;
    delay_us(5);
    Set_I2C_SCL_LOW;
    delay_us(5);   
  }
}
/************************************************
* 名称: Soft_I2C_Read_Byte
* 功能: 模拟I2C主器件向从器件发送一个字节
* 形参: 无      
* 返回: 一个字节
* 说明: 主器件从从器件里读一个字节
               
**************************************************/
uint8_t Soft_I2C_Read_Byte(void)
{
        uint8_t bit,Receive_Byte=0;
        Set_I2C_SDA_In;
        for(bit=0;bit<8;bit++)
        {
                Set_I2C_SCL_LOW;
                delay_us(5);
                Set_I2C_SCL_HIGHT;
                Receive_Byte<<=1;//把上一时刻的值左移一位
                if(Get_I2C_SDA)Receive_Byte|=0x01;
                delay_us(2);
        }
        return Receive_Byte;
}

static void delay_us(uint8_t time)
{
        do
        {
                nop();nop();nop();nop();
        }while(time--);
}

void writebyte(uint8_t Adress,uint16_t adr,uint8_t data)
{
        Soft_I2C_Start();
        Soft_I2C_Send_Byte(Adress);
        Soft_I2C_Ack();
        Soft_I2C_Send_Byte((uint8_t)(adr>>8));
        Soft_I2C_Ack();
        Soft_I2C_Send_Byte((uint8_t)adr);
        Soft_I2C_Ack();
        //-- Send Address
        Soft_I2C_Send_Byte(data);
        Soft_I2C_Ack();
        Soft_I2C_Stop();

}

uint8_t readbyte(uint8_t Adress,uint16_t adr)
{
        uint8_t RxData;
        Soft_I2C_Start();
        Soft_I2C_Send_Byte(Adress);
        Soft_I2C_Ack();
        Soft_I2C_Send_Byte((uint8_t)(adr>>8));
        Soft_I2C_Ack();
        Soft_I2C_Send_Byte((uint8_t)adr);
        Soft_I2C_Ack();
        //-- Send Address
        Soft_I2C_Start();
        Soft_I2C_Send_Byte(Adress | 0x01);   //-- Lowest bit = 1 => READ
        Soft_I2C_Ack();

        RxData = Soft_I2C_Read_Byte();
        Soft_I2C_Ack();
        Soft_I2C_Stop();
        return (RxData);
}
沙发
gaochy1126| | 2014-1-15 17:02 | 只看该作者
写还需要一个位置1吧。

使用特权

评论回复
板凳
_Hanking|  楼主 | 2014-1-15 17:04 | 只看该作者
gaochy1126 发表于 2014-1-15 17:02
写还需要一个位置1吧。

那个位置1?

使用特权

评论回复
地板
gaochy1126| | 2014-1-15 17:11 | 只看该作者
不知道你用的什么存储器,像at24之类的,7位地址+一位读写位。

使用特权

评论回复
5
_Hanking|  楼主 | 2014-1-15 19:20 | 只看该作者
gaochy1126 发表于 2014-1-15 17:11
不知道你用的什么存储器,像at24之类的,7位地址+一位读写位。

读时最低位置1,写时最低位为0

使用特权

评论回复
6
_Hanking|  楼主 | 2014-1-16 09:57 | 只看该作者
顶顶,有没有人遇到过IIC程序能读不能写的???

使用特权

评论回复
7
zhangyang86| | 2014-1-16 12:59 | 只看该作者
_Hanking 发表于 2014-1-16 09:57
顶顶,有没有人遇到过IIC程序能读不能写的???

没有遇到,你可以参考 https://bbs.21ic.com/forum.php?mod=viewthread&tid=454866

使用特权

评论回复
8
_Hanking|  楼主 | 2014-1-16 14:52 | 只看该作者
zhangyang86 发表于 2014-1-16 12:59
没有遇到,你可以参考 https://bbs.21ic.com/forum.php?mod=viewthread&tid=454866

多谢张兄问题已解决,是停止信号函数出错。
原来函数:
void Soft_I2C_Stop(void)
{
        Set_I2C_SDA_Out;
        Set_I2C_SCL_HIGHT;
        Set_I2C_SDA_LOW;
        delay_us(5);
        Set_I2C_SDA_HIGHT;//标准的I2C协议I2C停止条件:SCL为高时,SDA由低变高
        delay_us(5);
}
改后函数:
void Soft_I2C_Stop(void)
{
        Set_I2C_SDA_Out;
//        Set_I2C_SCL_HIGHT;
Set_I2C_SCL_LOW;
        Set_I2C_SDA_LOW;
        delay_us(5);
Set_I2C_SCL_HIGHT;
        Set_I2C_SDA_HIGHT;//标准的I2C协议I2C停止条件:SCL为高时,SDA由低变高
        delay_us(5);
}

但是还是有点疑惑,上面那个也是SCL为高时,SDA由低变高,为什么就会出问题?

使用特权

评论回复
9
zhangyang86| | 2014-1-17 10:50 | 只看该作者
_Hanking 发表于 2014-1-16 14:52
多谢张兄问题已解决,是停止信号函数出错。
原来函数:
void Soft_I2C_Stop(void)

:handshake

使用特权

评论回复
10
nienianhong| | 2014-2-26 13:03 | 只看该作者

使用特权

评论回复
11
nienianhong| | 2014-2-26 13:05 | 只看该作者
原来的停止条件还是有点不一样的

使用特权

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

本版积分规则

7

主题

37

帖子

2

粉丝