概述
1、电路原理图
SCL - GPIOD6
SDA - GPIOD7
操作两个管脚实现I2C通信协议,两种方式:
1) 软件直接控制;
2) 软硬件结合。
2、I2C控制器的数据手册
2.1 '管脚的配置
--->P 69. Function功能 ---> P 757. GPIODALTFN0功能选择
SCL -GPIOD6- Function1,SDA2 - 0xc001d020 - [13:12]01=6pin配置fun1
SDA -GPIOD7- Function1,SCL2 - 0xc001d020 - [15:14]01=7pin配置fun1
2.2 'I2C控制器的复位控制(时钟)
--->P 302. 时钟使能
I2CCLKENB- 0xc00b0000 - [ 3 ]1=PCLK is always enabled
--->P 294. I2C控制器的复位
IPRESET0- 0xc0012000 - [ 22 ]0=复位操作Reset
// 6818手册有误,非bit21;4418手册核对,操作bit22
2.3 'I2C控制器配置
S5P6818中有 3 个I2C控制器(CPU手册推断:I2C0 / I2C1 / I2C2)。
根据g-sensor使用的管脚为 GPIOD6 GPIOD7。
1) 推断出g-sensor使用的是CPU内部的I2C2的控制器;
2) 通信速率:标准模式达 100 kbit/s;快速模式达 400 kbit/s;
I2C控制器可以配置为主模式和从模式。
支持'中断/轮询'模式。
7位设备地址格式:
1) 在start信号后,发送一个7-bit从机地址;
2) 紧接着第8位是数据方向位,代表R/W(读写操作);
// 0 - 发送:写、1 - 请求数据:读
3) 传输地址时从高位开始:1。
' I2C控制器参数配置:
--->P 923.
'I2CCON' - 0xc00a6000
- [ 3 : 0 ] I2CCLK/(ICCR[3:0]+1) = Tx clock 时钟频率配置
// 1111 设置最慢的速度来调试,没问题,再设置正常值发送数据。
- [ 4 ] 1 = 中断产生了(收/发1个字节后),写1无效(描述)
- [ 5 ] 1 = 使能中断
- [ 6 ] 1 = PCLK/256 分频
- [ 7 ] 0/1 = 禁止/使能ack信号
- [ 8 ] 1 = 清除中断
'I2CSTAT' - 0xc00a6004
- [ 0 ] 0/1 = 收到/未收到ack信号
- [ 1 ] 0/1 = 产生start或stop信号 / 收到从设备地址为0x00
- [ 4 ] 0/1 = 禁止/使能数据收发
- [ 5 ] 0/1 = stop信号/start信号
- [ 7 : 6 ] 10/11 = 主设备接收/主设备发送 (0xf0,低4位置0/高4位置1)
// 6818手册有误,缺少bit[7:6];4418手册核对,有bit[7:6]
'I2CADD' - 0xc006008 // 当I2C控制器作为从设备时,保存自身的从设备地址
'I2CDS' - 0xc00a600c
- [ 7 : 0 ] = arm core有数据想发送,写入该bit
arm core想读取接收到的数据,读该bit
'I2CLC' - 0xc00a0010
- [ 1 : 0 ] 01 = 延时5个PCLK周期
- [ 2 ] 1 = 滤波使能
<tips>
' vi多文件的编辑
vi xxx.c
:sp xxx.h // 横着上侧,当前目录存在文件则打开,不存在则创建
:vp xxx.h // 竖着左侧,当前目录存在文件则打开,不存在则创建
两个窗口的跳转:ctrl + w + ↑/↓
/** 代码演示 .h **/
#ifndef _IIC_H_
#define _IIC_H_
extern void iic2_init (void);
extern void iic2_start (unsigned char, unsigned int);
extern void iic2_stop (void);
extern void iic2_tx (unsigned char*, unsigned char);
extern void iic2_rx (unsigned char*, unsigned char);
#endif //_IIC_H_
/** 代码演示 .c **/
#define GPIOD_ALTFN0 *((volatile unsigned int*)0xc001d020)
#define I2CCLKENB *((volatile unsigned int*)0xc00b0000)
#define IPRESET0 *((volatile unsigned int*)0xc0012000)
#define I2CCON *((volatile unsigned int*)0xc00a6000)
#define I2CSTAT *((volatile unsigned int*)0xc00a6004)
#define I2CADD *((volatile unsigned int*)0xc00a6008)
#define I2CDS *((volatile unsigned int*)0xc00a600c)
#define I2CLC *((volatile unsigned int*)0xc00a6010)
// iic2管脚和相关参数配置 - 初始化
void iic2_init (void) {
// 配置管脚的功能 Funtion1
GPIOD_ALTFN0 &= ~(3 << 12 | 3 << 14); // [13:12][15:14]清0
GPIOD_ALTFN0 |= (1 << 12 | 1 << 14);
// 使能I2C控制器时钟
I2CCLKENB |= (1 << 3);
// 复位I2C控制器,手册中有误(21)--->(22)
IPRESET0 &= ~(1 << 22);
IPRESET0 |= (1 << 22);
// 配置I2C控制器
I2CCON = (1 << 8) | (1 << 7) | (1 << 6) | (1 << 5) | 0x0f;
I2CLC = (1 << 2) | 1;
}
// addr:从设备地址。rdwr:读 1 写 0
// 发送start信号,发送从设备地址 | W/R
void iic2_start (unsigned char slave_addr, unsigned int rdwr) {
unsigned int iiccon = 0;
unsigned int stat = 0;
// 使能数据的收发
stat |= (1 << 4);
I2CSTAT |= (1 << 4);
// 清除中断标志,使能中断,使能ACK
iiccon = I2CCON;
iiccon &= ~ (1 << 4);
iiccon |= (1 << 8) | (1 << 7) | (1 << 5);
I2CCON = iiccon;
// 收发模式的设置
if (rdwr) { // 非0,读操作
stat |= (2 << 6); // master receive 主机接收
slave_addr = (slave_addr << 1) | 1; // 读操作置1
}
else {
stat |= (3 << 6); // master send 主机发送
slave_addr = (slave_addr << 1) | 0; // 写操作置0
}
// 填充要发送的从设备地址和读写位
I2CDS = slave_addr;
I2CCON &= ~(1 << 4); // 如果后续bit4=1代表发送完成
// start 信号,发送从设备地址 | R/W
stat |= (1 << 5);
I2CSTAT = stat;
// 轮询是否发送完成
while (! (I2CCON & (1 << 4))) ;
}
// 发送停止信号
void iic2_stop (void) {
// stop 信号
I2CSTAT &= ~(1 << 5);
}
// buf:存放要发送的数据的起始地址
// len:要发送的数据长度,1个len = 1 byte
void iic2_tx (unsigned char* buf, unsigned char len) {
int count = 0;
for (; count < len; count++) {
// 清除中断标志位
I2CCON &= ~(1 << 4);
// 填充要发送的数据
I2CDS = buf[count];
// 轮询是否发送完成,发送完就继续for循环继续下1个字节
while (! (I2CCON & (1 << 4))) ;
}
}
// buf:存放要接收的数据额起始地址
// len:要接收的数据长度,1个len = 1 byte
// 主设备在收到最后一个字节后,不需要再给从设备回ACK信号
void iic2_rx (unsigned char* buf, unsigned char len) {
int count = 0;
while (count < len) {
// 马上要接收的是否是最后一个字节
// 如果是CPU端无需回送ACK信号,即禁止自动ACK
if (count == (len - 1)) {
I2CCON &= ~(1 << 7); // disable ACK
// 清除中断标志
I2CCON &= ~(1 << 4);
// 轮询是否有中断产生,接收模式下
// 如果有中断产生,意味着收到了1个字节
while (! (I2CCON & (1 << 4))) ;
// 从I2C控制器中读走接收到的字节到DRAM中去
buf[count] = I2CDS;
count++;
}
}
}
3、g-sensor数据手册
加速度、速度、温度、声音、压力,都属于模拟量
计算机能够处理转化为数字量
// 三轴重力传感器芯片手册:mma8653fcr1.pdf
大小 2mm * 2mm * 1mm
精度:8bit / 10bit
加速度单位:m/s^2
g:重力加速度单位,数值常取值 9.8m/s^2
' 工作模式:
OFF:power down
STANDBY:待机模式
ACTIVE:正常工作模式
' 从设备地址:
0x1d [ 6 : 0 ]
R:0x3B
W:0x3A
原码、反码、补码
要想从g-sensor中读取其中一个寄存器的值:
主设备 - 发送start
主设备 - 发送从设备地址 + W写信号 - 0x1d<<1 | 0
主设备 - 等待ack
主设备 - 发送要访问g-sensor中寄存器的地址
主设备 - 等待ack
主设备 - 重复发送start
主设备 - 发送从设备地址 + R读信号 - 0x1d<<1 | 1
主设备 - 等待ack
主设备 - 接收从设备发出的指定寄存器的内容
主设备 - 第9个周期不回ack
主设备 - 第10个周期发送stop
语言组织:
如果给你一个芯片,如何完成它的驱动程序?
1>【确认芯片使用的通信协议】- I2C
2>【底板电路图】- MCU_SCL_2 - AC18 - GPIOD6
- MCU_SDA_2 - AB19 - GPIOD7
3>【核心板电路图】- SCL[GPIOD6-fun1-I2C2]
- SDA[GPIOD7-fun1-I2C2]
4>【配置管脚】
5>【配置I2C控制器的复位时钟】
6>【配置I2C控制器参数】
7>【主/从设备发送/接收流程编码验证】
最后
以上就是温暖白猫为你收集整理的ARM:g-sensor重力传感器电路原理图、I2C控制器数据手册、g-sersor芯片数据手册的全部内容,希望文章能够帮你解决ARM:g-sensor重力传感器电路原理图、I2C控制器数据手册、g-sersor芯片数据手册所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复