一:Tiny4412 裸板重力感应驱动编写
整个编写过程大概分为如下几步:
(1)在底板上找到重力感应器的所在位置,找到芯片型号(我用的板子上重力感应器芯片型号为:MMA7660FC)
(2)通过型号查看重力感应器电路图,了解每个引脚的功能
(3)找到引脚对应的网标(EINT,SDL,SCL)配置其相应的gpio口
(4)配置芯片相关寄存器
(5)使用I2C来读取重力感应器相应寄存器的值
下面是整个驱动的简单流程图:
通过看底板我们知道了重力感应器的控制芯片型号为:MMA7660FC,接下来我们就在看看改芯片的电路图(如下):
由上图我们可以看出它的外部中断XEINT25,用到的i2c总线为SDA3、SCL3
通过网标我们可以看到它是怎么连接到核心板上的(soc)
由上图可知,XEINT25、I2CSDA3、SCL3所对应的gpio分别为GPA1_2、GPA1_3、GPX3_1,之后我们就可以配置gpio口为相应的功能
通过datasheet我们可以找到它的外部中断号为64,如下图:
简单了解了mma7660的电路图之后我们就需要看芯片的datasheet,了解里面寄存器的配置及功能
首先看一下整个芯片与我们核心板的连接图:
由上图我们可以看出,芯片连接到我们核心板(soc)的总共为三根线:INT( 中断信号),SDA、SCL(通i2c来进行寄存器的配置和读取)
下面看一下该芯片的几种工作模式:
今天我们实验的所需要的就是就当板子在晃动的时候它会出发中断,我们利用i2c来读取它相应寄存器的值,来判断前后左右以及X、Y、Z的值
下面是该芯片的寄存器及功能:
由上图我们可以看出寄存器:0x00、0x01、0x02它的底六位分别存储着对应的X、Y、Z的值,因此在之后的试验中我们就可以利用i2c来读取它里面的值
0x03这个寄存器的具体功能如下所所示、它里面存储了前后左右上下的值:
下面的几个寄存器是我们需要配置的:
这个寄存是:该芯片里面的中断寄存器,我们需要配置相应值来响应中断,光配置外部中断是不可以的,我们需要配置该寄存器来响应我们的外部中断
该寄存器是配置相应的模式,我们需要配置它为shake,当我们在晃动板子是可以出发中断;配置好这两个寄存器之后,我们就可以使用I2C来读取对应寄存器的值了
接下来我们需要做的就是设置相应的gpio口,以及配置好I2C的相应寄存器:
I2C总线驱动在上一篇中已经介绍了,I2C总线设备分为四种模式:主端发送、主端接收,从端发送、从端接收,在该驱动中我们用到的只有主发跟主收,下面是相应的流程图,整个I2C的读写都是按照这个流程:
主端发送:
主端接收:
配置好整个I2C之后我们就可以对芯片进行相应的设置和读取了,下面贴出真个重力感应驱动的代码:
1 #ifndef __REGS_H 2 #define __REGS_H 3 4 #define printf(...) (((int (*)(const char *, ...))0xc3e114d8)(__VA_ARGS__)) 5 6 #define GPA1CON (*(volatile unsigned long *)0x11400020) 7 #define I2CCON3 (*(volatile unsigned long *)0x13890000) 8 #define I2CADD3 (*(volatile unsigned long *)0x13890008) 9 #define I2CSTAT3 (*(volatile unsigned long *)0x13890004) 10 #define I2CDS3 (*(volatile unsigned long *)0x1389000C) 11 #define I2CLC3 (*(volatile unsigned long *)0x13890010) 12 13 #define GPD1CON (*(volatile unsigned long *)0x114000C0) 14 #define GPD1PUD (*(volatile unsigned long *)0x114000C8) 15 #define I2CCON1 (*(volatile unsigned long *)0x13870000) 16 #define I2CADD1 (*(volatile unsigned long *)0x13870008) 17 #define I2CSTAT1 (*(volatile unsigned long *)0x13870004) 18 #define I2CDS1 (*(volatile unsigned long *)0x1387000C) 19 #define I2CLC1 (*(volatile unsigned long *)0x13870010) 20 21 #define ICCICR_CPU0 (*(volatile unsigned long *)0x10480000) 22 #define ICCPMR_CPU0 (*(volatile unsigned long *)0x10480004) 23 #define ICDDCR (*(volatile unsigned long *)0x10490000) 24 #define ICDIPR15_CPU0 (*(volatile unsigned long *)0x1049043C) 25 #define ICDIPTR15_CPU0 (*(volatile unsigned long *)0x1049083C) 26 #define ICDISER1_CPU0 (*(volatile unsigned long *)0x10490104) 27 #define ICDSGIR (*(volatile unsigned long *)0x10490f00) 28 #define ICCIAR_CPU0 (*(volatile unsigned long *)0x1048000C) 29 #define ICCEOIR_CPU0 (*(volatile unsigned long *)0x10480010) 30 31 #define GPX1CON (*(volatile unsigned long *)0x11000C20) 32 33 #define EXT_INT41_CON (*(volatile unsigned long *)0x11000E04) 34 #define EXT_INT41_MASK (*(volatile unsigned long *)0x11000F04) 35 #define EXT_INT41_PEND (*(volatile unsigned long *)0x11000F44) 36 37 #define GPX3CON (*(volatile unsigned long *)0x11000c60) 38 #define GPX3DAT (*(volatile unsigned long *)0x11000c64) 39 #define GPD0CON (*(volatile unsigned long *)0x110000a0) 40 #define GPD0DAT (*(volatile unsigned long *)0x110000a4) 41 42 #define ICCICR_CPU0 (*(volatile unsigned long *)0x10480000) 43 #define ICCPMR_CPU0 (*(volatile unsigned long *)0x10480004) 44 #define ICDDCR (*(volatile unsigned long *)0x10490000) 45 #define ICDIPR16_CPU0 (*(volatile unsigned long *)0x10490440) 46 #define ICDIPTR16_CPU0 (*(volatile unsigned long *)0x10490840) 47 #define ICDISER2_CPU0 (*(volatile unsigned long *)0x10490108) 48 #define ICDSGIR (*(volatile unsigned long *)0x10490f00) 49 #define ICCIAR_CPU0 (*(volatile unsigned long *)0x1048000C) 50 #define ICCEOIR_CPU0 (*(volatile unsigned long *)0x10480010) 51 52 #define EXT_INT43_CON (*(volatile unsigned long *)0x11000E0C) 53 #define EXT_INT43_MASK (*(volatile unsigned long *)0x11000F0C) 54 #define EXT_INT43_PEND (*(volatile unsigned long *)0x11000F4C) 55 56 #endif