|
http://blog.csdn.net/zengaliang/article/details/78705019 1.主函數(shù)流程
此程序的作用是實現(xiàn)不可屏蔽中斷功能。NMI(NonMaskableInterrupt)——不可屏蔽中斷(即CPU不能屏蔽),無論狀態(tài)寄存器中IF位的狀態(tài)如何,CPU收到有效的NMI必須進(jìn)行響應(yīng)。主函數(shù)如下: intmain(void) { // 外設(shè)使能配置 PSCInit();
// GPIO 管腳復(fù)用配置 GPIOBankPinMuxSet();
// DSP 中斷初始化 InterruptInit();
// GPIO 管腳初始化 GPIOBankPinInit();
// 主循環(huán) for(;;) {
} }
2.外設(shè)使能配置
函數(shù)首先在PSC模塊中使能外設(shè),這里是GPIO模塊。外設(shè)使能配置函數(shù)PSCInit如下: voidPSCInit(void) { // 使能 GPIO 模塊 // 對相應(yīng)外設(shè)模塊的使能也可以在 BootLoader 中完成 PSCModuleControl(SOC_PSC_1_REGS, HW_PSC_GPIO, PSC_POWERDOMAIN_ALWAYS_ON, PSC_MDCTL_NEXT_ENABLE); } 函數(shù)在PSC中使能HW_PSC_GPIO(#3)模塊,該模塊的Power Domain是ALWAYS_ON域(POWER DOMAIN 0),PSCModuleControl細(xì)節(jié)可參考這里: (指南P163)
3.GPIO管腳復(fù)用配置
GPIO管腳復(fù)用配置函數(shù)如下: voidGPIOBankPinMuxSet(void) { // 配置相應(yīng)的 GPIO 口功能為普通輸入輸出口 // 核心板 LED GPIOBank6Pin12PinMuxSetup(); GPIOBank6Pin13PinMuxSetup(); } GPIOBank6Pin12PinMuxSetup函數(shù)和GPIOBank6Pin13PinMuxSetup函數(shù)將GPIO[12]和GPIO[13]這兩個引腳設(shè)為普通輸入輸出口(即GPIO口)。這兩個函數(shù)在demo\StarterWare\Application\Platform工程下的GPIO.c文件中,GPIOBank6Pin12PinMuxSetup函數(shù)如下: voidGPIOBank6Pin12PinMuxSetup(void) { unsignedint savePinmux =0;
savePinmux = (HWREG(SOC_SYSCFG_0_REGS +SYSCFG0_PINMUX(13)) & ~(SYSCFG_PINMUX13_PINMUX13_15_12));
HWREG(SOC_SYSCFG_0_REGS +SYSCFG0_PINMUX(13)) = (PINMUX13_GPIO6_12_ENABLE | savePinmux); } GPIOBank6Pin13PinMuxSetup函數(shù)如下: voidGPIOBank6Pin13PinMuxSetup(void) { unsignedint savePinmux =0;
savePinmux = (HWREG(SOC_SYSCFG_0_REGS +SYSCFG0_PINMUX(13)) & ~(SYSCFG_PINMUX13_PINMUX13_11_8));
HWREG(SOC_SYSCFG_0_REGS +SYSCFG0_PINMUX(13)) = (PINMUX13_GPIO6_13_ENABLE | savePinmux); }
4.DSP中斷初始化
DSP中斷初始化函數(shù)InterruptInit如下: voidInterruptInit(void) { // 初始化 DSP 中斷控制器 IntDSPINTCInit();
// 注冊中斷服務(wù)函數(shù) IntRegister(C674X_MASK_NMI, NMIIsr); } 該函數(shù)中,首先初始化DSP中斷控制器,IntDSPINTCInit函數(shù)細(xì)節(jié)見這篇博文: 然后,程序?qū)PU不可屏蔽中斷C674X_MASK_NMI(#1)的中斷服務(wù)函數(shù)注冊為NMIIsr函數(shù)。IntRegister函數(shù)參考這里: C6748_EDMA_GPIO_中斷學(xué)習(xí)筆記
(指南P27) (Megamodule手冊P167)
5.GPIO管腳初始化
GPIO管腳初始化函數(shù)GPIOBankPinInit如下: voidGPIOBankPinInit(void) { // 配置 LED 對應(yīng)管腳為輸出管腳 // OMAPL138 及 DSP C6748 共有 144 個 GPIO // 以下為各組 GPIO BANK 起始管腳對應(yīng)值 // 范圍 1-144 // GPIO0[0] 1 // GPIO1[0] 17 // GPIO2[0] 33 // GPIO3[0] 49 // GPIO4[0] 65 // GPIO5[0] 81 // GPIO6[0] 97 // GPIO7[0] 113 // GPIO8[0] 129
// 核心板 LED GPIODirModeSet(SOC_GPIO_0_REGS, 109, GPIO_DIR_OUTPUT); // GPIO6[12] GPIODirModeSet(SOC_GPIO_0_REGS, 110, GPIO_DIR_OUTPUT); // GPIO6[13] } 該函數(shù)將GPIO6[12]腳和GPIO6[13]腳方向設(shè)為輸出,GPIODirModeSet函數(shù)如下: voidGPIODirModeSet(unsignedint baseAdd, unsignedint pinNumber, unsignedint pinDir)
{ unsignedint regNumber =0; unsignedint pinOffset =0;
/* ** Each register contains settings for each pin of two banks. The 32 bits ** represent 16 pins each from the banks. Thus the register number must be ** calculated based on 32 pins boundary. */ regNumber = (pinNumber -1)/32;
/* ** In every register the least significant bits starts with a GPIO number on ** a boundary of 32. Thus the pin offset must be calculated based on 32 ** pins boundary. Ex: 'pinNumber' of 1 corresponds to bit 0 in ** 'register_name01'. */ pinOffset = (pinNumber -1) %32;
if(GPIO_DIR_OUTPUT == pinDir) { HWREG(baseAdd +GPIO_DIR(regNumber)) &=~(1<< pinOffset); } else { HWREG(baseAdd +GPIO_DIR(regNumber)) |= (1<< pinOffset); } } 該函數(shù)設(shè)置GPIO_DIRn寄存器,從而配置GPIO引腳的輸入輸出方向。
6.中斷服務(wù)函數(shù)
中斷服務(wù)函數(shù)如下: #pragmaNMI_INTERRUPT(NMIIsr) voidNMIIsr(void) { GPIOPinWrite(SOC_GPIO_0_REGS, 109, Flag); // 翻轉(zhuǎn)標(biāo)志位 Flag=!Flag; GPIOPinWrite(SOC_GPIO_0_REGS, 110, Flag); }
其中,第一條語句為Pragma預(yù)處理指令,該指令使能直接用C代碼處理不可屏蔽中斷。 (CCS幫助文檔) 在中斷服務(wù)函數(shù)中,程序?qū)崿F(xiàn)GPIO6[12]和GPIO6[13]兩個引腳的輸出翻轉(zhuǎn),GPIOPinWrite函數(shù)如下: voidGPIOPinWrite(unsignedint baseAdd, unsignedint pinNumber, unsignedint bitValue) { unsignedint regNumber =0; unsignedint pinOffset =0;
/* ** Each register contains settings for each pin of two banks. The 32 bits ** represent 16 pins each from the banks. Thus the register number must be ** calculated based on 32 pins boundary. */
regNumber = (pinNumber -1)/32;
/* ** In every register the least significant bits starts with a GPIO number on ** a boundary of 32. Thus the pin offset must be calculated based on 32 ** pins boundary. Ex: 'pinNumber' of 1 corresponds to bit 0 in ** 'register_name01'. */
pinOffset = (pinNumber -1) %32;
if(GPIO_PIN_LOW == bitValue) { HWREG(baseAdd +GPIO_CLR_DATA(regNumber)) = (1<< pinOffset); } elseif(GPIO_PIN_HIGH == bitValue) { HWREG(baseAdd +GPIO_SET_DATA(regNumber)) = (1<< pinOffset); } } 函數(shù)根據(jù)要輸出的電平是高還是低,往GPIO_CLR_DATA寄存器和GPIO_SET_DATA寄存器的相應(yīng)位寫1,如果輸出的是低電平,則往GPIO_CLR_DATA寄存器的相應(yīng)位寫1;如果輸出的是高電平,則往GPIO_SET_DATA寄存器的相應(yīng)位寫1。 (指南P853) (指南P854) (指南P855)
(指南P856) |
|
|