本章目标:
了解I2C总线协议;
掌握S3C2410/S3C2440中I2C接口的使用方法;
12.1 I2C总线协议及硬件介绍

12.1.1 I2C总线协议
1 I2C总线的概念
2 I2C总线的信号类型

3 I2C总线的数据传输格式

12.1.2 S3C2410/S3C2440 I2C总线控制器
1. S3C2410/S3C2440 I2C总线控制器寄存器介绍
    S3C2410/S3C2440的I2C接口有4种工作模式:主机发送、主机接收、从机发送、
从机接收。其内部结构如图12.6所示。

    从图12.6可知,S3C2410/S3C2440提供4个寄存器来完成所有的I2C操作。SDA线上的数据
从IICDS寄存器发出,或传入IICDS寄存器中;IICADD寄存器中保存S3C2410/S3C2440当做从
机时的地址;IICCON、IICSTAT 两个寄存器用来控制或标识各种状态,比如选择工作模式,发出
S信号、P信号,决定是否发出ACK信号,检测是否收到ACK信号。各寄存器的用法如下:
(1)IICCON寄存器(Multi-master IIC-bus control)
    IICCON寄存器用于控制是否发出ACK信号、设置发送器的时钟、开启IIC中断,并标识中断是
否发生。它的各位含义如下表12.2所示。

     使用IICCON寄存器时,有如下注意事项:
    ① 发送模式的时钟频率由位[6]、位[3:0]联合决定。另外,当IICCON[6] = 0时,IICCON[3:0]
不能去0或1。
    ② IIC中断在以下3种情况下发生:
        当发出地址信息或接收到一个从机地址并且吻合时;
        当总线仲裁失败时;
        当发送/接收完一个字节的数据(包括响应位)时。
    ③ 基于SDA 、SCL线上时间特性的考虑,要发送数据时,先将数据写入IICDS寄存器,
然后清除中断。
    ④ 如果IICCON[5] = 0,IICCON[4]将不能正常工作。所以即使不使用IIC中断,也要将
IICCON[5]设为1。
(2)IICSTAT寄存器(Multi-master IIC-bus control/status)。
    IICSTAT寄存器用于选择IIC接口的工作模式,发出S信号、P信号,使能接收/发送功能,
并标识各种状态,比如总线仲裁是否成功、作为从机时是否被寻址、是否接收到0地址、是
否接收到ACK信号等。
    IICSTAT寄存器的各位如表12.3所示:

(3)IICADD寄存器(Multi-master IIC-bus address)
    用到位[7:1],表示从机地址。在IICSTAT[4]为1时,才可以写入;随时都可以读出。
(4)IICDS寄存器(Multi-master IIC-bus Tx/Rx data shift)
    用到位[7:0],其中保存的是要发送或已经接收到的数据。在IICSTAT[4]为1时才可写入,
随时可以读出。
2.S3C2410/S3C2440 I2C总线操作方法
    启动或复位S3C2410/S3C2440 的IIC传输有以下两种方法。
(1)当IICCON[4]即中断状态位为0时,通过写IICSTAT寄存器启动IIC操作。有以下两种
情况。
    ① 在主机模式:
        令IICSTAT[5:4]等于0b11,将发出S信号和IICDS寄存器的数据(寻址),
        令IICSTAT[5:4]等于0b01,将发出P信号。
    ② 在从机模式,令IICSTAT[4]等于1,将等待其他主机发出S信号及地址信息。
(2)当IICCON[4]即中断状态位为1时,表示I2C操作被暂停。在这期间设置好其他寄存器
之后,向IICCON[4]写入0即可恢复I2C操作。
    所谓“设置其他寄存器”,有以下3种情况。
    ① 对于主机模式,可以按照上面(1)的方法写IICSTAT寄存器,恢复I2C操作后即可发出
S信号和IICDS寄存器的值(寻址),或发出P信号。
    ② 对于发送器,可以将下一个要发送的数据写入IICDS寄存器中,恢复I2C操作后即可发
出这个数据。
    ③ 对于接收器,可以从IICDS寄存器中读出接收到的数据。最后向IICCON[4]写入0的同时,
设置IICCON[7]以决定在接收到下一个数据后是否发出ACK信号。
 
    通过中断服务程序驱动I2C传输。
