273. #define PORTD_PCR18 PORT_PCR_REG(PORTD_BASE_PT
R,18)
274. #define PORTD_PCR19 PORT_PCR_REG(PORTD_BASE_PT
R,19)
275. #define PORTD_PCR20 PORT_PCR_REG(PORTD_BASE_PT
R,20)
276. #define PORTD_PCR21 PORT_PCR_REG(PORTD_BASE_PT
R,21)
277. #define PORTD_PCR22 PORT_PCR_REG(PORTD_BASE_PT
R,22)
278. #define PORTD_PCR23 PORT_PCR_REG(PORTD_BASE_PT
R,23)
279. #define PORTD_PCR24 PORT_PCR_REG(PORTD_BASE_PT
R,24)
280. #define PORTD_PCR25 PORT_PCR_REG(PORTD_BASE_PT
R,25)
281. #define PORTD_PCR26 PORT_PCR_REG(PORTD_BASE_PT
R,26)
282. #define PORTD_PCR27 PORT_PCR_REG(PORTD_BASE_PT
R,27)
283. #define PORTD_PCR28 PORT_PCR_REG(PORTD_BASE_PT
R,28)
284. #define PORTD_PCR29 PORT_PCR_REG(PORTD_BASE_PT
R,29)
285. #define PORTD_PCR30 PORT_PCR_REG(PORTD_BASE_PT
R,30)
286. #define PORTD_PCR31 PORT_PCR_REG(PORTD_BASE_PT
R,31)
287. #define PORTD_GPCLR PORT_GPCLR_REG(PORTD_BASE_
PTR)
288. #define PORTD_GPCHR PORT_GPCHR_REG(PORTD_BASE_
PTR)
289. #define PORTD_ISFR PORT_ISFR_REG(PORTD_BASE_P
TR)
290. #define PORTD_DFER PORT_DFER_REG(PORTD_BASE_P
TR)
291. #define PORTD_DFCR PORT_DFCR_REG(PORTD_BASE_P
TR)
292. #define PORTD_DFWR PORT_DFWR_REG(PORTD_BASE_P
TR)
293. /* PORTE */
294. #define PORTE_PCR0 PORT_PCR_REG(PORTE_BASE_PT
R,0)
295. #define PORTE_PCR1 PORT_PCR_REG(PORTE_BASE_PT
R,1)
296. #define PORTE_PCR2 PORT_PCR_REG(PORTE_BASE_PT
R,2)
297. #define PORTE_PCR3 PORT_PCR_REG(PORTE_BASE_PT
R,3)
298. #define PORTE_PCR4 PORT_PCR_REG(PORTE_BASE_PT
R,4)
299. #define PORTE_PCR5 PORT_PCR_REG(PORTE_BASE_PT
R,5)
300. #define PORTE_PCR6 PORT_PCR_REG(PORTE_BASE_PT
R,6)
301. #define PORTE_PCR7 PORT_PCR_REG(PORTE_BASE_PT
R,7)
302. #define PORTE_PCR8 PORT_PCR_REG(PORTE_BASE_PT
R,8)
303. #define PORTE_PCR9 PORT_PCR_REG(PORTE_BASE_PT
R,9)
304. #define PORTE_PCR10 PORT_PCR_REG(PORTE_BASE_PT
R,10)
305. #define PORTE_PCR11 PORT_PCR_REG(PORTE_BASE_PT
R,11)
306. #define PORTE_PCR12 PORT_PCR_REG(PORTE_BASE_PT
R,12)
307. #define PORTE_PCR13 PORT_PCR_REG(PORTE_BASE_PT
R,13)
308. #define PORTE_PCR14 PORT_PCR_REG(PORTE_BASE_PT
R,14)
309. #define PORTE_PCR15 PORT_PCR_REG(PORTE_BASE_PT
R,15)
310. #define PORTE_PCR16 PORT_PCR_REG(PORTE_BASE_PT
R,16)
311. #define PORTE_PCR17 PORT_PCR_REG(PORTE_BASE_PT
R,17)
312. #define PORTE_PCR18 PORT_PCR_REG(PORTE_BASE_PT
R,18)
313. #define PORTE_PCR19 PORT_PCR_REG(PORTE_BASE_PT
R,19)
314. #define PORTE_PCR20 PORT_PCR_REG(PORTE_BASE_PT
R,20)
315. #define PORTE_PCR21 PORT_PCR_REG(PORTE_BASE_PT
R,21)
316. #define PORTE_PCR22 PORT_PCR_REG(PORTE_BASE_PT
R,22)
317. #define PORTE_PCR23 PORT_PCR_REG(PORTE_BASE_PT
R,23)
318. #define PORTE_PCR24 PORT_PCR_REG(PORTE_BASE_PT
R,24)
319. #define PORTE_PCR25 PORT_PCR_REG(PORTE_BASE_PT
R,25)
320. #define PORTE_PCR26 PORT_PCR_REG(PORTE_BASE_PT
R,26)
321. #define PORTE_PCR27 PORT_PCR_REG(PORTE_BASE_PT
R,27)
322. #define PORTE_PCR28 PORT_PCR_REG(PORTE_BASE_PT
R,28)
323. #define PORTE_PCR29 PORT_PCR_REG(PORTE_BASE_PT
R,29)
324. #define PORTE_PCR30 PORT_PCR_REG(PORTE_BASE_PT
R,30)
325. #define PORTE_PCR31 PORT_PCR_REG(PORTE_BASE_PT
R,31)
326. #define PORTE_GPCLR PORT_GPCLR_REG(PORTE_BASE_
PTR)
327. #define PORTE_GPCHR PORT_GPCHR_REG(PORTE_BASE_
PTR)
328. #define PORTE_ISFR PORT_ISFR_REG(PORTE_BASE_P
TR)
329. #define PORTE_DFER PORT_DFER_REG(PORTE_BASE_P
TR)
330. #define PORTE_DFCR PORT_DFCR_REG(PORTE_BASE_P
TR)
331. #define PORTE_DFWR PORT_DFWR_REG(PORTE_BASE_P
TR) 332.
333. /* PORT - Register array accessors */
334. #define PORTA_PCR(index) PORT_PCR_REG(PORTA_BASE_PT
R,index)
335. #define PORTB_PCR(index) PORT_PCR_REG(PORTB_BASE_PT
R,index)
336. #define PORTC_PCR(index) PORT_PCR_REG(PORTC_BASE_PT
R,index)
337. #define PORTD_PCR(index) PORT_PCR_REG(PORTD_BASE_PT
R,index)
338. #define PORTE_PCR(index) PORT_PCR_REG(PORTE_BASE_PT
R,index) 339. 340. /**
341. * @}
342. */ /* end of group PORT_Register_Accessor_Macros */ 343. 344. 345. /** 346. * @}
347. */ /* end of group PORT_Peripheral */
上述代码是K60芯片的PORT模块相关头文件定义,这里结合硬件手册 K60P100M100SF2RM 对该部分代码进行简要分析。
软件结构分析:
1、“struct PORT_MemMap{ }”:端口内存映射结构体,该结构体定义了一系列“端口控制寄存器”的名称,利用结构体本身的“平坦特性”与CPU中实际的寄存器的相对地址一一对应,实现结构体变量操作对物理地址操作的映射(这里只实现了相对映射,完全映射需要有绝对地址,下面会看到)。该结构体区域中有多块保留空间,与硬件文档地址分配一致不可删除,详见K60P100M100SF2RM 文件11.4 Memory map and register definition章节。如下图所示:
2、“#define PORT_PCR_REG(base,index) ((base)->PCR[index])”:端口内存映射结构体的内部变量宏定义,主要是便于操作结构体内部变量,该宏定义接收结构体指针(首地址),返回特定变量操作符。
3、“#define PORT_PCR_PS_MASK 0x1u”:端口寄存器中的位域屏蔽码,根据硬件手册对端口中各个寄存器的各个位域进行定义,根据缩写大概能猜想出个大概,便于后期使用,详见K60P100M100SF2RM 文件11.4.1 Pin Control Register n(PORTx_PCRn),其他定义类似。如下图所示:
4、“#define PORTA_BASE_PTR ((PORT_MemMapPtr)0x40049000u)”:定义端口A寄存器组的基地址0x40049000,该CPU中对各个寄存器的配置本质上是对内存映射地址的配置。上面讲到逻辑操作对物理地址的映射问题时,指出只能实现相对映射,这里的绝对地址定义就是为实现地址绝对映射。PORT_MemMapPtr是端口寄存器组的强制类型转换,与结构体“struct PORT_MemMap{ }”共同作用,表示基地址和偏移地址,这样就能通过结构体变量来操控该寄存器组中的任意硬件寄存器,对于其他端口定义也是类似。
5、“#define PORTA_PCR0 PORT_PCR_REG(PORTA_BASE_PTR,0)”:各个端口的内部寄存器变量定义,也是为了方便后期使用,每个端口的寄存器数量可能不一致,但都与硬件寄存器配置一致。
硬件特性分析:
1、PORT模块主要是对IO端口(不仅仅限于GPIO)的功能性能进行配置,达到一些复杂的功能实现。包括:引脚中断(中断类型配置、中断打开关闭、DMA设置)、数字输入滤波(滤波开关、滤波时钟源、分辨率)、端口控制(各个引脚功能复用、上拉/下拉,电平转换斜率,驱动强度)。例如:如果引脚想实现 GPIO模块 的功能,就需要对PORT模块进行相关配置,设置引脚复用为GPIO,设置上拉\\下拉等等。