Write_IIC_Byte(0x78);啥意思

iic协议读取数据的问题_百度知道
iic协议读取数据的问题
uint read_add(uchar address)
start_iic();
write_byte(0xa0);
respons();
write_byte(address);
respons();
start_iic();
write_byte(0xa1);
respons();
data=read_byte();
以上是读取数据的程序。用的是...
我有更好的答案
读地址和写地址是不一样的,读操作也是得先把读操作的地址先写进去才能读
可是 write_byte(0xa1)不也是把器件地址写进去。1是表示要读。write_byte(address)是表示要读的内容的地址。请问这样理解哪里错误了??谢谢。
是这样的,不明白你还有什么问题
额 可能是我问得不清楚。我的意思是把程序改成uint read_add(uchar address){
start_iic(); write_byte(0xa1);//写器件地址 并表示要读 respons(); write_byte(address);//寄存器地址 respons(); data=read_byte(); stop(); }
start_iic();是必需的
我知道啊。你对比一下两个程序先。
建议你详细看看IIC的协议,读的过程是:写器件地址--寄存器地址--读地址--读回数据
采纳率:27%
start_iic(); write_byte(0xa0);
respons(); write_byte(address);这上面的是要告诉器件,我要 (操作) 你的那个地址(address)单元。write_byte(0xa1);//这句话是要告诉器件,准备要来读你,读就要有对像,对像在哪呢?就是你上面所写入的地址。data=read_byte();//这句话才是真正的把数据给读出来,明白了吗?
你数据不首先写进去,怎么可以读出来呢?就像你没吃东西怎么会拉东西出来,要想从器件中读到数据,肯定要保障器件本来有数据对吧。所以首先要向里面写数据啊。然后再读出来啊。希望能帮到你。
现在是要读数据。不是写数据。。我的问题是 读数据的时候 为什么要write_byte(0xa0);
直接write_byte(0xa1);//写器件地址 并表示要读
这样不可以么?
哦,我明白你的意思了,是这样的,主器件读数据的时候肯定要知道它要读哪块地址吧,那个24C系列芯片存储数据是按一个一个地址来的,就像电脑内存一样,每个地址对应存一个字节数据,所以你要从从器件读数据到主器件,肯定必须要知道从哪个地址读对吧,就像你告诉我我可以来你家,但是前提是我得知道你家的地址才能去你家对吧。所以当主器件读数据的时候,肯定首先要把读哪个地址写进去,然后再从这个地址当中读出数据。这样明白了吗?至于那个24C系列芯片储存数据规格可以看它的datasheet。希望可以帮到你。
为您推荐:
其他类似问题
您可能关注的内容
iic的相关知识
换一换
回答问题,赢新手礼包
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。查看: 2348|回复: 7
IIC_Send_Byte(0XA0+((WriteAddr/256)<<1))之我的见解
主题帖子精华
初级会员, 积分 155, 距离下一级还需 45 积分
在线时间12 小时
因为是刚学习STM32,所以也看到很多人对这行代码不是很理解,我就来说说我自己的理解吧,也不知道是不是就这么,不对的话大神们多多指正,
首先因为EPPROM有不同型号,24C02 地址 A3 R/W 而其他的型号 A1 A2 A3 则变为 a10 a9 a8 。
其实0XA0相当于一扇门,而这一扇门里面有256位住户,也就是一个字节。WriteAddr/256这句话,就当于超过了一个字节,则需要移位了。
a8 0 就等于另外一扇门, 里面也有256位住户。若再超过,则使用A2的门地址,依次类推。
不知道我的理解正不正确。请大家多多指教!
主题帖子精华
新手上路, 积分 46, 距离下一级还需 4 积分
在线时间7 小时
该类器件要通过iic总线操作,读写过程中都要先寻址,这类器件地址有两个字节组成,如下表,1010是固定的,A表示器件地址,可以拉高和拉低,iic总线上可以并接2的几次方个器件。P表示具体的内部地址数,比如at24c02共有256个字节,第二个地址字节完全可以满足,不用P。但是at24c04一个有512个字节,需要9位地址线,第一个字节中的p就表示地址线了,p=0表示低256字节,1表示高256字节。
注意:一般页写可以连续写8个数据。主机每发送一个字节都要接受从机的应答信号。
该类器件是采用iic总线进行操作的,器件地址根据容量的不同稍有不同,如下
对于芯片的A0,A1,A2脚:
24C01/02,A0,A1,A2都是从设备地址。
24C04,A1,A2是从设备地址,A0没用
24C08,A2是从设备地址,A0,A1没用
24C16及以上,A0,A1,A2都没用了。
其中,A表示期间地址,p表示也地址,在读写的时候首先是起始条件+器件地址
器件地址如上所示在16k中,需要两个字节表示内部地址,正是p2/1/0 和8位具体的地址
主题帖子精华
金钱127940
在线时间1122 小时
其实就是对于大容量的EEPROM型号,本来作为片选地址线的1~3位用来表示数据地址了。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺:
主题帖子精华
初级会员, 积分 155, 距离下一级还需 45 积分
在线时间12 小时
回复【2楼】正点原子:
---------------------------------
原子哥,程序中的IIC_Wait_Ack();等待应答,我都修改为IIC_Ack();&应答信号,程序也能够正常运行,那么为什么要用IIC_Wait_Ack()呢?
主题帖子精华
金牌会员, 积分 1009, 距离下一级还需 1991 积分
在线时间392 小时
回复【3楼】Fong0716:
---------------------------------
只能说编程就死编程了,多联系下生活嘛,你发送东西给人家,是不是希望人家回应一下,东西收到了,人家发送东西给你,你是不是也要礼貌回应一下东西收到了,你发送数据,还发应答,你的假应答仍然代替不了别人的真应答,假的就是假的,有和没有一样。所以你写,就等待应答,读就发送应答,合情合理。
主题帖子精华
在线时间0 小时
何须琢磨出那么多类比,不过就是协议的首字节定义。
于停用该账号:http://www.microstar.club
主题帖子精华
高级会员, 积分 517, 距离下一级还需 483 积分
在线时间47 小时
回复【2楼】正点原子:
---------------------------------
原子哥,程序中的IIC_Wait_Ack();等待应答,我都 ...
使用iic_wait_ack()我感觉方便查错
主题帖子精华
新手入门, 积分 23, 距离下一级还需 -3 积分
在线时间6 小时
该类器件要通过iic总线操作,读写过程中都要先寻址,这类器件地址有两个字节组成,如下表,1010是固定的,A ...
你这说的什么意思?表在哪?
Powered byMSP430 IIC 程序驱动代码_百度文库
您的浏览器Javascript被禁用,需开启后体验完整功能,
赠送免券下载特权
10W篇文档免费专享
部分付费文档8折起
每天抽奖多种福利
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
MSP430 IIC 程序驱动代码
&&比赛必备
阅读已结束,下载本文需要
想免费下载本文?
定制HR最喜欢的简历
下载文档到电脑,同时保存到云知识,更方便管理
&#xe64e;加入VIP
还剩3页未读,
定制HR最喜欢的简历
你可能喜欢cortex_m3_stm32嵌入式学习笔记(二十):IIC实验(I2C串行总线)
IIC(Inter- Integrated Circuit)总线是一种由 PHILIPS 公司开发的两线式串行总线,用于连接微控制器及其外围设备。它是由数据线SDA 和时钟SCL构成的串行总线,可发送和接收数据。在
CPU 与被控 IC 之间、 IC 与 IC 之间进行双向传送, 高速 IIC 总线一般可达 400kbps 以上。
ALIENTEK MiniSTM32 开发板板载的 EEPROM 芯片型号为 24C02。该芯片的总容量是 256个字节,该芯片通过 IIC 总线与外部连接,我们本章就通过 STM32 来实现 24C02 的读写。目前大部分 MCU 都带有 IIC 总线接口, STM32 也不例外。但是这里我们不使用 STM32的硬件 IIC 来读写 24C02,而是通过软件模拟。STM32 的硬件 IIC
非常复杂,更重要的是不稳定,故不推荐使用。所以我们这里就通过模拟来实现了。有兴趣的读者可以研究一下 STM32的硬件 IIC。
科普:EEPROM,或写作E2PROM,全称电子抹除式可复写 (英语:Electrically-Erasable
Programmable Read-Only Memory),是一种可以通过电子方式多次复写的半导体存储设备,可以在电脑上或专用设备上擦除已有信息,重新。相比EPROM,EEPROM不需要用,也不需取下,就可以用特定的电压,来抹除芯片上的信息,以便写入新的数据。
I2C 总线在传送数据过程中共有三种类型信号, 它们分别是:开始信号、结束信号和应答信号。开始信号: SCL 为高电平时, SDA 由高电平向低电平跳变,开始传送数据。结束信号: SCL 为高电平时, SDA 由低电平向高电平跳变,结束传送数据。应答信号:接收数据的 IC 在接收到 8bit 数据后,向发送数据的 IC 发出特定的低电平脉冲,表示已收到数据。 CPU 向受控单元发出一个信号后,等待受控单元发出一个应答信号, CPU 接收到应答信号后,根据实际情况作出是否继续传递信号的判断。若未收到应答信号,由判断为受控单元出现故障。
这些信号中,起始信号是必需的,结束信号和应答信号,都可以不要。
24C02 的 SCL 和 SDA 分别连在 STM32 的 PC12 和 PC11 上的,连接关系如图24.2.1 所示:
在工程中添加两个源文件分别是 myiic.c 和 24cxx.c,myiic.c 文件存放 iic 驱动代码, 24cxx.c 文件存放 24C02 驱动代码myiic.c
#include "24cxx.h"
//初始化IIC接口
void AT24CXX_Init(void)
IIC_Init();
//在AT24CXX指定地址读出一个数据
//ReadAddr:开始读数的地址
:读到的数据
u8 AT24CXX_ReadOneByte(u16 ReadAddr)
u8 temp=0;
IIC_Start();
if(EE_TYPE&AT24C16)
IIC_Send_Byte(0XA0);
//发送写命令
IIC_Wait_Ack();
IIC_Send_Byte(ReadAddr&&8);//发送高地址
IIC_Wait_Ack();
}else IIC_Send_Byte(0XA0+((ReadAddr/256)&&1));
//发送器件地址0XA0,写数据
IIC_Wait_Ack();
IIC_Send_Byte(ReadAddr%256);
//发送低地址
IIC_Wait_Ack();
IIC_Start();
IIC_Send_Byte(0XA1);
//进入接收模式
IIC_Wait_Ack();
temp=IIC_Read_Byte(0);
IIC_Stop();//产生一个停止条件
//在AT24CXX指定地址写入一个数据
//WriteAddr
:写入数据的目的地址
//DataToWrite:要写入的数据
void AT24CXX_WriteOneByte(u16 WriteAddr,u8 DataToWrite)
IIC_Start();
if(EE_TYPE&AT24C16)
IIC_Send_Byte(0XA0);
//发送写命令
IIC_Wait_Ack();
IIC_Send_Byte(WriteAddr&&8);//发送高地址
IIC_Send_Byte(0XA0+((WriteAddr/256)&&1));
//发送器件地址0XA0,写数据
IIC_Wait_Ack();
IIC_Send_Byte(WriteAddr%256);
//发送低地址
IIC_Wait_Ack();
IIC_Send_Byte(DataToWrite);
//发送字节
IIC_Wait_Ack();
IIC_Stop();//产生一个停止条件
delay_ms(10);
//在AT24CXX里面的指定地址开始写入长度为Len的数据
//该函数用于写入16bit或者32bit的数据.
//WriteAddr
:开始写入的地址
//DataToWrite:数据数组首地址
:要写入数据的长度2,4
void AT24CXX_WriteLenByte(u16 WriteAddr,u32 DataToWrite,u8 Len)
for(t=0;t&Lt++)
AT24CXX_WriteOneByte(WriteAddr+t,(DataToWrite&&(8*t))&0xff);
//在AT24CXX里面的指定地址开始读出长度为Len的数据
//该函数用于读出16bit或者32bit的数据.
//ReadAddr
:开始读出的地址
:要读出数据的长度2,4
u32 AT24CXX_ReadLenByte(u16 ReadAddr,u8 Len)
u32 temp=0;
for(t=0;t&Lt++)
temp+=AT24CXX_ReadOneByte(ReadAddr+Len-t-1);
//检查AT24CXX是否正常
//这里用了24XX的最后一个地址(255)来存储标志字.
//如果用其他24C系列,这个地址要修改
//返回1:检测失败
//返回0:检测成功
u8 AT24CXX_Check(void)
temp=AT24CXX_ReadOneByte(255);//避免每次开机都写AT24CXX
if(temp==0X55)return 0;
else//排除第一次初始化的情况
AT24CXX_WriteOneByte(255,0X55);
temp=AT24CXX_ReadOneByte(255);
if(temp==0X55)return 0;
//在AT24CXX里面的指定地址开始读出指定个数的数据
//ReadAddr :开始读出的地址 对24c02为0~255
:数据数组首地址
//NumToRead:要读出数据的个数
void AT24CXX_Read(u16 ReadAddr,u8 *pBuffer,u16 NumToRead)
while(NumToRead)
*pBuffer++=AT24CXX_ReadOneByte(ReadAddr++);
NumToRead--;
//在AT24CXX里面的指定地址开始写入指定个数的数据
//WriteAddr :开始写入的地址 对24c02为0~255
:数据数组首地址
//NumToWrite:要写入数据的个数
void AT24CXX_Write(u16 WriteAddr,u8 *pBuffer,u16 NumToWrite)
while(NumToWrite--)
AT24CXX_WriteOneByte(WriteAddr,*pBuffer);
WriteAddr++;
pBuffer++;
#ifndef __MYIIC_H
#define __MYIIC_H
#include "sys.h"
#include "delay.h"
//IO方向设置
#define SDA_IN()
{GPIOC-&CRH&=0XFFFF0FFF;GPIOC-&CRH|=8&&12;}
#define SDA_OUT() {GPIOC-&CRH&=0XFFFF0FFF;GPIOC-&CRH|=3&&12;}
//IO操作函数
#define IIC_SCL
PCout(12)//SCL
#define IIC_SDA
PCout(11)//SDA
#define READ_SDA
PCin(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);
#include "24cxx.h"
//初始化IIC接口
void AT24CXX_Init(void)
IIC_Init();
//在AT24CXX指定地址读出一个数据
//ReadAddr:开始读数的地址
:读到的数据
u8 AT24CXX_ReadOneByte(u16 ReadAddr)
u8 temp=0;
IIC_Start();
if(EE_TYPE&AT24C16)
IIC_Send_Byte(0XA0);
//发送写命令
IIC_Wait_Ack();
IIC_Send_Byte(ReadAddr&&8);//发送高地址
IIC_Wait_Ack();
}else IIC_Send_Byte(0XA0+((ReadAddr/256)&&1));
//发送器件地址0XA0,写数据
IIC_Wait_Ack();
IIC_Send_Byte(ReadAddr%256);
//发送低地址
IIC_Wait_Ack();
IIC_Start();
IIC_Send_Byte(0XA1);
//进入接收模式
IIC_Wait_Ack();
temp=IIC_Read_Byte(0);
IIC_Stop();//产生一个停止条件
//在AT24CXX指定地址写入一个数据
//WriteAddr
:写入数据的目的地址
//DataToWrite:要写入的数据
void AT24CXX_WriteOneByte(u16 WriteAddr,u8 DataToWrite)
IIC_Start();
if(EE_TYPE&AT24C16)
IIC_Send_Byte(0XA0);
//发送写命令
IIC_Wait_Ack();
IIC_Send_Byte(WriteAddr&&8);//发送高地址
IIC_Send_Byte(0XA0+((WriteAddr/256)&&1));
//发送器件地址0XA0,写数据
IIC_Wait_Ack();
IIC_Send_Byte(WriteAddr%256);
//发送低地址
IIC_Wait_Ack();
IIC_Send_Byte(DataToWrite);
//发送字节
IIC_Wait_Ack();
IIC_Stop();//产生一个停止条件
delay_ms(10);
//在AT24CXX里面的指定地址开始写入长度为Len的数据
//该函数用于写入16bit或者32bit的数据.
//WriteAddr
:开始写入的地址
//DataToWrite:数据数组首地址
:要写入数据的长度2,4
void AT24CXX_WriteLenByte(u16 WriteAddr,u32 DataToWrite,u8 Len)
for(t=0;t&Lt++)
AT24CXX_WriteOneByte(WriteAddr+t,(DataToWrite&&(8*t))&0xff);
//在AT24CXX里面的指定地址开始读出长度为Len的数据
//该函数用于读出16bit或者32bit的数据.
//ReadAddr
:开始读出的地址
:要读出数据的长度2,4
u32 AT24CXX_ReadLenByte(u16 ReadAddr,u8 Len)
u32 temp=0;
for(t=0;t&Lt++)
temp+=AT24CXX_ReadOneByte(ReadAddr+Len-t-1);
//检查AT24CXX是否正常
//这里用了24XX的最后一个地址(255)来存储标志字.
//如果用其他24C系列,这个地址要修改
//返回1:检测失败
//返回0:检测成功
u8 AT24CXX_Check(void)
temp=AT24CXX_ReadOneByte(255);//避免每次开机都写AT24CXX
if(temp==0X55)return 0;
else//排除第一次初始化的情况
AT24CXX_WriteOneByte(255,0X55);
temp=AT24CXX_ReadOneByte(255);
if(temp==0X55)return 0;
//在AT24CXX里面的指定地址开始读出指定个数的数据
//ReadAddr :开始读出的地址 对24c02为0~255
:数据数组首地址
//NumToRead:要读出数据的个数
void AT24CXX_Read(u16 ReadAddr,u8 *pBuffer,u16 NumToRead)
while(NumToRead)
*pBuffer++=AT24CXX_ReadOneByte(ReadAddr++);
NumToRead--;
//在AT24CXX里面的指定地址开始写入指定个数的数据
//WriteAddr :开始写入的地址 对24c02为0~255
:数据数组首地址
//NumToWrite:要写入数据的个数
void AT24CXX_Write(u16 WriteAddr,u8 *pBuffer,u16 NumToWrite)
while(NumToWrite--)
AT24CXX_WriteOneByte(WriteAddr,*pBuffer);
WriteAddr++;
pBuffer++;
#ifndef __24CXX_H
#define __24CXX_H
#include "myiic.h"
#include "delay.h"
#define AT24C01
#define AT24C02
#define AT24C04
#define AT24C08
#define AT24C16
#define AT24C32
#define AT24C64
#define AT24C128 16383
#define AT24C256 32767
#define EE_TYPE AT24C02
u8 AT24CXX_ReadOneByte(u16 ReadAddr);//指定地址读取一个字节
void AT24CXX_WriteOneByte(u16 WriteAddr,u8 DataToWrite);//指定地址写入一个字节
void AT24CXX_WriteLenByte(u16 WriteAddr,u32 DataToWrite,u8 Len);//指定地址开始写入指定长度的数据
u32 AT24CXX_ReadLenByte(u16 ReadAddr,u8 Len);//指定地址开始读取指定长度数据
void AT24CXX_Write(u16 WriteAddr,u8 *pBuffer,u16 NumToWrite);//从指定地址开始写入指定长度的数据
void AT24CXX_Read(u16 ReadAddr,u8 *pBuffer,u16 NumToRead);//从指定地址开始读出指定长度的数据
u8 AT24CXX_Check(void);//检查器件
void AT24CXX_Init(void);//初始化IIC
#endif代码有点长。。但其实配好了用到一般只有读和写两个函数如下:
//在AT24CXX里面的指定地址开始读出指定个数的数据
//ReadAddr :开始读出的地址 对24c02为0~255
:数据数组首地址
//NumToRead:要读出数据的个数
void AT24CXX_Read(u16 ReadAddr,u8 *pBuffer,u16 NumToRead)
while(NumToRead)
*pBuffer++=AT24CXX_ReadOneByte(ReadAddr++);
NumToRead--;
//在AT24CXX里面的指定地址开始写入指定个数的数据
//WriteAddr :开始写入的地址 对24c02为0~255
:数据数组首地址
//NumToWrite:要写入数据的个数
void AT24CXX_Write(u16 WriteAddr,u8 *pBuffer,u16 NumToWrite)
while(NumToWrite--)
AT24CXX_WriteOneByte(WriteAddr,*pBuffer);
WriteAddr++;
pBuffer++;
}参数解释的很明白也很好理解。。
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "lcd.h"
#include "key.h"
#include "myiic.h"
#include "24cxx.h"
const u8 TEXT_Buffer[]={"MY IIC TEST"};
#define SIZE sizeof(TEXT_Buffer)
void init(void)
NVIC_Configuration();
delay_init();
uart_init(9600);
LED_Init();
KEY_Init();
LCD_Init();
AT24CXX_Init();
POINT_COLOR=RED;//设置字体为红色
LCD_ShowString(60,40,200,24,24,"IIC TEST");
LCD_ShowString(60,70,200,16,16,"~~~~~~~~~");
LCD_ShowString(60,90,200,16,16,"BY---yh");
LCD_ShowString(60,110,200,16,16,"");
LCD_ShowString(60,130,200,16,16,"WK_UP:Write
KEY0:Read");
while(AT24CXX_Check())//检测不到24c02
LCD_ShowString(60,150,200,16,16,"24C02 Check Failed!");
delay_ms(500);
LCD_ShowString(60,150,200,16,16,"Please Check!
delay_ms(500);
LED0=!LED0;//DS0闪烁
LCD_ShowString(60,150,200,16,16,"24C02 Ready!");
POINT_COLOR=BLUE;
int main(void)
u8 datatemp[SIZE];
key=KEY_Scan(0);
if(key==WK_UP_PRES)//写
LCD_Fill(0,170,239,319,WHITE);//清除半屏
LCD_ShowString(60,170,200,16,16,"Start Write 24C02....");
AT24CXX_Write(0,(u8*)TEXT_Buffer,SIZE);
LCD_ShowString(60,170,200,16,16,"24C02 Write Finished!");//提示传送完成
if(key==KEY0_PRES)//KEY0 按下,读取字符串并显示
LCD_ShowString(60,170,200,16,16,"Start Read 24C02.... ");
AT24CXX_Read(0,datatemp,SIZE);
LCD_ShowString(60,170,200,16,16,"The Data Readed Is:
");//提示传送完成
LCD_ShowString(60,190,200,16,16,datatemp);//显示读到的字符串
delay_ms(10);
LED0=!LED0;
看过本文的人也看了:
我要留言技术领域:
取消收藏确定要取消收藏吗?
删除图谱提示你保存在该图谱下的知识内容也会被删除,建议你先将内容移到其他图谱中。你确定要删除知识图谱及其内容吗?
删除节点提示无法删除该知识节点,因该节点下仍保存有相关知识内容!
删除节点提示你确定要删除该知识节点吗?

我要回帖

更多关于 0x7 的文章

 

随机推荐