完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
扫一扫,分享给好友
/*
* I2C.c * * Created on: 2017-9-4 * Author: 代忠 * function: implment i2c function */ #include "includes.h" /******************************************************************** *以下为24C0X 系列的EEROM操作函数 *******************************************************************/ #define __IIC24C0x_h__ #include "includes.h" #include "unistd.h" #include "system.h" #include "altera_avalon_pio_regs.h" #define false 0 #define true 1 /****************************************************************************** * 功能:读取SDA数据线上的数据 * 入口参数:无 * 返回值:返回数据线上的电平情况 */ alt_u8 SDA_READ(void) { return IORD_ALTERA_AVALON_PIO_DATA(SDA_BASE);//读取I2C总线数据线上的数据信息 } /******************************************************************** *功能:I2C总线初始化函数,在main函数中应该先调用该函数对i2C总线进行相关的初始化工作 *入口参数:无 *返回值:无 ********************************************************************/ void I2C_init(void) { SCL_DATA(0); delay(1); I2C_stop(); } /******************************************************************** *功能:I2C总线产生起始信号函数 *入口参数:无 *返回值:无 ********************************************************************/ void I2C_start(void) { SDA_DRE(1);//设置数据信号线的工作方式为输出模式 SDA_DATA(1); delay(1); SCL_DATA(1); delay(1); SDA_DATA(0); delay(1); SCL_DATA(0);//保持时钟信号线 delay(1); } /******************************************************************** *功能:I2C总线产生停止信号 *入口参数:无 *返回值:无 ********************************************************************/ void I2C_stop(void) { SDA_DRE(1);//设置数据信号线的工作方式为输出模式 SDA_DATA(0); delay(1); SCL_DATA(1); delay(1); SDA_DATA(1); delay(1); SCL_DATA(0); delay(1);//保持时钟信号线 } /******************************************************************** *功能:I2C总线上写入1个字节的数据 *入口参数:待写入的数据 *返回值:无 ********************************************************************/ alt_u8 I2C_sendByte(alt_u8 I2C_data) { alt_u8 i; alt_u8 ack; SDA_DRE(1);//设置数据信号线的工作方式为输出模式 for (i=0;i<8;i++) { if(I2C_data & 0x80) SDA_DATA(1); else SDA_DATA(0); I2C_data = I2C_data << 1; delay(1); SCL_DATA(1); delay(1); SCL_DATA(0); } delay(1); SDA_DATA(1); delay(1); SDA_DRE(0);//设置数据信号线的工作方式为输入模式 SCL_DATA(1); delay(1); if (SDA_READ())//等待从器件应答 ack = 0; else ack = 1; SCL_DATA(0); return ack; //返回从器件所发送应答信号进行取反返回 } /******************************************************************** *I2C总线上读取一个字节的内容 ********************************************************************/ alt_u8 I2C_receiveByte(void) { alt_u8 I2C_data = 0x00; alt_u8 i; SDA_DRE(1);//设置数据信号线的工作方式为输出模式 SDA_DATA(1); SDA_DRE(0);//设置数据信号线的工作方式为输入模式 delay(1); for (i=0;i<8;i++) { delay(1); I2C_data *= 2; //接受到的数据进行相关的左移 SCL_DATA(1); delay(1); if (SDA_READ()) I2C_data++; SCL_DATA(0); } return (I2C_data); } /******************************************************************** *I2C总线上向从器件写入器件地址和从寄存器地址 ********************************************************************/ void I2C_issue_add(alt_u8 chipAdd,alt_u16 subAdd) { alt_u8 low_add; alt_u8 wd = 0; low_add = subAdd; //24C04有两页的一个地址空间,此处为计算地址空间位于那一页,详情参观24C04的datasheet subAdd >>= 7; wd = subAdd & 0x02; //计算位于那一页 wd |= chipAdd; I2C_start(); I2C_sendByte(wd); I2C_sendByte(low_add); } /******************************************************************** *I2C总线等待从器件内部完成写操作 ********************************************************************/ void I2C_waitforwrite(alt_u8 chip) { alt_u8 ack; do { I2C_start(); ack = I2C_sendByte(chip); }while (!ack); } /******************************************************************** *将指针地址buf中的数据想入到器件chipAdd中的 s_add处 *写入数据的地址是连续写的,连续所写的内容最多为4个 ********************************************************************/ void I2C_write_block(alt_u8 chipAdd,alt_u16 S_add,alt_u8 n_buf,alt_u8 *buf) { alt_u8 i; I2C_issue_add(chipAdd,S_add); for (i=0;i I2C_sendByte(*(buf+i)); } I2C_stop(); //I2C_waitforwrite(chipAdd); } /******************************************************************** * 从EEROM中寄存器地址为S_add出读取n_buf个数据信息,存放于buf指针里面 ********************************************************************/ void I2C_read_block(alt_u8 chipAdd,alt_u16 S_add,alt_u8 n_buf,alt_u8 *buf) { alt_u8 i; alt_u8 rd=0; I2C_issue_add(chipAdd,S_add); S_add >>= 7; rd = S_add & 0x02; //地址页计算 rd |= chipAdd; rd |= 0x01; //进行读写位置位 I2C_start(); //重新产生启动信号,详情请参观I2C协议读取EEROM协议手册 I2C_sendByte(rd); for (i=0;i *(buf+i) = I2C_receiveByte(); delay(1); SDA_DRE(1); SDA_DATA(0); //应答是否需要连续读取数据 delay(1); SCL_DATA(1); delay(1); SCL_DATA(0); delay(1); SDA_DATA(1); } *(buf+i) = I2C_receiveByte(); I2C_stop(); } 希望大神帮我看看问题出在那边了,我在板子上不能读取到相关数据,上面是底层代码,没有吧测试代码发出来,求大神们帮忙看下 |
|
相关推荐
1个回答
|
|
不好意思由于自己的硬件上存在一个小纰漏昨天没有注意到,今天能够读写正常,以上函数经验证完全正常,如有需要的同志,可以直接使用以上函数
|
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
1559 浏览 1 评论
1335 浏览 0 评论
矩阵4x4个按键,如何把识别结果按编号01-16(十进制)显示在两个七段数码管上?
1544 浏览 0 评论
927 浏览 0 评论
2341 浏览 0 评论
1464 浏览 35 评论
5676 浏览 113 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-26 04:03 , Processed in 0.533939 second(s), Total 72, Slave 55 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号