STM32软件IIC与AT24C02通信
程序运行开始先读取三个时间值
static u8 g_second = 0, g_minute = 0, g_hour = 0;
static void InitData(void)
{
g_hour = IICGet()->ReadByte(100);
g_minute = IICGet()->ReadByte(101);
g_second = IICGet()->ReadByte(102);
printf("%d ", g_hour);
printf("%d ", g_minute);
printf("%d ", g_second);
printf("
");
}
定时器每秒钟向AT24C02写三个时间值
void Timer1_Callback(void *p_tmr, void *p_arg)
{
CPU_SR_ALLOC();
OS_CRITICAL_ENTER();
g_second++;
if(g_second >= 60)
{
g_second = 0;
g_minute++;
}
if(g_minute >= 60)
{
g_second = 0;
g_hour++;
}
if(g_hour >= 24)
{
g_hour = 0;
}
IICGet()->WriteByte(100, g_hour);
IICGet()->WriteByte(101, g_minute);
IICGet()->WriteByte(102, g_second);
OLEDFun()->ShowNumber(48, 0, 2, g_hour);
OLEDFun()->ShowNumber(72, 0, 2, g_minute);
OLEDFun()->ShowNumber(96, 0, 2, g_second);
OS_CRITICAL_EXIT();
}
每次STM32复位后,发现g_hour、g_second读写都是对的,g_minute读写不成功,每次都为0,多次测试发现连续读写都是第一个成功,第二个不成功,第三个成功,第四个不成功,间隔似的。
检查了IIC驱动代码
IIC.c
#include "sys.h"
#include "IIC.h"
static IICFun m_Instance;
static IICFun *pthis = NULL;
//static void SDA_Out(Level b_level)
//{
// if(b_level == High)
// GPIO_SetBits(IIC_SDA_GPIO_TYPE, IIC_SDA_GPIO_PIN);
// else
// GPIO_ResetBits(IIC_SDA_GPIO_TYPE, IIC_SDA_GPIO_PIN);
//}
//static void SCK_Out(Level b_level)
//{
// if(b_level == High)
// GPIO_SetBits(IIC_SCK_GPIO_TYPE, IIC_SCK_GPIO_PIN);
// else
// GPIO_ResetBits(IIC_SCK_GPIO_TYPE, IIC_SCK_GPIO_PIN);
//}
static void IIC_Start(void)
{
SDA_OUT();
IIC_SDA = 1;
IIC_SCL = 1;
delay_us(4);
IIC_SDA = 0;
delay_us(4);
IIC_SCL = 0;
}
static void IIC_Stop(void)
{
SDA_OUT();
IIC_SCL = 0;
IIC_SDA = 0;
delay_us(4);
IIC_SCL = 1;
delay_us(4);
IIC_SDA = 1;
delay_us(4);
}
static void ACK(void)
{
IIC_SCL = 0;
SDA_OUT();
IIC_SDA = 0;
delay_us(4);
IIC_SCL = 1;
delay_us(4);
IIC_SCL = 0;
}
static void No_ACK(void)
{
IIC_SCL = 0;
SDA_OUT();
IIC_SDA = 1;
delay_us(4);
IIC_SCL = 1;
delay_us(4);
IIC_SCL = 0;
}
static u8 Wait_ACK(void)
{
u8 ucErrTime=0;
SDA_IN();
IIC_SDA = 1;
delay_us(4);
IIC_SCL = 1;
delay_us(4);
while(READ_SDA)
{
ucErrTime++;
if(ucErrTime >250)
{
IIC_Stop();
return 1;
}
}
IIC_SCL=0;
return 0;
}
static void WriteByte(u8 data)
{
u8 i;
SDA_OUT();
IIC_SCL = 0;
for(i=0; i<8; i++)
{
if(data & 0x80)
IIC_SDA = 1;
else
IIC_SDA = 0;
data <<= 1;
delay_us(4);
IIC_SCL = 1;
delay_us(4);
IIC_SCL = 0;
delay_us(4);
}
}
static u8 ReadByte(u8 IsAck)
{
u8 i, receive = 0;
SDA_IN();
for(i=0; i<8; i++)
{
IIC_SCL = 0;
delay_us(4);
IIC_SCL = 1;
delay_us(4);
receive <<= 1;
if(READ_SDA)
receive++;
delay_us(4);
}
if(IsAck)
ACK();
else
No_ACK();
return receive;
}
static void WriteOneByte(u8 ReadAddr, u8 DataToWrite)
{
IIC_Start();
WriteByte(AT24X02_1 | IIC_WRITE_CMD);
Wait_ACK();
WriteByte(ReadAddr); //address
Wait_ACK();
WriteByte(DataToWrite); //·¢Ëí×Ö½ú
Wait_ACK();
IIC_Stop();//2úéúò»¸öí£Ö1ìõ¼t
delay_ms(20);
}
static u8 ReadOneByte(u8 ReadAddr)
{
u8 i, receive = 0, ack;
IIC_Start();
WriteByte(AT24X02_1 | IIC_WRITE_CMD);
Wait_ACK();
WriteByte(ReadAddr);
Wait_ACK();
IIC_Start();
WriteByte(AT24X01 | IIC_READ_CMD);
Wait_ACK();
receive = ReadByte(FALSE);
IIC_Stop();//2úéúò»¸öí£Ö1ìõ¼t
delay_ms(20);
return receive;
}
static void Read_Data(u8 addr, u8 size, u8 *buff)
{
u8 i;
if(NULL != buff)
{
for(i=0; i<size; i++)
{
IIC_Start();
WriteByte(AT24X02_1 | IIC_WRITE_CMD); //·¢ËíÆ÷¼tμØÖ·0XA0,D′êy¾Y
Wait_ACK();
WriteByte(addr++); //·¢ËíμíμØÖ·
Wait_ACK();
IIC_Start();
WriteByte(AT24X01 | IIC_READ_CMD); //½øèë½óêÕÄ£ê½
Wait_ACK();
if(i<size - 1)
*(buff+i)=ReadByte(TRUE);
else
*(buff+i)=ReadByte(FALSE);
IIC_Stop();//2úéúò»¸öí£Ö1ìõ¼t
delay_ms(20);
}
}
}
static void Write_Data(u8 addr, u8 size, u8 *buff)
{
u8 i;
if(NULL != buff)
{
for(i=0; i<size; i++)
{
IIC_Start();
WriteByte(AT24X02_1 | IIC_WRITE_CMD);
Wait_ACK();
WriteByte(addr++); //address
Wait_ACK();
WriteByte(*buff++); //·¢Ëí×Ö½ú
Wait_ACK();
IIC_Stop();//2úéúò»¸öí£Ö1ìõ¼t
delay_ms(20);
}
}
}
static void IIC_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
//RCC->APB2ENR|=1<<4;//Ïèê1ÄüíaéèIO PORTCê±Öó
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE );
GPIO_InitStructure.GPIO_Pin = IIC_SDA_GPIO_PIN ;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD ; //íÆíìêä3ö
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(IIC_SDA_GPIO_TYPE, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = IIC_SCK_GPIO_PIN ;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD ; //íÆíìêä3ö
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(IIC_SCK_GPIO_TYPE, &GPIO_InitStructure);
IIC_SDA = 1;
IIC_SCL = 1;
}
static u8 Check_AT2402(void)
{
u8 temp;
static u8 data = 0x55;
IIC_Start();
WriteByte(AT24X02_1 | IIC_WRITE_CMD);
Wait_ACK();
WriteByte(0xff); //address
Wait_ACK();
WriteByte(data); //·¢Ëí×Ö½ú
Wait_ACK();
IIC_Stop();//2úéúò»¸öí£Ö1ìõ¼t
delay_ms(10);
IIC_Start();
WriteByte(AT24X02 | IIC_WRITE_CMD); //·¢ËíÆ÷¼tμØÖ·0XA0,D′êy¾Y
Wait_ACK();
WriteByte(0xff); //·¢ËíμíμØÖ·
Wait_ACK();
IIC_Start();
WriteByte(AT24X02 | IIC_READ_CMD); //½øèë½óêÕÄ£ê½
Wait_ACK();
temp=ReadByte(FALSE);
IIC_Stop();//2úéúò»¸öí£Ö1ìõ¼t
if(temp == data)
printf("AT24C02 Init Succeed
");
else
printf("No Fine AT24C02
");
return temp;
}
static void New(void)
{
pthis = &m_Instance;
pthis->Init = IIC_Init;
pthis->ReadByte = ReadOneByte;
pthis->WriteByte = WriteOneByte;
pthis->Check = Check_AT2402;
pthis->ReadData = Read_Data;
pthis->WriteData = Write_Data;
}
IICFun *IICGet(void)
{
if(pthis == NULL)
{
New();
}
return pthis;
}
IIC.h
#ifndef _IIC_H_
#define _IIC_H_
#define SDA_IN() {GPIOB->CRL&=0X0FFFFFFF;GPIOB->CRL|=(u32)8<<28;}
#define SDA_OUT() {GPIOB->CRL&=0X0FFFFFFF;GPIOB->CRL|=(u32)1<<28;}
#define IIC_SDA_GPIO_PIN GPIO_Pin_7
#define IIC_SDA_GPIO_TYPE GPIOB
#define IIC_SCK_GPIO_PIN GPIO_Pin_6
#define IIC_SCK_GPIO_TYPE GPIOB
#define IIC_WRITE_CMD 0x00
#define IIC_READ_CMD 0x01
#define AT24X02_1 0xA0
#define AT24X02_2 0xA2
//IO2ù×÷oˉêy
#define IIC_SCL PBout(6) //SCL
#define IIC_SDA PBout(7) //SDA
#define READ_SDA PBin(7) //êäèëSDA
typedef struct
{
void (*Init)(void);
u8 (*ReadByte)(u8 ReadAddr);
void (*WriteByte)(u8 ReadAddr, u8 DataToWrite);
u8 (*Check)(void);
void (*ReadData)(u8 addr, u8 size, u8 *buff);
void (*WriteData)(u8 addr, u8 size, u8 *buff);
}IICFun;
IICFun *IICGet(void);
#endif
根据网友遇到的情况修改开漏输出或者推挽输出效果无变化
单次读数据和连续读数据也是数据间隔式丢失
读完数据延时增加到100ms也不解决第二个数据读写丢失的问题
从串口输出可以看到复位后g_hour和g_second确实保存了,但是g_minute丢失
不知道是读写时序问题还是其他问题
困扰我很多天了
望各位指教
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
一周热门 更多>