求助:参考风驰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);
} |