[TMS320C674x] 一、GPIO认识

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

  

 

posted @ 2015-11-07 22:31  疯玩TGB  阅读(945)  评论(0编辑  收藏  举报