ARM:g-sensor重力传感器电路原理图、I2C控制器数据手册、g-sersor芯片数据手册

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>【主/从设备发送/接收流程编码验证】
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

姜源Jerry

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值