(1)当仲裁失败时,发生中断——本次传输没有抢到总线,可以稍后继续。
(2)对于主机模式,当发出S信号、地址信息并经过一个SCL周期(对应ACK信号)后,发生
中断——主机可在此时判断是否成功寻址到从机。
(3)对于从机模式,当接收到的地址与IICADD寄存器吻合时,先发出ACK信号,然后发生
中断——从机可在此时准备后续的传输。
(4)对于发送器,当发送完一个数据并经过一个SCL周期(对应ACK信号)后,发生中断。这
时可以准备下一个要发送的数据,或发出P信号以停止传输。
(5)对于接收器,当接收到一个数据时,先根据IICCON[7]决定是否发出ACK信号后,然后
发生中断。这是可以读取IICDS寄存器得到数据,并设置IICCON[7]已决定接收到下一个数据
后是否发出ACK。
 
    对于4种工作模式,S3C2410/S3C2440数据手册中都有它们的操作流程图。现在以主机发
送器为例说明,它的工作流程如图12.7所示,其他的工作模式请参考数据手册。

    下面结合I2C寄存器的用法,详细讲解图12.7中各步骤的含义。
(1)配置主机发送器的各类参数
    设置GPE15、GPE14引脚用于SDA、SCL,设置IICCON寄存器选择I2C发送时钟,最后,
设置IICSTAT[4]为1,这样,后面才能写IICDS寄存器。
    注意:初始时IICCON[4]为0,不能将IICSTAT设为主机模式,否则就会立刻发出S信号、
发送IICDS寄存器里的值。
(2)将要寻址的从机地址写入IICDS寄存器。
(3)将0xF0写入IICSTAT寄存器,即设为主机发送器、使能串行输出功能、发出S信号。
(4)发出S信号后,步骤(2)中设置的IICDS寄存器值也将被发出,它用来寻址从机。
(5)在响应周期之后,发生中断,此时IICCON[4]为1,I2C传输暂停。
(6)如果没有数据要发送,则跳到步骤(10);否则跳到步骤(7)。
(7)将下一个要发送的数据写入IICDS寄存器中。
(8)向IICCON[4]中写入0,恢复I2C传输。
(9)这时,IICDS寄存器中的值将被一位一位地发送出去。当8位数据发送完毕,再经过
另一个SCL周期(对应ACK信号)后,中断再次发生,跳到步骤(5)。
    步骤(5)~(9)不断循环知道发出所有数据。当要停止传输时,跳到步骤(10)。
(10)将0xF0写入IICSTAT寄存器,即设为主机发送器、使能串行输出功能、发出P信号。
            注意:这时的P信号并没有实际发出,只有清除了IICCON[4]后才会发出P信号。
(11)清除IICCON[4],P信号得以发出。
(12)等待一段时间,使得P信号完全发出。
12.2 I2C总线操作实例
12.2.1 I2C接口RTC芯片M41t11的操作方法
    本书所用开发板中,通过I2C总线连接RTC(实时时钟)芯片M4lt11,它使用电池供电,系
统断电时也可以维持日期和时间。S3C2410/S3C2440作为I2C主机向M4lt11发送数据以设
置日期和时间、读取M4lt11以获取日期和时间。连接图如图12.8所示。

     M4lt11中有8个寄存器,分别对应秒、分、时、天(星期几)、日、月、年、控制寄存器,
其中的数据都是以BCD格式保存(BCD格式例子:0x15表示数值15),如表12.4所示。

     除上表的8个寄存器(地址为0~7)之外,M4lt11内部还有56字节的RAM(地址为8~63)。
访问M4lt11前,先设置寄存器地址,以后每次读写操作完成后,M4lt11内部会自动将寄
存器地址加1.
    所以读写M4lt11分以下两个步骤:
    (1)主机向M4lt11发出要操作的寄存器起始地址(0~7)。
    (2)要设置M4lt11时,主机连续发出数据;读取M4lt11时,主机连续读取数据。
    M4lt11的I2C从机地址为0xD0。
12.2.2 程序设计
    本实例将在串口上输出一个菜单,可以选择设置时间和日期,或者将它们读出来。将
通过本实例验证I2C主机的发送、接收操作。
12.2.3 设置/读取M4lt11的源码详解
    本实例的源码在/work/hardware/i2c目录下。
    文件i2c.c封装了S3C2410/S3C2440作为主机发送器、主机接收器的4个操作函数:
