K60(一)端口复用问题

回顾自己之前写的LED的亮灯程序,短短的几行代码就实现了。

#include <reg52.h>
void main(void){
    P0 = 0x11;
    while(1);
}

以上代码就可以点亮与P0口相连的阴极LED了。
但是这个灯是怎么亮的呢?
关键在于头文件

void  PORT_init(PTXn_e ptxn, uint32 cfg )
{
    SIM_SCGC5 |= (SIM_SCGC5_PORTA_MASK << PTX(ptxn));                           //开启PORTx端口 1.使能PORT时钟
                                                                                //系统时钟门控寄存器控制A,B,C,D,E的时钟源
    PORT_ISFR_REG(PORTX_BASE(ptxn)) = (1<<PTn(ptxn));                           // 清空标志位 2.清空中断标志位

    PORT_PCR_REG(PORTX_BASE(ptxn), PTn(ptxn)) = cfg;                            // 复用功能 实现中断触发方式,带无源滤波器,复用功能口,上拉或下拉电阻 3.配置port的各种属性
}

程序分析:
SIM_SCGC5的宏定义为:

typedef struct SIM_MemMap {
  uint32_t SOPT1;                          /**< System Options Register 1, offset: 0x0 */
  uint32_t SOPT1CFG;                       /**< SOPT1 Configuration Register, offset: 0x4 */
  uint8_t RESERVED_0[4092];
  uint32_t SOPT2;                           /**< System Options Register 2, offset: 0x1004 */
  uint8_t RESERVED_1[4];
  uint32_t SOPT4;                           /**< System Options Register 4, offset: 0x100C */
  uint32_t SOPT5;                           /**< System Options Register 5, offset: 0x1010 */
  uint8_t RESERVED_2[4];
  uint32_t SOPT7;                           /**< System Options Register 7, offset: 0x1018 */
  uint8_t RESERVED_3[8];
  uint32_t SDID;                        /**< System Device Identification Register, offset: 0x1024 */
  uint8_t RESERVED_4[12];
  uint32_t SCGC4;            /**< System Clock Gating Control Register 4, offset: 0x1034 */
  uint32_t SCGC5;    /**< System Clock Gating Control Register 5, offset: 0x1038 偏移量直接偏到SCGC5*/
  uint32_t SCGC6;     /**< System Clock Gating Control Register 6, offset: 0x103C */
  uint32_t SCGC7;     /**< System Clock Gating Control Register 7, offset: 0x1040 */
  uint32_t CLKDIV1;          /**< System Clock Divider Register 1, offset: 0x1044 */
  uint8_t RESERVED_5[4];
  uint32_t FCFG1;                /**< Flash Configuration Register 1, offset: 0x104C */
  uint32_t FCFG2;           /**< Flash Configuration Register 2, offset: 0x1050 */
  uint8_t RESERVED_6[4];
  uint32_t UIDMH;          /**< Unique Identification Register Mid-High, offset: 0x1058 */
  uint32_t UIDML;           /**< Unique Identification Register Mid Low, offset: 0x105C */
  uint32_t UIDL;               /**< Unique Identification Register Low, offset: 0x1060 */
  uint8_t RESERVED_7[156];
  uint32_t COPC;                     /**< COP Control Register, offset: 0x1100 */
  uint32_t SRVCOP;                   /**< Service COP Register, offset: 0x1104 */
} volatile *SIM_MemMapPtr;
//这个结构体内保存的是SIM存储映射的各个寄存器的名称和地址,地址是通过结构体指针的偏移来决定,后面的注释表明里地址偏移量

#define SIM_BASE_PTR  ((SIM_MemMapPtr)0x40047000u)  //SIM模块的绝对地址 0x4004 7000u
//其中(SIM_MemMapPtr)为一个结构体指针,这个结构体的绝对地址为0x4004 7000u
//因为地址总线为32根,所以用8位的16进制数来代表32位2进制,数据类型为unsigned int
#define SIM_SCGC5_REG(base)                      ((base)->SCGC5) //这里的BASE指的是SIM模块的绝对地址,在结//构体中SCGC5代表偏移量0x1038,直接偏移到SCG5寄存器上
uint32_t SCGC5;       /**< System Clock Gating Control Register 5, offset: 0x1038 偏移量直接偏到SCGC5*/
#define SIM_SCGC5     SIM_SCGC5_REG(SIM_BASE_PTR) //括号里为SIM的绝对地址,这里指的是SCG5寄存器的内存位置0x4004 8038

后面的还是不大懂

二:PORT的中断复位函数:
1.进行port端口复用
2.写入中断号
3.根据中断标志位判断对应引脚是否进入中断
4.写1清除对应引脚的中断标志位
5.执行处理函数
具体实现:

port_init(PTC9, ALT1 | IRQ_FALLING | PULLUP );                      //初始化 PTC9 管脚,复用功能为GPIO ,下降沿触发中断,上拉电阻
set_vector_handler(PORTC_PORTD_VECTORn ,PORTC_PORTD_IRQHandler);    //设置PORTC和PORTD的中断服务函数为 PORTC_PORTD_IRQHandler
enable_irq (PORTC_PORTD_IRQn);    //使能

void PORTC_PORTD_IRQHandler(void)
{

#if 0 // 条件编译,两种方法可供选择

    uint8  n = 0;    //引脚号
    n = 9;
    if(PORTC_ISFR & (1 << n))           //PTC9 触发中断
    {
        PORTC_ISFR  = (1 << n);        //写1清中断标志位

        /* 以下为用户任务 */

        /* 以上为用户任务 */
    }
#else
    PORT_FUNC(C,9,key_handler);
#endif
}

你可能感兴趣的:(回顾,库)