总线使用的一点小结
0赞初始化函数首先判断I2C的总线频率是否超过400kHz,如果超过,按400kHz计算。选择相应管脚为I2C功能,然后依据I2C的总线频率设置I2C时钟。I2C总线频率等于VPB时钟除以I2C占空比寄存器中的值。然后设置I2C中断,设置I2C中断(VIC通道号为9)为IRQ中断,分配给IRQ slot0,为最高优先级。然后将I2C中断服务程序的首地址存入IRQ slot0的向量地址寄存器VICVectAddr0中,最后使能I2C中断。
由于I2C采用的是中断传输的方式,所以这里重点讲述一下I2C中断服务程序。I2C的中断服务程序过长,所以终端代码请看附录。
I2C中断产生时有很多种状态,这些状态码存放在I2C状态寄存器(I2STAT)的高5位中,所以中断函数的第一步就是读取状态码的值,然后根据不同的状态进行不同的处理,所以用switch语句进行选择。
由于程序是在主端运行,所以下面只介绍几个重要主发送端和主接收端要用到的状态码:
1. 0x08表示起始条件已经发出
2. 0x10表示重发起始条件已经发出
3. 0x18表示从地址+W已发出,并收到ACK
4. 0x20表示从地址+W已发出,并收到NACK
5. 0x28表示数据字节已经发出,并收到ACK
;定义堆栈的大小
SVC_STACK_LEGTH EQU 0
FIQ_STACK_LEGTH EQU 0
IRQ_STACK_LEGTH EQU 256
ABT_STACK_LEGTH EQU 0
UND_STACK_LEGTH EQU 0
NoInt EQU 0x80
NoFIQ EQU 0x40
USR32Mode EQU 0x10
SVC32Mode EQU 0x13
SYS32Mode EQU 0x1f
IRQ32Mode EQU 0x12
FIQ32Mode EQU 0x11
;引入的外部标号在这声明
IMPORT FIQ_Exception ;快速中断异常处理程序
IMPORT __main C语言主程序入口
IMPORT TargetResetInit ; 目标板基本初始化
;给外部使用的标号在这声明
EXPORT bottom_of_heap
EXPORT StackUsr
EXPORT Reset
EXPORT __user_initial_stackheap
CODE32
PRESERVE8
AREA RESET,CODE,READONLY
ARM
;中断向量表
Reset
LDR PC, ResetAddr
LDR PC, UndefinedAddr
LDR PC, SWI_Addr
LDR PC, PrefetchAddr
LDR PC, DataAbortAddr
DCD 0xb9205f80
LDR PC, [PC, #-0xff0]
LDR PC, FIQ_Addr
