title: iic框架

tags: ARM

date: 2018-11-05 13:44:58

i2c框架

寄存器

/* 配置引脚用于I2C*/
GPECON &= ~((3<<28) | (3<<30));
GPECON |= ((2<<28) | (2<<30)); /* 设置时钟 */
/* [7] : IIC-bus acknowledge enable bit, 1-enable in rx mode
* [6] : 时钟源, 0: IICCLK = fPCLK /16; 1: IICCLK = fPCLK /512
* [5] : 1-enable interrupt
* [4] : 读出为1时表示中断发生了, 写入0来清除并恢复I2C操作
* [3:0] : Tx clock = IICCLK/(IICCON[3:0]+1).
* Tx Clock = 100khz = 50Mhz/16/(IICCON[3:0]+1)
*/
IICCON = (1<<7) | (0<<6) | (1<<5) | (30<<0);

中断配置: IIC没有次中断源.直接配置INTMSK即可INTMSK &= ~(1<<27);

主机发送

int do_master_tx(p_i2c_msg msg)
{
p_cur_msg = msg; msg->cnt_transferred = -1;
msg->err = 0; /* 设置寄存器启动传输 */
/* 1. 配置为 master tx mode */
IICCON |= (1<<7); /* TX mode, 在ACK周期释放SDA */
IICSTAT = (1<<4); /* 2. 把从设备地址写入IICDS */
IICDS = msg->addr<<1; /* 3. IICSTAT = 0xf0 , 数据即被发送出去, 将导致中断产生 */
IICSTAT = 0xf0; /* 后续的传输由中断驱动 */ /* 循环等待中断处理完毕 */
while (!msg->err && msg->cnt_transferred != msg->len); if (msg->err)
return -1;
else
return 0;
}

主机接收

int do_master_rx(p_i2c_msg msg)
{
p_cur_msg = msg; msg->cnt_transferred = -1;
msg->err = 0; /* 设置寄存器启动传输 */
/* 1. 配置为 Master Rx mode */
IICCON |= (1<<7); /* RX mode, 在ACK周期回应ACK */
IICSTAT = (1<<4); /* 2. 把从设备地址写入IICDS */
IICDS = (msg->addr<<1)|(1<<0); /* 3. IICSTAT = 0xb0 , 从设备地址即被发送出去, 将导致中断产生 */
IICSTAT = 0xb0; /* 后续的传输由中断驱动 */ /* 循环等待中断处理完毕 */
while (!msg->err && msg->cnt_transferred != msg->len); if (msg->err)
return -1;
else
return 0;
}

中断处理

注意

  1. 连续读的最后一个字节不响应ack,以用来终止读.
  2. 在读写第一个字节的时候,判断是否有ack来判断是否设备存在

if (p_cur_msg->flags == 0)	/* write */
{
/* 对于第1个中断, 它是发送出设备地址后产生的
* 需要判断是否有ACK
* 有ACK : 设备存在
* 无ACK : 无设备, 出错, 直接结束传输
*/
if (p_cur_msg->cnt_transferred == 0) /* 第1次中断 */
{
if (iicstat & (1<<0))
{ /* no ack */
/* 停止传输 */
IICSTAT = 0xd0;
IICCON &= ~(1<<4);//挂起标志
p_cur_msg->err = -1;
printf("tx err, no ack\n\r");
delay(1000);
return;
}
} if (p_cur_msg->cnt_transferred < p_cur_msg->len)
{
/* 对于其他中断, 要继续发送下一个数据
*/
IICDS = p_cur_msg->buf[p_cur_msg->cnt_transferred];
IICCON &= ~(1<<4);//挂起标志
}
else
{
/* 停止传输 */
IICSTAT = 0xd0;
IICCON &= ~(1<<4);//挂起标志
delay(1000);
}
}

/* 对于第1个中断, 它是发送出设备地址后产生的
* 需要判断是否有ACK
* 有ACK : 设备存在, 恢复I2C传输, 这样在下一个中断才可以得到第1个数据
* 无ACK : 无设备, 出错, 直接结束传输
*/
if (p_cur_msg->cnt_transferred == 0) /* 第1次中断 */
{
if (iicstat & (1<<0))
{ /* no ack */
/* 停止传输 */
IICSTAT = 0x90;
IICCON &= ~(1<<4);
p_cur_msg->err = -1;
printf("rx err, no ack\n\r");
delay(1000);
return;
}
else /* ack */
{
/* 如果是最后一个数据, 启动传输时要设置为不回应ACK */
/* 恢复I2C传输 */
if (isLastData())
{
resume_iic_without_ack();
}
else
{
resume_iic_with_ack();
}
return;
}
} /* 非第1个中断, 表示得到了一个新数据
* 从IICDS读出、保存
*/
if (p_cur_msg->cnt_transferred < p_cur_msg->len)
{
index = p_cur_msg->cnt_transferred - 1;
p_cur_msg->buf[index] = IICDS; /* 如果是最后一个数据, 启动传输时要设置为不回应ACK */
/* 恢复I2C传输 */
if (isLastData())
{
resume_iic_without_ack();
}
else
{
resume_iic_with_ack();
}
}
else
{
/* 发出停止信号 */
IICSTAT = 0x90;
IICCON &= ~(1<<4);//清标志
delay(1000);
}

程序框架

最新文章

  1. Javascript模块化编程(三):require.js的用法
  2. PDF的信息表达原理及特点分析
  3. solr&amp;lucene3.6.0源码解析(三)
  4. 【C语言入门教程】1.1 基本程序结构
  5. Downloader调用WCF服务返回文件
  6. Erlang 从入门到精通(一) 下载安装
  7. 首先定义一个描述银行账户的Account类,包括成员变 量“账号”和“存款余额”,成员方法有“存款”、“取款”和“余额查询”。其次, 编写一个主类,在主类中测试Account类的功能。(已完善)
  8. javascript --- 将共享属性迁移到原型中去
  9. juery动态添加和删除
  10. Android-调用优酷SDK上传视频
  11. 5. 星际争霸之php设计模式--抽象工厂模式
  12. eclipse下安装插件
  13. MAC自动备份数据到服务器
  14. UML与数据流图
  15. SQL操作(增删改查)
  16. ADT &quot;Running Android Lint&quot; has encountered a problem
  17. 关于offsetTop offsetHeight clientHeight scrollHeight scrollTop的区别研究
  18. 如何避免JSP乱码
  19. 深入了解Android蓝牙Bluetooth——《进阶篇》
  20. React 系列文章(1): npm 手动搭建React 运行实例 (新手必看)

热门文章

  1. 洛谷 P3951 小凯的疑惑
  2. html input 禁止输入中文
  3. Navicat MySQL 自动备份
  4. Matplotlib学习---用seaborn画联合分布图(joint plot)
  5. CSAPC2008 skyline
  6. PHP 公共方法分享180628
  7. $NOIp2018$劝退记
  8. java == 与 equals
  9. OpenLayers学习笔记(七)— 类似比例尺的距离环(一)
  10. python random使用方法