完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
扫一扫,分享给好友
|
|
相关推荐
1个回答
|
|
摘要
之前写过51内核系列的IO口模拟IIC通讯,最近用arm内核的mcu模拟IIC通讯,发现与51内核有些区别(arm内核不支持位寻址) IIC的信号:开始信号(SCL保持高,拉低SDA)、应答信号(第九个时钟,SDA为低)、非应答信号(第九个时钟,SDA为低)、结束信号(SCL保持高,拉高SDA) (非)应答信号: 有应答信号才可以进行下一步,非应答信号会结束通讯 IIC写数据设置三个信号:起始信号、从地址+写(如:addr为0x18(00011000),左移1位后为0x30(00110000),最后一位是0表示写)、寄存器 IIC读数据设置五个信号:起始信号、从地址+写、寄存器、起始信号、从地址+读(如:addr为0x18(00011000),左移1位后为0x30(00110000)与上1后为0x31,最后一位是1表示读(上个图帮助理解) 看下代码吧 一、IO宏定义 51内核定义方式: #define IIC_SCL P04//SCL输出模式 #define IIC_SDA P03 //SDA输出模式 #define READ_SDA P03//读取应答信号SDA 输入模式 arm内核定义方式: //IIC IO定义 #define IIC_SCL(x) GPIO_output(0, 2, x)//SCL输出模式 #define IIC_SDA(x) GPIO_output(0, 3, x) //SDA输出模式 #define READ_SDA() gpio_input(0,2)//读取应答信号SDA 输入模式 #define READ_SCL() gpio_input(0,3)//读取应答信号SDA 输入模式 //SDA线输入输出设置 #define SET_SDA_IN() GPIO_config(0,2,0) #define SET_SDA_OUT() GPIO_config(0,2,1) //SCL线输入输出设置 #define SET_SCL_IN() GPIO_config(0,3,0) #define SET_SCL_OUT() GPIO_config(0,3,1) 二、写数据 /************************************************************** 函数名: IIC_SendNByte 功能: 发送Nbyte数据 输入参数: ADDR从机地址,REG寄存器地址 待发送数据dat,n数据大小 返回值: 成功写了多少个 函数类型: void -------------------------------------------------------------*/ unsigned char IIC_WriteNByte(unsigned char addr,unsigned char reg_addr,unsigned char *dat,unsigned char n) { unsigned char i; IIC_Start();//一个起始信号 addr <<= 1; //左移1位,最低位为0 表示写 IIC_Write1Byte(addr);//一个从机地址信号 IIC_Write1Byte(reg_addr);//一个寄存器地址信号 //下面可以连续写啦 for(i = 0;i IIC_Write1Byte(dat); if(IIC_Ack()) { IIC_Stop(); return i; } } IIC_Stop(); return i; } 硬件IIC内部有地址自增功能,所以一直读就可以了 三、读数据 /************************************************************** 函数名: IIC_ReadNByte 功能: 接收Nbyte数据 输入参数: 是否需要发送应答信号 1:需要 0:不需要 返回值: 接收到的数据 函数类型: u8 -------------------------------------------------------------*/ void IIC_ReadNByte(unsigned char addr,unsigned char reg_addr,unsigned char *dat,unsigned char n) { unsigned char i; IIC_Start();//一个起始信号 addr <<= 1; //左移1位,最低位为0 表示写 IIC_Write1Byte(addr);//一个从机地址信号 IIC_Write1Byte(reg_addr);//一个寄存器地址信号 IIC_Start();//restart信号 IIC_Write1Byte(addr|1);//从机地址+读 //下面就可以读啦 for(i = 0;i dat=IIC_Read1Byte(); if(i<(n-1)) IIC_SendAck(); } IIC_NoSendAck();//发送非应答 IIC_Stop(); } 四,读和写的区别 1、写数据要接收应答或非应答信号、读数据发送应答或非应答信号 2、写数据:start、addr+w、reg; 读数据:start、addr+w、reg、start、addr+r 多了start、addr+r |
|
|
|
只有小组成员才能发言,加入小组>>
2554 浏览 0 评论
1153浏览 2评论
752浏览 1评论
505浏览 0评论
269浏览 0评论
435浏览 0评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-24 06:12 , Processed in 1.329463 second(s), Total 78, Slave 60 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号