![]() |
|
||||||||||||||
| . 网站首页 . 新闻 . 新品 . 方案 . 专访 . 活动 . DSP . EDA . 评测室 . 技术文库 . 会员区 . 商城 . 服务导航 . 邮购 . 资源 . | ||
|
||
|
|||||
| DM642 I2C通用读写源代码 | |||||
作者:Free 文章来源:本站原创 点击数: 更新时间:2007-11-19 ![]() |
|||||
|
参考了各家的I2C源代码,均发现有不足之处,经过一周时间的学习,搞了个通用的I2C读写代码,抛砖引玉一下。
#include <csl_i2c.h> #include <stdio.h> I2C_Handle g_I2C_Handle; // I2C 全局句柄 Bool I2C_Initialize(void) { g_I2C_Handle = I2C_open(I2C_PORT0,I2C_OPEN_RESET); if(g_I2C_Handle == INV) { return FALSE; } else { I2C_outOfReset(g_I2C_Handle); // 允许I2C总线 I2C_RSETH(g_I2C_Handle, I2CPSC, 0x0E); // I2C模块时钟设置为10M 150M/15 //I2C_RSETH(g_I2C_Handle, I2CCLKL, 0x2D); // 设置I2C外部时钟为100K //I2C_RSETH(g_I2C_Handle, I2CCLKH, 0x2D); // 设置I2C外部时钟为100K //I2C_RSETH(g_I2C_Handle, I2CCLKL, 0x500); // 设置I2C外部时钟为100K //I2C_RSETH(g_I2C_Handle, I2CCLKH, 0x500); // 设置I2C外部时钟为100K I2C_RSETH(g_I2C_Handle, I2CCLKL, 0x300); // 设置I2C外部时钟为100K I2C_RSETH(g_I2C_Handle, I2CCLKH, 0x300); // 设置I2C外部时钟为100K return TRUE; } } Uint8 I2C_Write(Uint8 dev_addr, Uint8 *sub_addr, Uint8 sub_addr_len, Uint8 *write_buffer, Uint8 write_len) { Uint8 bResult = 0; Uint32 I2CState; I2C_Config prevI2CCfg; if(write_len == 0) { return 0; } while (I2C_bb(g_I2C_Handle)); I2C_getConfig(g_I2C_Handle, &prevI2CCfg); // clear all interrupt state I2C_FSETH(g_I2C_Handle, I2CSTR, AL, 1); I2C_FSETH(g_I2C_Handle, I2CSTR, NACK, 1); I2C_FSETH(g_I2C_Handle, I2CSTR, ARDY, 1); I2C_FSETH(g_I2C_Handle, I2CSTR, ICRRDY, 1); I2C_FSETH(g_I2C_Handle, I2CSTR, ICXRDY, 1); I2C_RSETH(g_I2C_Handle, I2COAR, 0); I2C_RSETH(g_I2C_Handle, I2CIER, 0); I2C_RSETH(g_I2C_Handle, I2CCNT, 0); I2C_RSETH(g_I2C_Handle, I2CSAR, dev_addr); I2C_RSETH(g_I2C_Handle, I2CMDR, 0x26A0); // wait send start condition while(I2C_FGETH(g_I2C_Handle, I2CMDR, STT)); while(1) { I2CState = I2C_RGETH(g_I2C_Handle, I2CSTR); if(I2CState & 0x01) { // Arbitration lost // clear AL state in I2C Status Register I2C_FSETH(g_I2C_Handle, I2CSTR, AL, 1); break; } if(I2CState & 0x04) { // ARDY == 1 if(I2CState & 0x02) { // NACK == 1 // clear NACK state in I2C Status Register I2C_FSETH(g_I2C_Handle, I2CSTR, NACK, 1); break; } else { if(I2CState & 0x10) { // ICXRDY == 1 if(bResult < sub_addr_len) { I2C_RSETH(g_I2C_Handle, I2CDXR, sub_addr[bResult]); bResult ++; } else if(bResult < sub_addr_len + write_len) { I2C_RSETH(g_I2C_Handle, I2CDXR, write_buffer[bResult - sub_addr_len]); bResult ++; } else { break; } } } } } I2C_sendStop(g_I2C_Handle); //I2C_FSETSH(g_I2C_Handle,I2CMDR,STP,STOP); while (I2C_bb(g_I2C_Handle)); I2C_config(g_I2C_Handle, &prevI2CCfg); return (bResult < sub_addr_len) ? 0 : (bResult - sub_addr_len); } Uint8 I2C_Read(Uint8 dev_addr, Uint8 *sub_addr, Uint8 sub_addr_len, Uint8 *read_buffer, Uint8 read_len) { Uint8 bResult = 0; Uint32 I2CState; I2C_Config prevI2CCfg; if(read_len == 0) { return 0; } while (I2C_bb(g_I2C_Handle)); I2C_getConfig(g_I2C_Handle, &prevI2CCfg); // clear all interrupt state I2C_FSETH(g_I2C_Handle, I2CSTR, AL, 1); I2C_FSETH(g_I2C_Handle, I2CSTR, NACK, 1); I2C_FSETH(g_I2C_Handle, I2CSTR, ARDY, 1); I2C_FSETH(g_I2C_Handle, I2CSTR, ICRRDY, 1); I2C_FSETH(g_I2C_Handle, I2CSTR, ICXRDY, 1); // 写子地址 if(sub_addr_len) { I2C_RSETH(g_I2C_Handle, I2COAR, 0); I2C_RSETH(g_I2C_Handle, I2CIER, 0); I2C_RSETH(g_I2C_Handle, I2CCNT, 0); I2C_RSETH(g_I2C_Handle, I2CSAR, dev_addr); I2C_RSETH(g_I2C_Handle, I2CMDR, 0x26A0); // wait send start condition while(I2C_FGETH(g_I2C_Handle, I2CMDR, STT)); while(1) { I2CState = I2C_RGETH(g_I2C_Handle, I2CSTR); if(I2CState & 0x01) { // Arbitration lost I2C_FSETH(g_I2C_Handle, I2CSTR, AL, 1); I2C_sendStop(g_I2C_Handle); //I2C_FSETSH(g_I2C_Handle,I2CMDR,STP,STOP); while (I2C_bb(g_I2C_Handle)); I2C_config(g_I2C_Handle, &prevI2CCfg); return 0; } if(I2CState & 0x04) { // ARDY == 1 if(I2CState & 0x02) { // NACK == 1 I2C_FSETH(g_I2C_Handle, I2CSTR, NACK, 1); I2C_sendStop(g_I2C_Handle); //I2C_FSETSH(g_I2C_Handle,I2CMDR,STP,STOP); while (I2C_bb(g_I2C_Handle)); I2C_config(g_I2C_Handle, &prevI2CCfg); return 0; } else { if(I2CState & 0x10) { // ICXRDY == 1 if(bResult < sub_addr_len) { I2C_RSETH(g_I2C_Handle, I2CDXR, sub_addr[bResult]); bResult ++; } else { break; } } } } } } // 是否需要等待由发送转换为接收 重复起始条件 bResult = 0; I2C_RSETH(g_I2C_Handle, I2COAR, 0); I2C_RSETH(g_I2C_Handle, I2CIER, 0); I2C_RSETH(g_I2C_Handle, I2CCNT, 0); I2C_RSETH(g_I2C_Handle, I2CSAR, dev_addr); I2C_RSETH(g_I2C_Handle, I2CMDR, 0x24A0); // wait send start condition while(I2C_FGETH(g_I2C_Handle, I2CMDR, STT)); while(1) { I2CState = I2C_RGETH(g_I2C_Handle, I2CSTR); if(I2CState & 0x01) { // Arbitration lost I2C_FSETH(g_I2C_Handle, I2CSTR, AL, 1); break; } if(I2CState & 0x04) { // ARDY == 1 if(I2CState & 0x02) { // NACK == 1 I2C_FSETH(g_I2C_Handle, I2CSTR, NACK, 1); break; } else if(I2CState & 0x2000) { // NACKSNT == 1 I2C_FSETH(g_I2C_Handle, I2CSTR, NACKSNT, 1); break; } else { if(I2CState & 0x08) { // ICRRDY == 1 if(bResult < read_len) { read_buffer[bResult] = I2C_RGETH(g_I2C_Handle, I2CDRR); bResult ++; if(bResult >= read_len) { // 如果收完所有字节 则发送NACK I2C_FSETSH(g_I2C_Handle,I2CMDR,NACKMOD,NACK); } } else { I2C_FSETSH(g_I2C_Handle,I2CMDR,NACKMOD,NACK); I2C_RGETH(g_I2C_Handle, I2CDRR); } } } } } I2C_sendStop(g_I2C_Handle); //I2C_FSETSH(g_I2C_Handle,I2CMDR,STP,STOP); while (I2C_bb(g_I2C_Handle)); I2C_config(g_I2C_Handle, &prevI2CCfg); return bResult; } |
|||||
| 欢迎点击进入:TI德州中文网 (国内唯一针对TI应用的中文技术网站) 文章录入:admin 责任编辑:admin | |||||
| 【发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口】 | |||||
| 最新热点 | 最新推荐 | 相关文章 | ||
| DM642上TCP/IP协议的实现及性… 基于DM642嵌入式无线视频监控… 基于AVS-M和DM642视频服务器… DM642 Ver2.0多路实时图像处… DM642与百兆以太网接口设计 DM642与1394a的接口设计 DM642和线阵CCD的接口 DM642与以太网的接口 DM642与CMOS图像传感器的接口 在DM642平台上实现高速USB主… |
| 网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!) |
| | 设为首页 | 加入收藏 | 联系站长 | 友情链接 | 版权申明 | 网站公告 | 管理登录 | | |||
|
|