i2c_init用于初始化,i2c_write用于发起发送数据,i2c_read用于发起读取数据,
I2CIntHandle是I2C中断服务程序,用于完成后续的数据传输。
1.S3C2410/S3C2440 I2C控制器初始化
    i2c_init函数对应于图12.7中的步骤(1),初始化I2C,代码如下:
 行号
24行/*
25行 *I2C初始化
26行 */
27行 void i2c_init(void)
28行 {
29行 GPEUP |= 0xc000; //禁止内部上拉
30行 GPECON |= 0xa0000000; //选择引脚功能,GPE15:IICSDA,GPE14:IICSCL
31行
32行 INTMSK &= ~(BIT_IIC);
33行
34行 /*bit[7] = 1,使能ACK
35行 *bit[6] = 0,IICCLK = PCLK/16
36行 *bit[5] = 1,使能中断
37行 *bit[3:0] = 0xf,Tx clock = IICCLK/16
38行 *PCLK = 50MHz、IICCLK = 3.125MHz,Tx Clock = 0.195MHz
39行 */
40行 IICCON = ( << ) | ( << ) | ( << ) | (0xf); //0xaf
41行
42行 IICADD = 0x10; //S3C24xx slave address = [7:1]
43行 IICSTAT = 0x10; //I2C串行输出使能(Rx/Tx)
44行 }
45行

i2c.c->i2c_init()

    第32行在INTMSK寄存器中开启I2C中断,这样,以后调用i2c_read、i2c_write启动传
输时,即可触发中断,进而可以在中断服务程序中进一步完成后续的传输。
    第40行用于选择发送时钟,并进行一些设置:使能ACK、使能中断。
    第42行用于设置S3C2410/S3C2440作为I2C从机时的地址,本实例未用到。
    第43行使能I2C串行输出(设置IICSTAT[4]为1),这样,在i2c_write、i2c_read
函数中就可以写IICDS寄存器了。
2.S3C2410/S3C2440 I2C主机发送函数
    初始化完成后,就可以调用i2c_read、i2c_write读写I2C从机了。它们的使用方法从参数
名称就可以看出。这两个函数只是启动I2C传输,然后等待,知道数据在中断服务程序中传
输完毕后再返回。
    i2c_write函数的实现如下:
 行号
46行 /*
47行 *主机发送
48行 *slvAddr:从机地址,buf:数据存放的缓冲区,len:数据长度
49行 */
50行 void i2c_write(unsigned int slvAddr, unsigned char *buf, int len)
51行 {
52行 g_tS3C24xx_I2C.Mode = WRDATA; //写操作
53行 g_tS3C24xx_I2C.Pt = ; //索引值初始化为0
54行 g_tS3C24xx_I2C.pDATA = buf; //保存缓冲区地址
55行 g_tS3C24xx_I2C.DataCount = len; //传输长度
56行
57行 IICDS = slvAddr;
58行 IICSTAT = 0xf0; //主机发送、启动
59行
60行 /*等待直至数据传输完毕*/
61行 while(g_tS3C24xx_I2C.DataCount != -);
62行 }
63行

i2c.c->i2c_write()

    第57行将从机地址写入IICDS寄存器,这样,在第58行启动传输并发出S信号后,紧接
着就自动发出从机地址。
    第58行设置IICSTAT寄存器,将S3C2410/S3C2440设为主机发送器,并发出S信号。
后续的传输工作将在中断服务程序中完成。
    第61行等待g_tS3C24xx_I2C.DataCount在中断服务程序中被设为-1,这表明传输完成,
于是返回。
3.S3C2410/S3C2440 I2C主机接收函数

i2c_read函数的实现与i2c_write类似,代码如下:

 行号
64行 /*
65行 *主机接收
66行 *slvAddr:从机地址,buf:数据存放的缓冲区,len:数据长度
67行 */
68行 void i2c_read(unsigned int alvAddr, unsigned char *buf, int len)
69行 {
70行 g_tS3C24xx_I2C.Mode = RDDATA; //读操作
71行 g_tS3C24xx_I2C.Pt = -; //索引值初始化为-1,表示第一个中断时不接收数据(地址中断)
72行 g_tS3C24xx_I2C.pData = buf; //保存缓冲区地址
73行 g_tS3C24xx_I2C.DataCount = len; //传输长度
74行
75行 IICDS = slvAddr;
76行 IICSTAT = 0xb0; //主机接收,启动
77行
78行 /*等待直至数据传输完毕*/
79行 while(g_tS3C24xx_I2C.DataCount != -);
80行 }
81行

