小弟碰到AT24C02不能从指定直接地址开始读取,设定跨页写入一堆数组,从指定地址开始读数组,只能读取一个字节数据,不能达到连续读的效果,现将代码拷贝如下:
/****************************I2C.C*************************************/
#include "i2c.h"
#include "stm32f1xx_hal.h"
#include "delay.h"
#define I2C GPIOB
#define I2C_SCL_PIN GPIO_PIN_6
#define I2C_SDA_PIN GPIO_PIN_7
void GPIO_I2C_Init()
{
GPIO_InitTypeDef I2C_Init;
__HAL_RCC_GPIOB_CLK_ENABLE(); //打开GPIO_B时钟
I2C_Init.Mode=GPIO_MODE_OUTPUT_OD;
I2C_Init.Pin=I2C_SCL_PIN|I2C_SDA_PIN;
I2C_Init.Pull=GPIO_NOPULL;
I2C_Init.Speed=GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(I2C,&I2C_Init);
}
void GPIO_I2C_SCL(u8 val)
{
if(val)
HAL_GPIO_WritePin(I2C,I2C_SCL_PIN,GPIO_PIN_SET);
else
HAL_GPIO_WritePin(I2C,I2C_SCL_PIN,GPIO_PIN_RESET);
}
void GPIO_I2C_SDA(u8 val)
{
if(val)
HAL_GPIO_WritePin(I2C,I2C_SDA_PIN,GPIO_PIN_SET);
else
HAL_GPIO_WritePin(I2C,I2C_SDA_PIN,GPIO_PIN_RESET);
}
u8 GPIO_I2C_SDA_STA()
{
if(HAL_GPIO_ReadPin(I2C,I2C_SDA_PIN)==GPIO_PIN_SET)
return 1;
else
return 0;
}
void I2C_START()
{
GPIO_I2C_SCL(1);
GPIO_I2C_SDA(1);
delay_us(4);
GPIO_I2C_SDA(0);
delay_us(4);
GPIO_I2C_SCL(0);
}
void I2C_STOP()
{
GPIO_I2C_SCL(0);
GPIO_I2C_SDA(0);
delay_us(4);
GPIO_I2C_SCL(1);
GPIO_I2C_SDA(1);
delay_us(4);
}
//产生应答
void I2C_ACK(void)
{
GPIO_I2C_SCL(0);
GPIO_I2C_SDA(0);
delay_us(2);
GPIO_I2C_SCL(1);
delay_us(2);
GPIO_I2C_SCL(0);
}
//不产生应答
void I2C_NOACK()
{
GPIO_I2C_SCL(0);
GPIO_I2C_SDA(1);
delay_us(2);
GPIO_I2C_SCL(1);
delay_us(2);
GPIO_I2C_SCL(0);
}
u8 I2C_WAIT_ACK()
{
u8 err=0;
// GPIO_I2C_SDA(1);
GPIO_I2C_SCL(0);
delay_us(2);
GPIO_I2C_SCL(1);
while(GPIO_I2C_SDA_STA())
{
err++;
if(err>255)
{
I2C_STOP();
return 1;
}
}
GPIO_I2C_SCL(0);
return 0;
}
void I2C_WRITE_BYTE(u8 data)
{
u8 i;
for(i=0;i<8;i++)
{
GPIO_I2C_SCL(0);
delay_us(2);
if(data&0x80)
GPIO_I2C_SDA(1);
else
GPIO_I2C_SDA(0);
GPIO_I2C_SCL(1);
data<<=1;
delay_us(2);
}
}
u8 I2C_READ_BYTE(u8 ack)
{
u8 i,temp=0x00;
for(i=0;i<8;i++)
{
GPIO_I2C_SCL(0);
delay_us(2);
GPIO_I2C_SCL(1);
temp<<=1;
if(GPIO_I2C_SDA_STA())
temp++;
delay_us(2);
}
if(ack)
I2C_ACK();
else
I2C_NOACK();
return temp;
}
/*************************I2C.H***********************************/
#ifndef __I2C_H
#define __I2C_H
#include "stm32f1xx_hal.h"
#define u8 uint8_t
#define u16 uint16_t
void GPIO_I2C_Init(void);
void GPIO_I2C_SCL(u8 val);
void GPIO_I2C_SDA(u8 val);
u8 GPIO_I2C_SDA_STA(void);
void I2C_START(void);
void I2C_STOP(void);
void I2C_ACK(void);
void I2C_NOACK(void);
u8 I2C_WAIT_ACK(void);
u8 I2C_READ_BYTE(u8 ack);
void I2C_WRITE_BYTE(u8 data);
#endif
/**************************24C02.C***************************/
#include "at24c02.h"
#include "stm32f1xx_hal.h"
#include "delay.h"
#include "i2c.h"
#define MAX_ADDR 255
#define MAX_PAGE 8
void AT24C02_WRITEONEBYTE(u8 writeadrr,u8 data)
{
I2C_START();
I2C_WRITE_BYTE(0xA0);
I2C_WAIT_ACK();
I2C_WRITE_BYTE(writeadrr);
I2C_WAIT_ACK();
I2C_WRITE_BYTE(data);
I2C_WAIT_ACK();
I2C_STOP();
delay_ms(10);
}
u8 AT24C02_READONEBYTE(u8 readadrr)
{
u8 temp=0x00;
I2C_START();
I2C_WRITE_BYTE(0xA0);
I2C_WAIT_ACK();
I2C_WRITE_BYTE(readadrr);
I2C_WAIT_ACK();
I2C_START();
I2C_WRITE_BYTE(0xA1);
I2C_WAIT_ACK();
temp=I2C_READ_BYTE(0);
I2C_STOP();
return temp;
}
u8 AT24C02_WRITEPAGEBYTE(u8 writeaddr,u8 *pointbuff,u8 size)
{
u8 i;
if((MAX_ADDR-writeaddr)<size-1)
return 0;
while(size>(MAX_PAGE-writeaddr%8))
{
u8 temp;
temp=MAX_PAGE-writeaddr%8; //temp表示当前页剩下可写的字节数
I2C_START();
I2C_WRITE_BYTE(0xA0);
I2C_WAIT_ACK();
I2C_WRITE_BYTE(writeaddr);
I2C_WAIT_ACK();
for(i=temp;i>0;i--)
{
I2C_WRITE_BYTE(*(pointbuff++));
I2C_WAIT_ACK();
}
I2C_STOP();
delay_ms(10);
writeaddr=writeaddr+temp;
size=size-temp;
}
I2C_START();
I2C_WRITE_BYTE(0xA0);
I2C_WAIT_ACK();
I2C_WRITE_BYTE(writeaddr);
I2C_WAIT_ACK();
for(i=size;i>0;i--)
{
I2C_WRITE_BYTE(*(pointbuff++));
I2C_WAIT_ACK();
}
I2C_STOP();
delay_ms(10);
return 1;
}
u8 AT24C02_READSEQBYTE(u8 readaddr,u8 *pbuff,u8 size)
{
if(size>(256-readaddr))
return 0;
I2C_START();
I2C_WRITE_BYTE(0xA0);
I2C_WAIT_ACK();
I2C_WRITE_BYTE(readaddr);
I2C_WAIT_ACK();
I2C_START();
I2C_WRITE_BYTE(0xA1);
I2C_WAIT_ACK();
while(size--)
{
*(pbuff++)=I2C_READ_BYTE(size);
}
I2C_STOP();
return 1;
}
/************************24C02.H********************************************/
#ifndef __24C02_H
#define __24C02_H
#include "stm32f1xx_hal.h"
#define u8 uint8_t
#define u16 uint16_t
void AT24C02_WRITEONEBYTE(u8 adrr,u8 data);
u8 AT24C02_READONEBYTE(u8 adrr);
u8 AT24C02_WRITEPAGEBYTE(u8 writeaddr,u8 *pointbuff,u8 size);
u8 AT24C02_READSEQBYTE(u8 readaddr,u8 *pbuff,u8 size);
#endif
/******************************MIAN.C************************************/
#include "stm32f1xx_hal.h"
#include "delay.h"
#include "i2c.h"
#include "at24c02.h"
u8 a[]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,8};
u8 b[5];
u8 read_byte;
int main()
{
// rtc_time rtc;
SystemClock_Config();
GPIO_I2C_Init();
/* GPIO_DS1302_Init();
DS1302_WP_DISABLE();
DS1302_WRITE_CMD(0x80,0x10);
DS1302_WRITE_CMD(0x82,0x22);
DS1302_WRITE_CMD(0x84,0x12);
DS1302_WP_ENABLE();
DS1302_WP_DISABLE();
rtc.dat=22;
rtc.day=5;
rtc.hour=15;
rtc.min=49;
rtc.mon=9;
rtc.sec=0;
rtc.year=17;
DS1302_WRITE_TIME(&rtc);
DS1302_WP_ENABLE();
while(1)
{
a=DS1302_READ_CMD(0x81+0);
b=DS1302_READ_CMD(0x81+2);
c=DS1302_READ_CMD(0x81+4);
d=DS1302_READ_CMD(0x81+6);
e=DS1302_READ_CMD(0x81+8);
f=DS1302_READ_CMD(0x81+10);
g=DS1302_READ_CMD(0x81+12);
delay_ms(1000);
}
I2C_START();
I2C_WRITE_BYTE(0xA0);
I2C_WAIT_ACK();
I2C_WRITE_BYTE(0x01);
I2C_WAIT_ACK();
I2C_WRITE_BYTE(0x15);
I2C_WAIT_ACK();
I2C_STOP();
delay_ms(10);
I2C_START();
I2C_WRITE_BYTE(0xA0);
I2C_WAIT_ACK();
I2C_WRITE_BYTE(0x01);
I2C_WAIT_ACK();
I2C_START();
I2C_WRITE_BYTE(0xA1);
I2C_WAIT_ACK();
read_byte=I2C_READ_BYTE(0);
I2C_STOP();
while(1);
AT24C02_WRITEONEBYTE(0x01,0x85);
read_byte=AT24C02_READONEBYTE(0x01); */
AT24C02_WRITEPAGEBYTE(0x13,a,sizeof(a));
AT24C02_READSEQBYTE(0x17,b,5);
while(1);
}
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
后来还是用单字节轮询去连续读字节了,就是效率低了点。
u8 AT24C02_READSEQBYTE(u8 readaddr,u8 *pbuff,u8 size)
{
if(size>(256-readaddr))
return 0;
/* I2C_START();
I2C_WRITE_BYTE(0xA0);
I2C_WAIT_ACK();
I2C_WRITE_BYTE(readaddr);
I2C_WAIT_ACK();
I2C_START();
I2C_WRITE_BYTE(0xA1);
I2C_WAIT_ACK(); */
while(size)
{
*pbuff++=AT24C02_READONEBYTE(readaddr++);
size--;
}
return 1;
}
一周热门 更多>