i2c框架
2024-08-31 09:12:34
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;
}
中断处理
注意
- 连续读的最后一个字节不响应ack,以用来终止读.
- 在读写第一个字节的时候,判断是否有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);
}
程序框架
最新文章
- Javascript模块化编程(三):require.js的用法
- PDF的信息表达原理及特点分析
- solr&;lucene3.6.0源码解析(三)
- 【C语言入门教程】1.1 基本程序结构
- Downloader调用WCF服务返回文件
- Erlang 从入门到精通(一) 下载安装
- 首先定义一个描述银行账户的Account类,包括成员变 量“账号”和“存款余额”,成员方法有“存款”、“取款”和“余额查询”。其次, 编写一个主类,在主类中测试Account类的功能。(已完善)
- javascript --- 将共享属性迁移到原型中去
- juery动态添加和删除
- Android-调用优酷SDK上传视频
- 5. 星际争霸之php设计模式--抽象工厂模式
- eclipse下安装插件
- MAC自动备份数据到服务器
- UML与数据流图
- SQL操作(增删改查)
- ADT ";Running Android Lint"; has encountered a problem
- 关于offsetTop offsetHeight clientHeight scrollHeight scrollTop的区别研究
- 如何避免JSP乱码
- 深入了解Android蓝牙Bluetooth——《进阶篇》
- React 系列文章(1): npm 手动搭建React 运行实例 (新手必看)