i2c.c->i2c_read()

    需要注意的是第71行将索引值设为-1,在中断处理函数中会根据这个值决定是否从
IICDS寄存器中读取数据。读操作时,第1次中断发生时表示发出了地址,这时候不能
读取数据。

4.S3C2410/S3C2440 I2C中断服务程序

I2C操作的主体在中断服务程序,它分为3部分:首先在SRCPND、INTPND中清除中

断,后面两部分对应于写操作和读操作。先看清除中断的代码:
 行号
82行 /*
83行 *I2C中断服务程序
84行 *根据剩余的数据长度选择继续传输或者结束
85行 */
86行 void I2CInitHandle(void)
87行 {
88行 unsigned int iicSt, i;
89行
90行 //清中断
91行 SRCPND = BIT_IIC;
92行 INTPND = BIT_IIC;
93行
94行 iicSt = IICSTAT;
95行
96行 if(iicSt & 0x8){printf("Bus arbitration failed\n\r");} //仲裁失败

i2c.c->I2CInitHandle()

    第91、92行用来清除I2C中断的代码。需要注意的是,即使清除中断后,IICCON寄存器
中的位[4](中断标识位)仍为1,这导致I2C传输暂停。
    第94行读取状态寄存器IICSTAT,发生中断时有可能时因为仲裁失败,在第96行对它进行
处理。本程序忽略仲裁失败,因为只有一个I2C主机。
    接下来是一个switch语句,分别处理写操作、读操作。先看写操作:
 行号
98行 switch(g_tS3C24xx_I2C.Mode)
99行 {
100行 case WRDATA:
101行 {
102行 if((g_tS3C24xx_I2C.DataCount--) == )
103行 {
104行 //下面两行用于恢复I2C操作,发出P信号
105行 IICSTAT = 0xd0;
106行 IICCON = 0xaf;
107行 Delay(); //等待一段时间以便P信号已经发出
108行 break;
109行 }
110行
111行 IICDS = g_tS3C24xx_I2C.pData[g_tS3C24xx_I2C.Pt++];
112行
113行 //将数据写入IICDS后,需要一段时间才能出现在SDA线上
114行 for(i = ; i < ; i++);
115行
116行 IICCON = 0xaf; //恢复I2C传输
117行 break;
118行 }
119行

i2c.c->I2CInitHandle()->switch()->case WRDATA

    g_tS3C24xx_I2C.DataCount表示剩余等待传输的数据个数,第102行判断数据是否已经
全部发送完毕:若是,则通过第105、106行发出P信号,停止传输;
    第105行设置IICSTAT寄存器以便发出P信号,但是由于这时IICCON[4]仍为1,P信号还没
有实际发出;
    当第106行清除IICCON[4]后,P信号才真正发出去;
    第107行等待一段时间,确保P信号已经发送完毕。
    如果数据还没有发送完毕,第111行从缓冲区中得到下一个要发送的数据,将它写入IICDS
寄存器中。稍等之后,即可在第116行清除IICCON[4]以恢复I2C传输,这时,IICDS寄存器中
的数据就会发送出去,这将触发下一个中断。
    I2C读操作的处理与写操作相似,代码如下:
 行号
120行 case RDDATA:
121行 {
122行 if(g_tS3C24xx_I2C.Pt == -)
123行 {
124行 //这次中断时在发送I2C设备地址后发生的,没有数据
125行 //只接收一个数据时,不要发出ACK信号
126行 g_tS3C24xx_I2C.Pt = ;
127行 if(g_tS3C24xx_I2C.DataCount == )
128行 IICCON = 0x2f; //恢复I2C传输,开始接收数据,接收到数据时不发出ACK
129行 else
130行 IICCON = 0xaf; //恢复I2C传输,开始接收数据
131行 break;
132行 }
133行
134行 if((g_tS3C24xx_I2C.DataCount--) == )
135行 {
136行 g_tS3C24xx_I2C.pData[g_tS3C24xx_I2C.Pt++] = IICDS;
137行
138行 //下面两行恢复I2C操作,发出P信号
139行 IICSTAT = 0x90;
140行 IICCON = 0xaf;
141行 Delay(); //等待一段时间以便P信号已经发出
142行 break;
143行 }
144行
145行 g_tS3C24xx_I2C.pData[g_tS3C24xx_I2C.Pt++] = IICDS;
146行
147行 //接收最后一个数据时,不要发出ACK信号
148行 if(g_tS3C24xx_I2C.DataCount == )
149行 IICCON = 0x2f; //恢复I2C传输,接收到下一个数据时无ACK
150行 else
151行 IICCON = 0xaf; //恢复I2C传输,接收到下一个数据时发出ACK
152行 break;
153行 }

case RDDATA

    读操作比写操作多一个步骤:第一次中断发生时,表示发出了地址,这时候还不能读取
数据。在代码中要分辨这点。对应第122~132行:如果g_tS3C24xx_I2C.Pt等于-1,表示
这是第一次中断,然后修改g_tS3C24xx_I2C.Pt为0,并设置IICCON寄存器恢复I2C传输
(第127~130行)。
    当数据传输已经开始后,每接收到一个数据就会触发一次中断。后面的代码读取数据,
判断所有数据是否已经完成:如果完成则发出P信号,否则继续下一次传输。
    第134行判断数据是否已经发送完毕。
    第19行设置IICSTAT寄存器以便发出P信号,但是由于这时IICCON[4]仍为1,P信号还没
有实际发出。
    第140行清除IICCON[4]后,P信号才真正发出。
    第145~151行用来启动下一次数据的接收。
    第148~151行判断是否只剩下最后一个数据了:若是,则通过第149行的清除IICCON[4]、
IICCON[7],这样即可恢复IIC传输,并使得接收到数据后,S3C2410/S3C2440不发出ACK
信号(这样从机即可知道数据传输完毕);否则在第151行中只要清除IICCON[4]以恢复IIC传输。
    中断服务程序中,当数据数据传输完毕时,g_tS3C24xx_I2C.DataCount将自减为-1,这样,
i2c_read或i2C_write函数即可跳出等待,直接返回。
5.RTC芯片M4lt11特性相关的操作
    m4lt11.c文件中提供两个函数m4lt11_set_datetime、m4lt11_get_datetime。它们都通过调
用i2c_read或i2c_write函数来完成与M4lt11的交互。
    前面说过,操作M4lt11只需要两步:发出寄存器地址,发出数据或读取数据。
m4lt11_set_datetime函数把这两个步骤合并为一个I2C写操作,m4lt11_get_datetime函数先发
起一个I2C写传输,再发起一个I2C读传输。

m4lt11_set_datetime函数代码如下:

 行号
29行 /*
30行 *写m4lt11,设置日期和时间
31行 */
32行 int m4lt11_set_datetime(struct rtc_time *dt)
33行 {
34行 unsigned char leap_yr;
35行 struct{
36行 unsigned char addr;
37行 struct rtc_registers rtc;
38行 }__attribute__ ((packed)) addr_and_regs;
... .../*设置rtc结构,即根据传入的参数构造各寄存器的值*/
76行 i2c_write(0xD0, (unsigned char *)&addr_and_regs, sizeof(addr_and_regs));
77行
78行 return ;
79行 }

m4lt11.c->m4lt11_set_datetime()

    省略号表示的代码用来设置addr_and_regs结构体。这个结构体分为两部分:
addr_and_regs表示M4lt11寄存器地址(它被设为0);
addr_and_regs.rtc表示M4lt11的8个寄存器——秒、分、时、天(星期几)、日、月、年、控制寄存器。
    根据传入参数填充好addr_and_regs结构体后,就可以启动I2C写操作了。
    第38行使用“__attribute__((packed))”设置这个结构体为紧凑格式。使得它的大小
为9字节(否则大小为12字节):1字节用来保存寄存器的地址,8字节用来保存8个寄存器的值。
    m4lt11_get_datetime函数的代码与m4lt11_set_datetime函数类似,如下所示:
 行号
81行 /*
82行 *读取m4lt11,获取日期与时间
83行 */
84行 int m4lt11_get_datetime(struct rtc_time *dt)
85行 {
86行 unsigned char addr[] = {};
87行 struct rtc_registers rtc;
88行
89行 memset(&rtc, , sizeof(rtc));
90行
91行 i2c_write(0xD0, addr, );
92行 i2c_read(0xD0, (unsigned char *)&rtc, sizeof(rtc));
93行
... .../*根据读出的各寄存器的值,设置dr结构体*/
110行 return ;
111行 }

m4lt11.c->m4lt11_get_datetime()

    第91行发起一次I2C写传输,设置要操作的M4lt11寄存器地址为0;
    第92行发起一次I2C读传输,读出M4lt11各寄存器的值;
    省略号对应的代码根据读出的各寄存器的值,设置dr结构。M4lt11中以BCD码表示
日期与时间,需要转换为程序使用的一般二进制格式。
12.2.4 I2C实例的连接脚本
    本实例要用到第8章NAND Flash控制器的代码将代码从NAND Flash复制到SDRAM
中。由于nand代码中用到全局变量,而全局变量要运行与可读写的内存中,为了方便,
使用连接脚本将这些初始代码放到Steppingstone中。
    连接脚本为i2c.lds,内容如下:
 SECTIONS{
. = 0x00000000;
.init : AT(){head.o init.o nand.o}
. = 0x30000000;
.text : AT(){ *(.text)}
.rodata ALIGN() : AT((LOADADDR(.text)+SIZEOF(.text)+)&~(0x03)){*(.rodata*)}
.data ALIGN() :AT((LOADADDR(.rodata)+SIZEOF(.rodata)+)&~(0x03)){*(.data)}
__bss_start = .;
.bss ALIGN() :{ *(.bss) *(COMMON)}
__bss_end = .;
}

i2c.lds

    第2~3行将head.S和nand.c对应的代码的运行地址设为0,加载地址(存在NAND Flash
上的地址)设为0。从NAND Flash启动时,这些代码被复制到Steppingstone后就可以直接运行。
    第4行设置其余代码的运行地址为0x3000 0000;第5行将代码段的加载地址设为4096,
表示代码段将存在NAND Flash地址4096处。
    第6~7行的“AT(...)”设置rodata段、data段的加载地址依次位于代码段之后。
“LOADADDR(...)”表示某段的加载地址,SIZEOF(...)表示它的大小。这两行的前面使用
“ALIGN(4)”使得它们的运行地址为4字节对齐。为了使各段之间加载地址的相应偏移值等于
地址的相对偏移,需要将“AT(...)”中的值也设为4字节对齐:先加上3,然后与~(0x03)进
行与操作(将低2位清0)。
12.2.5 实例测试    
    本程序在main函数中通过串口输出一个菜单,用于设置或读取时间,步骤如下:
(1)使用串口将开发板的COM0和PC的串口相连,打开PC的穿裤工具设为115200、8N1;
(2)在i2c目录下执行make,将可执行文件烧入NAND Flash中运行;
(3)在PC的串口工具上,可以看到如下菜单:
#### RTC Menu ####
Data format: 'year.month.day w hour:min:sec', 'w' is week day
eg:.. ::
[S] Set the RTC
[R] Read the RTC
Enter your selection:
(4)要设置RTC,输入"s"或“S”。可以看到如下字符。
Enter data&time:
    在串口工具中按照"year.month.day w hour:min:sec"格式输入日期与时间,比如:"2007.08.30 4 01:16:57",然后按回车键。
注意:只能输入2000.01.1至2099.12.31之间的日期与时间;年月日与星期必须真实存
在,否则RTC芯片无法正常工作。
(5)要可读取RTC,输入"r"或"R",即可看到当前日期与时间,串口上回输出类似
下面的结果。
*** Now is: ..  :: ***
(6)断电后重启,输入“R”,仍可看到正确的时间。
附:代码:

链接: https://pan.baidu.com/s/1kV24a9L 密码: tfab

JZ2440 裸机驱动 第12章 I2C接口的更多相关文章

  1. JZ2440 裸机驱动 第5章 GPIO接口

    本章目标:     掌握嵌入式开发的步骤:编程.编译.烧写程序.运行     通过GPIO的操作了解软件如何控制硬件 5.1 GPIO硬件介绍     S3C2440A有130个多功能输入/输出口引脚 ...

  2. JZ2440 裸机驱动 第14章 ADC和触摸屏接口

    本章目标:     了解S3C2410/S3C2440和触摸屏的结构:     了解电阻触摸屏的工作原理和等效电路图:     了解S3C2410/S3C2440触摸屏控制器的多种工作模式:     ...

  3. JZ2440 裸机驱动 第13章 LCD控制器(1)

    本章目标  了解LCD显示器的接口及时序: 掌握S3C2410/S3C2440 LCD控制器的使用方法: 了解帧缓冲区的概念,掌握如何设置帧缓冲区来显示图像: 13.1 LCD和LCD控制器 13.1 ...

  4. JZ2440 裸机驱动 第10章 系统时钟和定时器

    本章目标      了解S3C2410/S3C2440的时钟体系结构     掌握通过设置MPLL改变系统时钟的方法     掌握在不同的频率下设置存储控制器的方法     掌握PWM定时器的用法   ...

  5. JZ2440 裸机驱动 第6章 存储控制器

    本章目标:     了解S3C2410/S3C2440地址空间的布局     掌握如何通过总线形式访问扩展的外设,比如内存.NOR Flash.网卡等 ························ ...

  6. JZ2440 裸机驱动 第8章 NAND Flash控制器

    本章目标  了解NAND Flash 芯片的接口 掌握通过NAND Flash控制器访问NAND Flash的方法 8.1 NAND Flash介绍和NAND Flash控制器使用     NAND ...

  7. JZ2440 裸机驱动 第13章 LCD控制器(2)

    13.2 TFT LCD显示实例 13.2.1 程序设计     本实例的目的是从串口输出一个菜单,从中选择各种方法进行测试,比如画线. 画圆.显示单色.使用调色板等. 13.2.2代码详解     ...

  8. JZ2440 裸机驱动 第11章 通用异步收发器UART

    本章目标: 了解UART原理: 掌握S3C2410/S3C2440中UART的使用 11.1 UART原理及UART内部使用方法 11.1.1 UART原理说明     UART用于传输串行数据:   ...

  9. JZ2440 裸机驱动 第7章 内存管理单元MMU

    本章目标:     了解虚拟地址和物理地址的关系:     掌握如何通过设置MMU来控制虚拟地址到物理地址的转化:     了解MMU的内存访问权限机制:     了解TLB.Cache.Write ...

随机推荐

  1. java并发编程:线程安全管理类--原子操作类--AtomicLongArray

    1.类 AtomicLongArray public class AtomicLongArray extends Object implements Serializable 可以用原子方式更新其元素 ...

  2. 7dynamic_cast用法

    已知下面的class层次,其中每一个class都定义有一个default constructor和一个virtual destructor: class X{……}; class A{……}; cla ...

  3. python 安装 scapy windows 10 64bit

    简介: 前段时间装的pypcap做嗅探.打包受阻.因为我都是在windows做的.也要打包到exe给别人用. 所以尝试了一下scapy,也可以嗅探,貌似功能更强大.先用sniff吧. 这个也不是在ve ...

  4. ReentrantReadWriteLock——读读共享(一)

    多个线程可以同时读,读读是异步的.非互斥的 1.Service.java(封装的方法,供线程A和B访问) package ReentrantReadWriteLock; import java.uti ...

  5. 栈(stack),C++模板实现

    body, table{font-family: 微软雅黑; font-size: 13.5pt} table{border-collapse: collapse; border: solid gra ...

  6. String类型的注意事项

    1.string类型是可变长字符序列,而vector是集合,存放的是某种类型的可变长序列 2.string类型对象的初始化有多种方式:string str="Hello",是将字符 ...

  7. L1-013 计算阶乘和

    对于给定的正整数N,需要你计算 S=1!+2!+3!+...+N!. 输入格式: 输入在一行中给出一个不超过10的正整数N. 输出格式: 在一行中输出S的值. 输入样例: 3 输出样例: 9   #i ...

  8. python struct模块的使用

    struct模块中的函数 函数 return explain pack(fmt,v1,v2…) string 按照给定的格式(fmt),把数据转换成字符串(字节流),并将该字符串返回. pack_in ...

  9. js push ,pop ,concat ,join方法

    push 方法 将新元素添加到一个数组中,并返回数组的新长度值. arrayObj.push([item1 [item2[. . . [itemN ]]]]) 说明 push 方法将以新元素出现的顺序 ...

  10. Java中统计字符串中各个字符出现的次数

    import java.util.Iterator; import java.util.Set; import java.util.TreeMap; public class TreeMapDemo ...