恩智浦 龙邱K66 LED例程20.01.15

恩智浦 龙邱K66 LED例程

  1. 宏定义
    PORTx_PCRn:
    SIM_SCGC5:

    #define PTX(PTX_n)  (PTX_n>>5)  //获取模块号 PTX_n/32 //内联函数PTX() 输出端口号 如PTB=1
    #define PTn(PTX_n)  (PTX_n&0x1f)//获取引脚号 PTX_n%32 //输出引脚号 如PTD2=2,PTE9=9
    #define SIM_BASE                                 (0x40047000u)	//对应SIM寄存器的首地址SIM_SOPT1
    #define SIM                                      ((SIM_Type *)SIM_BASE)	//SIM_Type结构体类型的指针 对应地址是SIM_BASE
    #define   __I     volatile             /*!< defines 'read only' permissions                 */ //volatile读取变量的地址所对应的值
    #define   __I     volatile const       /*!< defines 'read only' permissions                 */
    #define     __O     volatile             /*!< defines 'write only' permissions                */
    #define     __IO    volatile             /*!< defines 'read / write' permissions              */
    #define SIM_SCGC5_PORTA_MASK                     0x200u	//对应PORTA地址 ‭0010 0000 0000‬
    #define PORT_PCR_MUX_MASK                        0x700u	//对应PCR地址的MUX	‭0111 0000 0000‬
    #define PORT_PCR_MUX_SHIFT                       8	//1 0000
    #define PORT_PCR_MUX(x)                          (((uint32_t)(((uint32_t)(x))<<PORT_PCR_MUX_SHIFT))&PORT_PCR_MUX_MASK)//把x变为32位 左移8位得MUX00x 其他位置零 (000禁用 001GPIO)
  2. 初始化全局变量、枚举与结构体(请自行查找文档)
    GPIO_MemMapPtr GPIOX[5] = {PTA_BASE_PTR, PTB_BASE_PTR, PTC_BASE_PTR, PTD_BASE_PTR, PTE_BASE_PTR}; //GPIO寄存器指针
    PORT_MemMapPtr PORTX[5] = {PORTA_BASE_PTR, PORTB_BASE_PTR, PORTC_BASE_PTR, PORTD_BASE_PTR, PORTE_BASE_PTR};//PORT寄存器指针
    
    typedef enum//枚举从0开始赋值,如PTA0=0,PTB0=32,各端口占用32位
    {
        /*  PTA端口    */ //0~31
        PTA0,  PTA1,  PTA2,  PTA3,  PTA4,  PTA5,  PTA6,  PTA7,  PTA8,  PTA9,  PTA10, PTA11, PTA12, PTA13, PTA14, PTA15,
        PTA16, PTA17, PTA18, PTA19, PTA20, PTA21, PTA22, PTA23, PTA24, PTA25, PTA26, PTA27, PTA28, PTA29, PTA30, PTA31,
    
        /*  PTB端口    */ //32~63
        PTB0,  PTB1,  PTB2,  PTB3,  PTB4,  PTB5,  PTB6,  PTB7,  PTB8,  PTB9,  PTB10, PTB11, PTB12, PTB13, PTB14, PTB15,
        PTB16, PTB17, PTB18, PTB19, PTB20, PTB21, PTB22, PTB23, PTB24, PTB25, PTB26, PTB27, PTB28, PTB29, PTB30, PTB31,
    
        /*  PTC端口    */
        PTC0,  PTC1,  PTC2,  PTC3,  PTC4,  PTC5,  PTC6,  PTC7,  PTC8,  PTC9,  PTC10, PTC11, PTC12, PTC13, PTC14, PTC15,
        PTC16, PTC17, PTC18, PTC19, PTC20, PTC21, PTC22, PTC23, PTC24, PTC25, PTC26, PTC27, PTC28, PTC29, PTC30, PTC31,
    
        /*  PTD端口    */
        PTD0,  PTD1,  PTD2,  PTD3,  PTD4,  PTD5,  PTD6,  PTD7,  PTD8,  PTD9,  PTD10, PTD11, PTD12, PTD13, PTD14, PTD15,
        PTD16, PTD17, PTD18, PTD19, PTD20, PTD21, PTD22, PTD23, PTD24, PTD25, PTD26, PTD27, PTD28, PTD29, PTD30, PTD31,
    
        /*  PTE端口    */
        PTE0,  PTE1,  PTE2,  PTE3,  PTE4,  PTE5,  PTE6,  PTE7,  PTE8,  PTE9,  PTE10, PTE11, PTE12, PTE13, PTE14, PTE15,
        PTE16, PTE17, PTE18, PTE19, PTE20, PTE21, PTE22, PTE23, PTE24, PTE25, PTE26, PTE27, PTE28, PTE29, PTE30, PTE31,
    } PTXn_e;
    typedef enum GPIO_CFG
    {
        //这里的值不能改!!!
        GPI         = 0,                          //定义管脚输入方向      GPIOx_PDDRn里,0表示输入,1表示输出
        GPO         = 1,                          //定义管脚输出方向	
    
        GPI_DOWN    = 0x02,                       //输入下拉              PORTx_PCRn需要PE=1,PS=0
        GPI_UP      = 0x03,                       //输入上拉              PORTx_PCRn需要PE=1,PS=1
        GPI_PF      = 0x10,                       //输入,带无源滤波器	0b10000	Passive Filter Enable	//PFE
        GPI_DOWN_PF = GPI_DOWN | GPI_PF ,         //输入下拉,带无源滤波器
        GPI_UP_PF   = GPI_UP   | GPI_PF ,         //输入上拉,带无源滤波器
    
        GPO_HDS     = 0x41,                        //输出高驱动能力   0b100 0001    High drive strength	//DSE
        GPO_SSR     = 0x05,                        //输出慢变化率          0b101     Slow slew rate	//SRE
        GPO_HDS_SSR = GPO_HDS | GPO_SSR,           //输出高驱动能力、慢变化率
    } GPIO_CFG;  //最低位为0,肯定是输入;GPI_UP 和 GPI_UP_PF的最低位为1,其他为输出
    /** SIM - Register Layout Typedef */
    typedef struct {
      __IO uint32_t SOPT1;                             /**< System Options Register 1, offset: 0x0 */
      __IO uint32_t SOPT1CFG;                          /**< SOPT1 Configuration Register, offset: 0x4 */
      __IO uint32_t USBPHYCTL;                         /**< USB PHY Control Register, offset: 0x8 */
           uint8_t RESERVED_0[4088];
      __IO uint32_t SOPT2;                             /**< System Options Register 2, offset: 0x1004 */
           uint8_t RESERVED_1[4];
      __IO uint32_t SOPT4;                             /**< System Options Register 4, offset: 0x100C */
      __IO uint32_t SOPT5;                             /**< System Options Register 5, offset: 0x1010 */
           uint8_t RESERVED_2[4];
      __IO uint32_t SOPT7;                             /**< System Options Register 7, offset: 0x1018 */
      __IO uint32_t SOPT8;                             /**< System Options Register 8, offset: 0x101C */
      __IO uint32_t SOPT9;                             /**< System Options Register 9, offset: 0x1020 */
      __I  uint32_t SDID;                              /**< System Device Identification Register, offset: 0x1024 */
      __IO uint32_t SCGC1;                             /**< System Clock Gating Control Register 1, offset: 0x1028 */
      __IO uint32_t SCGC2;                             /**< System Clock Gating Control Register 2, offset: 0x102C */
      __IO uint32_t SCGC3;                             /**< System Clock Gating Control Register 3, offset: 0x1030 */
      __IO uint32_t SCGC4;                             /**< System Clock Gating Control Register 4, offset: 0x1034 */
      __IO uint32_t SCGC5;                             /**< System Clock Gating Control Register 5, offset: 0x1038 */
      __IO uint32_t SCGC6;                             /**< System Clock Gating Control Register 6, offset: 0x103C */
      __IO uint32_t SCGC7;                             /**< System Clock Gating Control Register 7, offset: 0x1040 */
      __IO uint32_t CLKDIV1;                           /**< System Clock Divider Register 1, offset: 0x1044 */
      __IO uint32_t CLKDIV2;                           /**< System Clock Divider Register 2, offset: 0x1048 */
      __IO uint32_t FCFG1;                             /**< Flash Configuration Register 1, offset: 0x104C */
      __I  uint32_t FCFG2;                             /**< Flash Configuration Register 2, offset: 0x1050 */
      __I  uint32_t UIDH;                              /**< Unique Identification Register High, offset: 0x1054 */
      __I  uint32_t UIDMH;                             /**< Unique Identification Register Mid-High, offset: 0x1058 */
      __I  uint32_t UIDML;                             /**< Unique Identification Register Mid Low, offset: 0x105C */
      __I  uint32_t UIDL;                              /**< Unique Identification Register Low, offset: 0x1060 */
      __IO uint32_t CLKDIV3;                           /**< System Clock Divider Register 3, offset: 0x1064 */
      __IO uint32_t CLKDIV4;                           /**< System Clock Divider Register 4, offset: 0x1068 */
    } SIM_Type, *SIM_MemMapPtr;//将SIM寄存器 存于 SIM_TYPE结构体
    /** PORT - Register Layout Typedef */
    typedef struct {
      __IO uint32_t PCR[32];                           /**< Pin Control Register n, array offset: 0x0, array step: 0x4 */
      __O  uint32_t GPCLR;                             /**< Global Pin Control Low Register, offset: 0x80 */
      __O  uint32_t GPCHR;                             /**< Global Pin Control High Register, offset: 0x84 */
           uint8_t RESERVED_0[24];
      __IO uint32_t ISFR;                              /**< Interrupt Status Flag Register, offset: 0xA0 */
           uint8_t RESERVED_1[28];
      __IO uint32_t DFER;                              /**< Digital Filter Enable Register, offset: 0xC0 */
      __IO uint32_t DFCR;                              /**< Digital Filter Clock Register, offset: 0xC4 */
      __IO uint32_t DFWR;                              /**< Digital Filter Width Register, offset: 0xC8 */
    } PORT_Type, *PORT_MemMapPtr;
    /** GPIO - Register Layout Typedef */
    typedef struct GPIO_MemMap
    {
        union
        {
            uint32_t PDOR;                                   /**< Port Data Output Register, offset: 0x0 */
            struct                                            // 用于直接赋值位的   ——by
            {
                u32 PDOR0 : 1;
                u32 PDOR1: 1;
                u32 PDOR2 : 1;
                u32 PDOR3 : 1;
                u32 PDOR4 : 1;
                u32 PDOR5 : 1;
                u32 PDOR6 : 1;
                u32 PDOR7 : 1;
                u32 PDOR8 : 1;
                u32 PDOR9 : 1;
                u32 PDOR10: 1;
                u32 PDOR11: 1;
                u32 PDOR12: 1;
                u32 PDOR13: 1;
                u32 PDOR14: 1;
                u32 PDOR15: 1;
                u32 PDOR16: 1;
                u32 PDOR17: 1;
                u32 PDOR18: 1;
                u32 PDOR19: 1;
                u32 PDOR20: 1;
                u32 PDOR21: 1;
                u32 PDOR22: 1;
                u32 PDOR23: 1;
                u32 PDOR24: 1;
                u32 PDOR25: 1;
                u32 PDOR26: 1;
                u32 PDOR27: 1;
                u32 PDOR28: 1;
                u32 PDOR29: 1;
                u32 PDOR30: 1;
                u32 PDOR31: 1;
            } PDORs;
            struct                                            // 用于直接赋值位的   ——by
            {
                u8 Byte0;
                u8 Byte1;
                u8 Byte2;
                u8 Byte3;
            } PDORByte;
            struct                                            // 用于直接赋值位的   ——by
            {
                u16 Word0;
                u16 Word1;
            } PDORWord;
        };
    
        uint32_t PSOR;                                   /**< Port Set Output Register, offset: 0x4 */
        uint32_t PCOR;                                   /**< Port Clear Output Register, offset: 0x8 */
        uint32_t PTOR;                                   /**< Port Toggle Output Register, offset: 0xC */
    
        union
        {
            uint32_t PDIR;                                   /**< Port Data Input Register, offset: 0x10 */
            struct                                            // 用于直接赋值位的   ——by
            {
                u32 PDIR0 : 1;
                u32 PDIR1: 1;
                u32 PDIR2 : 1;
                u32 PDIR3 : 1;
                u32 PDIR4 : 1;
                u32 PDIR5 : 1;
                u32 PDIR6 : 1;
                u32 PDIR7 : 1;
                u32 PDIR8 : 1;
                u32 PDIR9 : 1;
                u32 PDIR10: 1;
                u32 PDIR11: 1;
                u32 PDIR12: 1;
                u32 PDIR13: 1;
                u32 PDIR14: 1;
                u32 PDIR15: 1;
                u32 PDIR16: 1;
                u32 PDIR17: 1;
                u32 PDIR18: 1;
                u32 PDIR19: 1;
                u32 PDIR20: 1;
                u32 PDIR21: 1;
                u32 PDIR22: 1;
                u32 PDIR23: 1;
                u32 PDIR24: 1;
                u32 PDIR25: 1;
                u32 PDIR26: 1;
                u32 PDIR27: 1;
                u32 PDIR28: 1;
                u32 PDIR29: 1;
                u32 PDIR30: 1;
                u32 PDIR31: 1;
            } PDIRs;
            struct                                            // 用于直接赋值位的   ——by
            {
                u8 Byte0;
                u8 Byte1;
                u8 Byte2;
                u8 Byte3;
            } PDIRByte;
            struct                                            // 用于直接赋值位的   ——by
            {
                u16 Word0;
                u16 Word1;
            } PDIRWord;
        };
    
        union
        {
            uint32_t PDDR;                                   /**< Port Data Direction Register, offset: 0x14 */
            struct                                            // 用于直接赋值位的   ——by
            {
                u32 DDR0 : 1;
                u32 DDR1: 1;
                u32 DDR2 : 1;
                u32 DDR3 : 1;
                u32 DDR4 : 1;
                u32 DDR5 : 1;
                u32 DDR6 : 1;
                u32 DDR7 : 1;
                u32 DDR8 : 1;
                u32 DDR9 : 1;
                u32 DDR10: 1;
                u32 DDR11: 1;
                u32 DDR12: 1;
                u32 DDR13: 1;
                u32 DDR14: 1;
                u32 DDR15: 1;
                u32 DDR16: 1;
                u32 DDR17: 1;
                u32 DDR18: 1;
                u32 DDR19: 1;
                u32 DDR20: 1;
                u32 DDR21: 1;
                u32 DDR22: 1;
                u32 DDR23: 1;
                u32 DDR24: 1;
                u32 DDR25: 1;
                u32 DDR26: 1;
                u32 DDR27: 1;
                u32 DDR28: 1;
                u32 DDR29: 1;
                u32 DDR30: 1;
                u32 DDR31: 1;
            } DDRs;
            struct                                            // 用于直接赋值位的   ——by
            {
                u8 Byte0;
                u8 Byte1;
                u8 Byte2;
                u8 Byte3;
            } DDRByte;
            struct                                            // 用于直接赋值位的   ——by
            {
                u16 Word0;
                u16 Word1;
            } DDRWord;
        };
    
    } volatile GPIO_Type,*GPIO_MemMapPtr;
  3. 系统函数
    GPIOx_PDDR GPIOx_PDOR原理图

    /*------------------------------------------------------------------------------------------------------
    【函    数】GPIO_Init
    【功    能】初始化GPIO 并配置GPIO模式
    【参    数】ptx_n : 要初始化的GPIO, 在common.h中定义
    【参    数】dir   : GPIO方向和配置, 具体在GPIO.h中
    【参    数】data  : GPIO默认状态  1:高电平  0:低电平
    【返 回 值】无
    【实    例】GPIO_Init(PTA17, GPO, 1); //设置PTA17为输出模式 并设置为高电平
    【注意事项】
    --------------------------------------------------------------------------------------------------------*/
    void GPIO_PinInit(PTXn_e ptx_n, GPIO_CFG dir, uint8_t data)
    {
      
        uint8_t ptx,ptn;
        
        ptx = PTX(ptx_n);	//计算端口号
        ptn = PTn(ptx_n);	//计算引脚号
        
        /* 使能端口时钟 */
      SIM->SCGC5 |= (SIM_SCGC5_PORTA_MASK << ptx); //启用SCGC5时钟 ptx对应PORT A-E
        
        /* 清除之前的复用功能 */
        PORTX[ptx]->PCR[ptn] &= ~(uint32)PORT_PCR_MUX_MASK; //全部清零
        
        /* 设置复用功能为GPIO即普通IO口 */
        PORTX[ptx]->PCR[ptn] |= PORT_PCR_MUX(1);	//MUX=001
        
        /* 配置GPIO模式 */
        PORTX[ptx]->PCR[ptn] |= dir;	//GPIO方向
    
        /* 设置GPIO方向 */
        if(dir)	//0表示输入,1表示输出
        {
            GPIOX[ptx]->PDDR |= (uint32)(1<<ptn);	//对应引脚置1
        }
        else  
        {
            GPIOX[ptx]->PDDR &= ~(uint32)(1<<ptn);	//对应引脚置0
        }
     
        /* 设置端口默认状态 */
        if(data) //3.3V->PN->GPIO 所以0表示亮,1表示灭
        {
            GPIOX[ptx]->PDOR |=  (uint32)(1<<ptn);	//对应引脚置1
        }	
        else 
        {
            GPIOX[ptx]->PDOR &= ~(uint32)(1<<ptn);	//对应引脚置0
        }
    }
  4. 功能函数
    /*------------------------------------------------------------------------------------------------------
    【函    数】LED_Init
    【功    能】初始化核心板和母板上的LED
    【参    数】无
    【返 回 值】无
    【实    例】LED_Init(); //初始化LED
    【注意事项】
    --------------------------------------------------------------------------------------------------------*/
    void LED_Init(void)	//灯全灭
    {
        /* 初始化核心板上的LED */
       GPIO_PinInit(PTA17, GPO, 1);	
       GPIO_PinInit(PTC0 , GPO, 1);
       GPIO_PinInit(PTD15, GPO, 1);
       GPIO_PinInit(PTE26, GPO, 1);
       
       /* 初始化母板上的LED */
       GPIO_PinInit(PTC18, GPO, 1);
       GPIO_PinInit(PTC19, GPO, 1);
    }
    
    /*------------------------------------------------------------------------------------------------------
    【函    数】LED_ON
    【功    能】开灯
    【参    数】led   :  LED号
    【返 回 值】无
    【实    例】LED_ON(1); //开LED
    【注意事项】
    --------------------------------------------------------------------------------------------------------*/
    void LED_ON(uint8_t led)	//对应灯亮
    {
        switch(led)
        {
          case 0:
            GPIO_PinInit(PTA17, GPO, 0);
            break;
            
          case 1:
            GPIO_PinInit(PTC0 , GPO, 0);
            break;
            
          case 2:
            GPIO_PinInit(PTD15, GPO, 0);
            break;
            
          case 3:
            GPIO_PinInit(PTE26, GPO, 0);
            break;
            
          case 4:
            GPIO_PinInit(PTC18, GPO, 0);
            break;
            
          case 5:
            GPIO_PinInit(PTC19, GPO, 0);
            break;
            
          default:
            break;
        }
    }
    
    
    /*------------------------------------------------------------------------------------------------------
    【函    数】LED_OFF
    【功    能】关灯
    【参    数】led   :  LED号
    【返 回 值】无
    【实    例】LED_OFF(1); //关LED
    【注意事项】
    --------------------------------------------------------------------------------------------------------*/
    void LED_OFF(uint8_t led)	//对应灯灭
    {
    
        switch(led)
        {
          case 0:
            GPIO_PinInit(PTA17, GPO, 1);
            break;
            
          case 1:
            GPIO_PinInit(PTC0 , GPO, 1);
            break;
            
          case 2:
            GPIO_PinInit(PTD15, GPO, 1);
            break;
            
          case 3:
            GPIO_PinInit(PTE26, GPO, 1);
            break;
            
          case 4:
            GPIO_PinInit(PTC18, GPO, 1);
            break;
            
          case 5:
            GPIO_PinInit(PTC19, GPO, 1);
            break;
            
          default:
            break;
        }
    }
    /*------------------------------------------------------------------------------------------------------
    【函    数】LED_Reverse
    【功    能】翻转LED
    【参    数】led   :  LED号
    【返 回 值】无
    【实    例】LED_Reverse(1); //翻转LED
    【注意事项】
    --------------------------------------------------------------------------------------------------------*/
    void LED_Reverse(uint8_t led)	//对应灯翻转
    {
        /* 记录LED状态 */
        static uint8_t led_state[6];
        led_state[led]++;
        
        if(0 == led_state[led]%2)
        {
            LED_ON(led);
        }
        else
        {
            LED_OFF(led);
        }
    }
    
    /*------------------------------------------------------------------------------------------------------
    【函    数】LED_Test
    【功    能】翻转LED
    【参    数】led   :  LED号
    【返 回 值】无
    【实    例】LED_Test(); //测试LED
    【注意事项】
    --------------------------------------------------------------------------------------------------------*/
    void Test_LED(void)
    {
        LED_Init();
        while(1)
        {
            LED_ON(0);
            LED_OFF(1);
            LED_OFF(2);
            LED_OFF(3);
            delayms(100);
            
            LED_OFF(0);
            LED_ON(1);
            LED_OFF(2);
            LED_OFF(3);
            delayms(100);
            
            LED_OFF(0);
            LED_OFF(1);
            LED_ON(2);
            LED_OFF(3);
            delayms(100);
            
            LED_OFF(0);
            LED_OFF(1);
            LED_OFF(2);
            LED_ON(3);
            delayms(100);
            
            LED_Reverse(4);
            LED_Reverse(5);
        }
    }

     

 

 

发表评论

电子邮件地址不会被公开。 必填项已用*标注