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
}
發佈了42 篇原創文章 · 獲贊 28 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章