第5章 LPC2000系列ARM硬件结构
如果存储器组配置成 32 位宽度,地址线 A0 和 A1 无用。如果存储器组配置成 16 位宽,
4. 使用 VIC 产生软件中断
EXTINT = 0x02;
VICVectAddr = 0;
}
void __irq Eint2_IRQ(void) { …
EXTINT = 0x04;
VICVectAddr = 0;
}
4. 使用 VIC 产生软件中断
VIC 提供了软件中断功能,第一个中断均可以使用软件中断产生,软件中断与对应通道 上的硬件中断是逻辑“或”的关系。VIC 产生软件中断是进入到 IRQ/FIQ 模式,是进入 IRQ
- - 185
模式还是FIQ 模式与该通道中断设置有关(VICIntSelect 寄存器设置)。VIC 软件中断初始化 例子如程序清单5.15 所示。
VIC 软件中断是通过设置 VICSoftInt 发生,在中断处理程序中需要操作 VICSoftIntClear 来清除中断标志。
程序清单 5.15 VIC 软件中断初始化 VICIntSelect = 0x00000000; // 设置所有中断均为IRQ 中断 VICVectCntl15 = 0x20 | 31; // 中断通道号 31 分配到 Slot15
VICVectAddr15 = (uint32) Soft_IRQ; // 设置 VIC 软件中断服务程序入口地址 VICIntEnable = 1<<31;
5.8.8 启动代码相关部分
LPC2100、LPC2200 的启动代码中包含有 VIC 初始化程序,如程序清单 5.16 所示(在 target.c 文件中)。程序首先禁止所有中断(程序清单 5.16 (1)),设置 VICVectAddr 寄存器的值 为0(程序清单 5.16 (2)),最后将所有中断设置为 IRQ 中断(程序清单 5.16 (3))。
禁止所有中断是避免调试时一个中断没有响应就再次载入程序,因向量中断控制器状态 错误而不能正确识别中断。
程序清单 5.16 TargetResetInit ()—VIC 初始化 void TargetResetInit(void)
{
…
/* 初始化 VIC */
VICIntEnClr = 0xffffffff; (1)
VICVectAddr = 0; (2)
VICIntSelect = 0; (3)
… }
当用户使用IRQ/FIQ 中断时,需要设置 CPSR 寄存器的 I 位或 F 位,并在用户主程序中 设置VIC 来使能相应片内外设的中断,设置片内外设中断使能。
一旦产生 IRQ 中断,微控制器即会切换到 IRQ 模式,并且跳转到向量表 0x00000018 地址执行程序。如程序清单5.17 (7)所示,在 IRQ 向量使用的指令与其它向量不同,当 CPU 执行这条指令但还没有跳转时,PC 的值为 0x00000020(因为 ARM7TDMI 内核是三级流水线 结构),0x00000020 减去 0x00000ff0 为 0xFFFFF030,这是向量中断控制器(VIC)的特殊寄 存器VICVectAddr,这个寄存器保存当前将要服务的 IRQ 的中断服务程序的入口,用这一条 指令就可以直接跳转到需要的中断服务程序中。
一旦产生FIQ 中断,处理器即会切换到 FIQ 模式,并且跳转到向量表 0x0000001C 地址 执行程序。如程序清单5.17 (8、16)所示,程序将跳到 FIQ_Handler 标号处,处理 FIQ 中断 服务程序。
程序清单 5.17 异常向量表—IRQ/FIQ 中断 Reset
LDR PC, ResetAddr (1)
- - 186
LDR PC, UndefinedAddr (2)
LDR PC, SWI_Addr (3) LDR PC, PrefetchAddr (4)
LDR PC, DataAbortAddr (5)
DCD 0xb9205f80 (6) LDR PC, [PC, #-0xff0] (7) LDR PC, FIQ_Addr (8)
ResetAddr DCD ResetInit (9) UndefinedAddr DCD Undefined (10) SWI_Addr DCD SoftwareInterrupt (11) PrefetchAddr DCD PrefetchAbort (12) DataAbortAddr DCD DataAbort (13) Nouse DCD 0 (14) IRQ_Addr DCD 0 (15) FIQ_Addr DCD FIQ_Handler (16)
设置CPSR 寄存器的 I 位或 F 位,需要在特权模式下进行,最简单的方法就是在启动代 码中设置。如程序清单5.18 所示(在 startup.s 文件中),把程序清单 5.18 (2)从原来的 0xdf 更 改为0x5f,即清零 CPSR 寄存器的 I 位,使能 IRQ 总的中断允许。
程序清单 5.18 设置 CPSR 寄存器的 I 位 InitStack
MOV R0, LR (1)
…
;设置系统模式堆栈
MSR CPSR_c, #0x5f (2)
LDR SP, =StackUsr (3)
MOV PC, R0 (4)
5.9 GPIO
5.9.1 特性
单独位的方向控制,即每一个 I/O 口线可单独设置为输入/输出模式 单独控制 I/O 口输出的置位或清零
所有 I/O 口在复位后默认为输入 5.9.2 应用
通用 I/O 口
驱动 LED 或其它指示器 控制片外器件
检测数字输入,如键盘或开关信号
- - 187 5.9.3 引脚描述
GPIO 引脚描述见表 5.64,这是 P0 和 P1 端口的 GPIO 引脚。除 P0 和 P1 外,
LPC2210/2212/2214 还包含另外两个端口——P2 和 P3,这两个端口与外部存储器总线复用,
只有在不用作外部存储器总线时(通过配置 PINSEL2 寄存器实现),才可以作为 GPIO 使用, 0xE0028020,P3 口的寄存器起始地址为 0xE0028030,如表 5.66 所示,各寄存器的功能与 P0 和 P1 的寄存器是一致的。
GPIO 输出置位寄存器。该寄存器和 IOCLR 寄存器一起控制输出引脚的状态。写入1 使
GPIO 输出置位寄存器。该寄存器和 IOCLR 寄存器一起控制输出引脚的状态。写入1 使
- - 188 接上表
通用
名称 描述 访问 复位值 PORT2
地址&名称
PORT3 地址&名称
IOCLR
GPIO 输出清零寄存器。该寄存器控制输出引 脚的状态。写入1 使对应引脚输出低电平并 清零IOSET 寄存器中的对应位。写入 0 无效。
只清零 0x0000 0000
0xE002802C IO0CLR
0xE002803C IO1CLR 注意:LPC2210/2212/2214 才有 P2 和 P3 口。
GPIO 引脚值寄存器(IO0PIN - 0xE0028000,IO1PIN – 0xE0028010)
该寄存器提供GPIO 引脚的值。它反映了外部环境对引脚的影响。
写该寄存器会将值保存到输出寄存器,可用于I/O 测试。该特性在应用中几乎毫无用处,
因为不可能对该寄存器中单个字节执行写操作。
IOPIN 寄存器描述见表 5.67。
表 5.67 GPIO 引脚值寄存器
IOPIN 描述 复位值
31:0 GPIO 引脚值。IO0PIN 的位 0 对应于 P0.0 ... 位 31 对应于 P0.31 未定义
GPIO 输出置位寄存器(IO0SET - 0xE0028004,IO1SET – 0xE0028014)
当引脚配置为GPIO 输出模式时,可使用该寄存器从引脚输出高电平。写入 1 使对应引 脚输出高电平。写入0 无效。如果一个引脚被配置为输入或第二功能,写 IOSET 无效。
读IOSET 寄存器返回 GPIO 输出寄存器中的值。该值由前一次对 IOSET 和 IOCLR(或 前面提到的IOPIN)的写操作决定。该值不反映任何外部环境对引脚的影响。
IOSET 寄存器描述见表 5.68。
表 5.68 GPIO 输出置位寄存器
IOSET 描述 复位值
31:0 输出置位。IO0SET 的位 0 对应于 P0.0 ... 位 31 对应于 P0.31 0
GPIO 输出清零寄存器(IO0CLR - 0xE002800C,IO1CLR – 0xE002801C)
当引脚配置为GPIO 输出模式时,可使用该寄存器从引脚输出低电平。写入 1 使对应引 脚输出低电平并清零IOSET 寄存器中相应的位。写入 0 无效。如果一个引脚被配置为输入 或第二功能,写IOCLR 无效。
IOCLR 寄存器描述见表 5.69。
表 5.69 GPIO 输出清零寄存器
IOCLR 描述 复位值
31:0 输出清零。IO0CLR 的位 0 对应于 P0.0 ... 位 31 对应于 P0.31 0
GPIO 方向寄存器(IO0DIR - 0xE0028008,IO1DIR – 0xE0028018)
当引脚配置为GPIO 模式时,可使用该寄存器控制引脚的方向。任意引脚的方向位的设 置必须与引脚功能一致,比如某引脚用作输出功能,IODIR 寄存器的相应位必须设置为 1。
IODIR 寄存器描述见表 5.70。
- - 189
表 5.70 GPIO 方向寄存器
IODIR 描述 复位值
31:0 方向控制位(0=输入,1=输出)。IO0DIR 的位 0 控制 P0.0 ... 位 31 控制 P0.31 0
5.9.5 GPIO 使用注意事项
如果指定输出引脚在 GPIO 输出置位寄存器(IOnSET)和 GPIO 输出清零寄存器
(IOnCLR)中的对应位都置位,那么引脚的输出电平取决于后写入的寄存器的值。例如:
IO0SET = 0x0000 0080 IO0CLR = 0x0000 0080
P0.7 输出电平为低,因为写 GPIO 清零寄存器在写置位寄存器之后。
5.9.6 GPIO 应用示例