STM32快速读写AT24C16代码模拟I2C

STM32快速读写AT24C16代码模拟I2C
本帖只适⽤AT24C16及以下的芯⽚,AT24C32及以上的芯⽚读写⽅式不⼀样,故不适⽤
如果你的代码可以正常读写24C01/02,直接拿来读取24C16是可以的,但是只能读取256字节
AT24C16与AT24C01/02/04/08 不同,它引脚的A2,A1,A0是⽆效的,也就是它没有⾃⼰独⽴的地址,总线上只能挂⼀个
AT24C16设备。
AT24C16总共2048字节,分为128页,每页16字节,地址范围是0~2047。
128页只需要7位地址,分为⾼3位和低4位,⾼3位在设备地址中,低4位在字节地址中。
设备地址:1010+页地址⾼3位+读写⽅向(1:读  0:写)
字节地址:页地址⾼4位+4位页内偏移地址
例如读写地址:1864 ,⾸先计算该地址是多少页的多少个字节,1864/16=116(0x74)页,1864%16=8(0x08),即116页的第8个字节
其中页地址0x74=0 1 1 1 0 1 0 0,最⾼位忽略,分为D6、D5、D4(⾼3位)和D3~D0(低4位)两个部分 。
可以计算出 设备地址和字节地址:
设备地址:1010+111+0/1  (AT24C16设备地址⾼4位固定为1010)
字节地址:0100+1000(⾼4位是页地址低4位,低4位是页内偏移地址,即0x08)8gggg
最后,根据标准I2C读写时序来对这个地址进⾏读写即可!
折叠炕桌
模拟I2C.c
#include "myiic.h"
#include "delay.h"
__asm void delay_us(u32 usec)
{
ALIGN
PUSH.W {r1}  //2时钟周期
MOV r1,#18  //1时钟周期
MUL r0,r1  //1时钟周期
SUB r0,#3  //1时钟周期
loop
SUBS r0,#1  //1时钟周期
BNE loop  //如果跳转则为3个周期,不跳则只有1个周期
POP {r1}  //2时钟周期
BX lr    //3个时钟周期
//总共所⽤周期为(usec*4)-4,此处减4主要⽤于抵消调⽤此函数的消耗时钟周期(传参1时钟,BLX跳转3时钟)  //本函数内总共所⽤周期为usec*(freq/4)-2 +9,调⽤此函数的消耗5个时钟周期(传参2时钟,BLX跳转3时钟)
}
#endif
//初始化IIC
void IIC_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(IIC_CLOCK, ENABLE );
GPIO_InitStructure.GPIO_Pin = SCL_PIN|SDA_PIN;    //引脚
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ;  //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(SCL_PORT, &GPIO_InitStructure);
IIC_SCL=1;
IIC_SDA=1;//拉⾼SDA和SCL
}
//产⽣IIC起始信号
void IIC_Start(void)
{
SDA_OUT();    //sda线输出
IIC_SDA=1;
IIC_SCL=1;
delay_us(4);
IIC_SDA=0;//START:when CLK is high,DATA change form high to low
delay_us(4);
IIC_SCL=0;//钳住I2C总线,准备发送或接收数据
}
//产⽣IIC停⽌信号
void IIC_Stop(void)
{
SDA_OUT();//sda线输出
IIC_SCL=0;
IIC_SDA=0;//STOP:when CLK is high DATA change form low to high
delay_us(4);
IIC_SCL=1;
IIC_SDA=1;//发送I2C总线结束信号
delay_us(4);
}
//等待应答信号到来
//返回值:1,接收应答失败
//        0,接收应答成功
u8 IIC_Wait_Ack(void)
{
u8 ucErrTime=0;
SDA_IN();      //SDA设置为输⼊
IIC_SDA=1;delay_us(1);
IIC_SCL=1;delay_us(1);
while(READ_SDA)
{
if(ucErrTime>250)
{
IIC_Stop();
return 1;
}
}
IIC_SCL=0;//时钟输出0
return 0;
}
/
/产⽣ACK应答
泥浆比重试验void IIC_Ack(void)
{
IIC_SCL=0;
SDA_OUT();
矫形鞋IIC_SDA=0;
delay_us(2);
IIC_SCL=1;
delay_us(2);
IIC_SCL=0;
}
/
/不产⽣ACK应答
void IIC_NAck(void)
{
IIC_SCL=0;
SDA_OUT();
IIC_SDA=1;
delay_us(2);
IIC_SCL=1;
delay_us(2);
IIC_SCL=0;
}
/
/IIC发送⼀个字节
//返回从机有⽆应答
//1,有应答
//0,⽆应答
void IIC_Send_Byte(u8 txd)
{
u8 t;
SDA_OUT();
IIC_SCL=0;//拉低时钟开始数据传输
for(t=0;t<8;t++)
{
IIC_SDA=(txd&0x80)>>7;
txd<<=1;
delay_us(2);  //对TEA5767这三个延时都是必须的
IIC_SCL=1;
delay_us(2);
IIC_SCL=0;
公牛辅助
delay_us(2);
}
}
//读1个字节,ack=1时,发送ACK,ack=0,发送nACK  u8 IIC_Read_Byte(unsigned char ack)
{
unsigned char i,receive=0;
SDA_IN();//SDA设置为输⼊
for(i=0;i<8;i++ )
{
IIC_SCL=0;
涤纶单丝delay_us(2);
IIC_SCL=1;
receive<<=1;
if(READ_SDA)receive++;
delay_us(1);
if (!ack)
IIC_NAck();//发送nACK    else
IIC_Ack(); //发送ACK      return receive;
}
i2c.h
#ifndef __MYIIC_H
#define __MYIIC_H
#include "stm32f10x.h"
//位段定义⽅便后⾯直接操作IO⼝  Reg:寄存器地址  Bit:该寄存器的第多少位
#define BITBAND_REG(Reg,Bit) (*((uint32_t volatile*)(0x42000000u + (((uint32_t)&(Reg) - (uint32_t)0x40000000u)<<5) + (((uint32_t)(Bit))<<2)))) #define SoftDelay 0  //是否使⽤软件延时
//IO⼝定义移植需要修改
#define SCL_PORT GPIOC
#define SDA_PORT GPIOC
#define SCL_PIN  GPIO_Pin_12
#define SDA_PIN  GPIO_Pin_11
//I2C 时钟移植需要修改
#define IIC_CLOCK RCC_APB2Periph_GPIOC
//IO⽅向设置移植需要修改
#define SDA_IN()  {SDA_PORT->CRH&=0XFFFF0FFF;SDA_PORT->CRH|=8<<12;} // SDA配置为输⼊
#define SDA_OUT() {SDA_PORT->CRH&=0XFFFF0FFF;SDA_PORT->CRH|=3<<12;} // SDA配置为输出
//IO操作函数移植需要修改
#define IIC_SCL    BITBAND_REG(SCL_PORT->ODR,12) //SCL输出=?
#define IIC_SDA    BITBAND_REG(SDA_PORT->ODR,11)  //SDA输出=?
#define READ_SDA  (SDA_PORT->IDR&(1<<11))  //读SDA脚
//IIC所有操作函数
void IIC_Init(void);        //初始化IIC的IO⼝
void IIC_Start(void);    //发送IIC开始信号
void IIC_Stop(void);      //发送IIC停⽌信号
void IIC_Send_Byte(u8 txd);  //IIC发送⼀个字节
u8 IIC_Read_Byte(unsigned char ack);//IIC读取⼀个字节
u8 IIC_Wait_Ack(void);    //IIC等待ACK信号
void IIC_Ack(void);    //IIC发送ACK信号
void IIC_NAck(void);    //IIC不发送ACK信号
void IIC_Write_One_Byte(u8 daddr,u8 addr,u8 data);
u8 IIC_Read_One_Byte(u8 daddr,u8 addr);
#endif
AT24C16.c
#include "24cxx.h"
#include "delay.h"
#include "stdio.h"

本文发布于:2024-09-22 01:03:40,感谢您对本站的认可!

本文链接:https://www.17tex.com/tex/1/100050.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

下一篇:ASCII码表
标签:地址   字节   发送   信号   需要   时钟   移植
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议