http://blog.csdn.net/zengaliang/article/details/78705019
1.主函数流程

此程序的作用是实现不可屏蔽中断功能。NMI(NonMaskableInterrupt)——不可屏蔽中断(即CPU不能屏蔽),无论状态寄存器中IF位的状态如何,CPU收到有效的NMI必须进行响应。主函数如下:
intmain(void)
{
//
外设使能配置
PSCInit();
// GPIO
管脚复用配置
GPIOBankPinMuxSet();
// DSP
中断初始化
InterruptInit();
// GPIO
管脚初始化
GPIOBankPinInit();
//
主循环
for(;;)
{
}
}
2.外设使能配置
函数首先在PSC模块中使能外设,这里是GPIO模块。外设使能配置函数PSCInit如下:
voidPSCInit(void)
{
//
使能 GPIO
模块
//
对相应外设模块的使能也可以在 BootLoader
中完成
PSCModuleControl(SOC_PSC_1_REGS, HW_PSC_GPIO, PSC_POWERDOMAIN_ALWAYS_ON, PSC_MDCTL_NEXT_ENABLE);
}
函数在PSC中使能HW_PSC_GPIO(#3)模块,该模块的Power Domain是ALWAYS_ON域(POWER DOMAIN 0),PSCModuleControl细节可参考这里:
C6748_UART_EDMA

(指南P163)
3.GPIO管脚复用配置
GPIO管脚复用配置函数如下:
voidGPIOBankPinMuxSet(void)
{
//
配置相应的 GPIO
口功能为普通输入输出口
//
核心板 LED
GPIOBank6Pin12PinMuxSetup();
GPIOBank6Pin13PinMuxSetup();
}
GPIOBank6Pin12PinMuxSetup函数和GPIOBank6Pin13PinMuxSetup函数将GPIO[12]和GPIO[13]这两个引脚设为普通输入输出口(即GPIO口)。这两个函数在demo\StarterWare\Application\Platform工程下的GPIO.c文件中,GPIOBank6Pin12PinMuxSetup函数如下:
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函数如下:
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中断初始化函数InterruptInit如下:
voidInterruptInit(void)
{
//
初始化 DSP
中断控制器
IntDSPINTCInit();
//
注册中断服务函数
IntRegister(C674X_MASK_NMI, NMIIsr);
}
该函数中,首先初始化DSP中断控制器,IntDSPINTCInit函数细节见这篇博文:
C6748_SPI_FLASH
然后,程序将CPU不可屏蔽中断C674X_MASK_NMI(#1)的中断服务函数注册为NMIIsr函数。IntRegister函数参考这里:
C6748_EDMA_GPIO_中断学习笔记
NMI引脚低电平有效,当该引脚输入低电平时,将会发送不可屏蔽中断(NMEVT)。

(指南P27)

(Megamodule手册P167)
5.GPIO管脚初始化
GPIO管脚初始化函数GPIOBankPinInit如下:
voidGPIOBankPinInit(void)
{
//
配置 LED
对应管脚为输出管脚
// OMAPL138
及 DSP C6748
共有 144
个 GPIO
//
以下为各组 GPIO BANK
起始管脚对应值
//
范围 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]
}
该函数将GPIO6[12]脚和GPIO6[13]脚方向设为输出,GPIODirModeSet函数如下:
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);
}
}
该函数设置GPIO_DIRn寄存器,从而配置GPIO引脚的输入输出方向。
6.中断服务函数
中断服务函数如下:
#pragmaNMI_INTERRUPT(NMIIsr)
voidNMIIsr(void)
{
GPIOPinWrite(SOC_GPIO_0_REGS,
109, Flag);
//
翻转标志位
Flag=!Flag;
GPIOPinWrite(SOC_GPIO_0_REGS,
110, Flag);
}
其中,第一条语句为Pragma预处理指令,该指令使能直接用C代码处理不可屏蔽中断。

(CCS帮助文档)
在中断服务函数中,程序实现GPIO6[12]和GPIO6[13]两个引脚的输出翻转,GPIOPinWrite函数如下:
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);
}
}
函数根据要输出的电平是高还是低,往GPIO_CLR_DATA寄存器和GPIO_SET_DATA寄存器的相应位写1,如果输出的是低电平,则往GPIO_CLR_DATA寄存器的相应位写1;如果输出的是高电平,则往GPIO_SET_DATA寄存器的相应位写1。


(指南P853)

(指南P854)

(指南P855)

(指南P856)
|