前几日购买了一款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);
}
}