前几日购买了一款ARM+DSP+FPGA的开发板,由于之前一直做FPGA方向,对ARM也有研究。虽然找的工作是数字IC设计,纯Verilog硬件语言,也不想固步自封,把自己死掉在数字IC中,所以继续往DSP方向钻。(暂时DSP不会淘汰吧)
言归正传吧~~~DSP小白,有些地方不对,望指正!
一、外设初始化
由于硬件的时钟、DDR2的初始化都已经在GEL文件中设定,程序中不比继续做时钟等硬件的初始化,只需要对相关模块使能即可。
PSC是C6748内部的电源管理模块,通过PSCInit()函数可以完成相应功能使能;
void PSCInit(void){ // 使能 GPIO 模块 // 对相应外设模块的使能也可以在 BootLoader 中完成 PSCModuleControl(SOC_PSC_1_REGS,HW_PSC_GPIO,PSC_POWERDOMAIN_ALWAYS_ON, PSC_MDCTL_NEXT_ENABLE);}
SOC_PSC_1_REGS是PSC1的寄存器地址、HW_PSC_GPIO是GPIO使能的偏移。
二、管脚复用配置
void GPIOBank0Pin0PinMuxSetup(void){ unsigned int savePinmux = 0; savePinmux = (HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_PINMUX(1)) & ~(SYSCFG_PINMUX1_PINMUX1_31_28)); HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_PINMUX(1)) = (PINMUX1_GPIO0_0_ENABLE | savePinmux);}
HWREG是读取寄存器宏定义;SYSCFG0_PINMUX(x) 是选择复用寄存器x;
分析:savePinmux = (HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_PINMUX(1)) & ~(SYSCFG_PINMUX1_PINMUX1_31_28));
是对31~28位清零;
分析:HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_PINMUX(1)) = (PINMUX1_GPIO0_0_ENABLE | savePinmux);
#define PINMUX1_GPIO0_0_ENABLE (SYSCFG_PINMUX1_PINMUX1_31_28_GPIO0_0 << SYSCFG_PINMUX1_PINMUX1_31_28_SHIFT)
#define SYSCFG_PINMUX1_PINMUX1_31_28_GPIO0_0 (0x00000008u)
#define SYSCFG_PINMUX1_PINMUX1_31_28_SHIFT (0x0000001Cu)
是对31~28位置8h;
三、GPIO管脚初始化
void GPIOBankPinInit(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] // 底板 LED GPIODirModeSet(SOC_GPIO_0_REGS, 1, GPIO_DIR_OUTPUT); // D7 GPIO0[0] GPIODirModeSet(SOC_GPIO_0_REGS, 2, GPIO_DIR_OUTPUT); // D9 GPIO0[1] GPIODirModeSet(SOC_GPIO_0_REGS, 3, GPIO_DIR_OUTPUT); // D10 GPIO0[2] GPIODirModeSet(SOC_GPIO_0_REGS, 6, GPIO_DIR_OUTPUT); // D6 GPIO0[5] }
GPIODirModeSet的原型gpio.c文件里面定义,相关输入参数如下
void GPIOBankPinInit(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] // 底板 LED GPIODirModeSet(SOC_GPIO_0_REGS, 1, GPIO_DIR_OUTPUT); // D7 GPIO0[0] GPIODirModeSet(SOC_GPIO_0_REGS, 2, GPIO_DIR_OUTPUT); // D9 GPIO0[1] GPIODirModeSet(SOC_GPIO_0_REGS, 3, GPIO_DIR_OUTPUT); // D10 GPIO0[2] GPIODirModeSet(SOC_GPIO_0_REGS, 6, GPIO_DIR_OUTPUT); // D6 GPIO0[5] }
GPIODirModeSet的原型gpio.c文件里面定义,相关输入参数如下
/** * \brief This function configures the direction of a pin as input or output. * * \param baseAdd The memory address of the GPIO instance being used. * \param pinNumber The serial number of the GPIO pin. The 144 GPIO pins have serial numbers from 1 to 144 * \param pinDir The direction to be set for the pin. This can take the values: * 1> GPIO_DIR_INPUT, for configuring the pin as input. * 2> GPIO_DIR_OUTPUT, for configuring the pin as output. * * \return None. * * \note Here we write to the DIRn register. Writing a logic 1 configures * the pin as input and writing logic 0 as output. By default, all * the pins are set as input pins. */ void GPIODirModeSet(unsigned int baseAdd, unsigned int pinNumber, unsigned int pinDir) { unsigned int regNumber = 0; unsigned int 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操作
作为通用的GPIO既可以输出高电平也可以输出低电平。由TL6748底板的原理图可知若想点亮LED需要将控制引脚置高,熄灭LED需要将控 制引脚置低。DSP的GPIO输出的高低电平可以由不同的寄存器控制,也可以使用同一个寄存器来实现。例程中使用了同一个寄存器来控制G PIO输出的状态即:OUT_DATAn寄存器。GP0[0]的输出状态对应OUT_DATA01寄存器的第0位,对该位置1则可以在该管脚上输出高电平,反之清零该位即可在该脚上输出低电平。
GPIOPinWrite(SOC_GPIO_0_REGS, 1, GPIO_PIN_HIGH); // D7 亮 GPIO0[0]Delay(0x00FFFFFF);GPIOPinWrite(SOC_GPIO_0_REGS, 1, GPIO_PIN_LOW); // D7 灭 GPIO0[0]
GPIOPinWrite原型在gpio.c文件定义:
* \brief This function writes a logic 1 or a logic 0 to the specified pin. * * \param baseAdd The memory address of the GPIO instance being used. * \param pinNumber The serial number of the GPIO pin. * The 144 GPIO pins have serial numbers from 1 to 144. * * \param bitValue This signifies whether to write a logic 0 or logic 1 * to the specified pin.This variable can take any of the * following two values: * 1> GPIO_PIN_LOW, which indicates to clear(logic 0) the bit. * 2> GPIO_PIN_HIGH, which indicates to set(logic 1) the bit. * * \return None. * * \note The pre-requisite to write to any pin is that the pin has to * be configured as an output pin. */void GPIOPinWrite(unsigned int baseAdd, unsigned int pinNumber, unsigned int bitValue){ unsigned int regNumber = 0; unsigned int 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); } else if(GPIO_PIN_HIGH == bitValue) { HWREG(baseAdd + GPIO_SET_DATA(regNumber)) = (1 << pinOffset); }}