wuyouwuyou

总线使用的一点小结

0
阅读(2778)

初始化函数首先判断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