英飞凌TC275芯片使用——GPIO&LED

1,功能介绍

按下Button,LED亮,松开不亮

1.1 相关电路原理图

TC275 lite Kit这块板子有两个可以演示的LED,分别对应P00.5和P00.6这两个芯片管脚,根据电路原理图可以看出当GPIO输出低电平时,电路导通,LED被点亮;除了两个可以操作的LED,还提供了一个Button按钮,对应管脚P00.7,根据电路原理图,当按钮按下时,由于R20电阻的存在,P00.7会得到低电平,GPIO为0,当Button松开时,GPIO为1。

1.2 Port口初始化配置及相关寄存器介绍

芯片的端口引脚可以被配置成通用输出输出(GPIO)引脚,TC275有3个核,通过在core 0的主函数中调用init_GPIOs函数来配置端口引脚。

int core0_main(void)
{
    IfxCpu_enableInterrupts();

    /* !!WATCHDOG0 AND SAFETY WATCHDOG ARE DISABLED HERE!!
     * Enable the watchdogs and service them periodically if it is required
     */
    IfxScuWdt_disableCpuWatchdog(IfxScuWdt_getCpuWatchdogPassword());
    IfxScuWdt_disableSafetyWatchdog(IfxScuWdt_getSafetyWatchdogPassword());

    /* Wait for CPU sync event */
    IfxCpu_emitEvent(&g_cpuSyncEvent);
    IfxCpu_waitEvent(&g_cpuSyncEvent, 1);

    init_GPIOs();       /* Initialize port pin for push button and LED          */

    while(1)
    {
        control_LED();  /* Check the push button and set the LED accordingly    */
    }
    return (1);
}

在init_GPIOs函数中,把LED1和LED2对应的Port口设置为GPIO的输出,将Button对应的Port口配置成输出

#define LED1     &MODULE_P00,5   /* Port pin for the LED     */
#define LED2     &MODULE_P00,6   /* Port pin for the LED     */
#define BUTTON  &MODULE_P00,7   /* Port pin for the button  */

void init_GPIOs(void)
{
    /* Setup the port pin connected to the LED to general output mode push-pull. This function can be used
     * to initialize any port pin by specifying the port number, pin number and port pin mode.
     */
    IfxPort_setPinMode(LED1, IfxPort_Mode_outputPushPullGeneral);
    IfxPort_setPinMode(LED2, IfxPort_Mode_outputPushPullGeneral);

    /* Setup the port pin connected to the push button to input mode. This function can be used to initialize any
     * port to input mode by just specifying the port number as illustrated.
     */
    IfxPort_setPinMode(BUTTON, IfxPort_Mode_inputPullUp);
}

芯片的P0端口对应的首地址是0xF003A000u ,地址大小是256byte,TC275共有16组Port口,寄存器地址空间是非完全连续的。

 

从芯片手册可以看出,P00.5可以配置成GTM、ADC、GPIO等多种功能

关于Port相关的寄存器如下:

typedef volatile struct _Ifx_P
{
    Ifx_P_OUT OUT;                          /**< \brief 0, Port Output Register */
    Ifx_P_OMR OMR;                          /**< \brief 4, Port Output Modification Register */
    Ifx_P_ID ID;                            /**< \brief 8, Identification Register */
    unsigned char reserved_C[4];            /**< \brief C, \internal Reserved */
    Ifx_P_IOCR0 IOCR0;                      /**< \brief 10, Port Input/Output Control Register 0 */
    Ifx_P_IOCR4 IOCR4;                      /**< \brief 14, Port Input/Output Control Register 4 */
    Ifx_P_IOCR8 IOCR8;                      /**< \brief 18, Port Input/Output Control Register 8 */
    Ifx_P_IOCR12 IOCR12;                    /**< \brief 1C, Port Input/Output Control Register 12 */
    unsigned char reserved_20[4];           /**< \brief 20, \internal Reserved */
    Ifx_P_IN IN;                            /**< \brief 24, Port Input Register */
    unsigned char reserved_28[24];          /**< \brief 28, \internal Reserved */
    Ifx_P_PDR0 PDR0;                        /**< \brief 40, Port Pad Driver Mode 0 Register */
    Ifx_P_PDR1 PDR1;                        /**< \brief 44, Port Pad Driver Mode 1 Register */
    unsigned char reserved_48[8];           /**< \brief 48, \internal Reserved */
    Ifx_P_ESR ESR;                          /**< \brief 50, Port Emergency Stop Register */
    unsigned char reserved_54[12];          /**< \brief 54, \internal Reserved */
    Ifx_P_PDISC PDISC;                      /**< \brief 60, Port Pin Function Decision Control Register */
    Ifx_P_PCSR PCSR;                        /**< \brief 64, Port Pin Controller Select Register */
    unsigned char reserved_68[8];           /**< \brief 68, \internal Reserved */
    Ifx_P_OMSR0 OMSR0;                      /**< \brief 70, Port Output Modification Set Register 0 */
    Ifx_P_OMSR4 OMSR4;                      /**< \brief 74, Port Output Modification Set Register 4 */
    Ifx_P_OMSR8 OMSR8;                      /**< \brief 78, Port Output Modification Set Register 8 */
    Ifx_P_OMSR12 OMSR12;                    /**< \brief 7C, Port Output Modification Set Register 12 */
    Ifx_P_OMCR0 OMCR0;                      /**< \brief 80, Port Output Modification Clear Register 0 */
    Ifx_P_OMCR4 OMCR4;                      /**< \brief 84, Port Output Modification Clear Register 4 */
    Ifx_P_OMCR8 OMCR8;                      /**< \brief 88, Port Output Modification Clear Register 8 */
    Ifx_P_OMCR12 OMCR12;                    /**< \brief 8C, Port Output Modification Clear Register 12 */
    Ifx_P_OMSR OMSR;                        /**< \brief 90, Port Output Modification Set Register */
    Ifx_P_OMCR OMCR;                        /**< \brief 94, Port Output Modification Clear Register */
    unsigned char reserved_98[8];           /**< \brief 98, \internal Reserved */
    Ifx_P_LPCR0 LPCR0;                      /**< \brief A0, Port LVDS Pad Control Register 0 */
    Ifx_P_LPCR1 LPCR1;                      /**< \brief A4, Port LVDS Pad Control Register 1 */
    Ifx_P_LPCR2 LPCR2;                      /**< \brief A8, Port LVDS Pad Control Register 2 */
    unsigned char reserved_A4[76];          /**< \brief AC, \internal Reserved */
    Ifx_P_ACCEN1 ACCEN1;                    /**< \brief F8, Port Access Enable Register 1 */
    Ifx_P_ACCEN0 ACCEN0;                    /**< \brief FC, Port Access Enable Register 0 */
} Ifx_P;
/** \}  */

1.3  IfxPort_setPinMode

在初始化过程中,主要是通过IfxPort_setPinMode去配置Port口的相关寄存器实现对应功能

参数说明

  1. Ifx_P *port:指向端口控制模块的指针,详见1.2章节

  2. uint8 pinIndex:引脚索引 (0-15)

  3. IfxPort_Mode mode:引脚模式配置

  • IOCR(输入输出控制寄存器(Port Input/Output Control Registers,IOCR))

每个Port口最多有16个引脚,以P0为例,分别是P0.0~P0.15;每个Port口有四个IOCR寄存器,其中

  • IOCR0:控制引脚 0-3

  • IOCR4:控制引脚 4-7

  • IOCR8:控制引脚 8-11

  • IOCR12:控制引脚 12-15

通过iocrIndex = (pinIndex / 4);来确定使用哪个寄存器,选定IOCR寄存器后,每个Port端口具有4个IOCR寄存器,对应Pin脚关系如下:

  • Pn_IOCR0: Pn.[3:0]

  • Pn_IOCR4: Pn.[7:4]

  • Pn_IOCR8: Pn.[11:8]

  • Pn_IOCR12: Pn.[15:12]

我们以Pn_IOCR0为示例,每个IOCR有4个位域,分别对应4个pin脚,

每个位域有5个bit位,这5个bit位的不同含义如下:

/** \brief Ifx_P input / output mode definition.
 *
 * \see Ifx_P.IOCR, IfxPort_setPinMode()
 */
typedef enum
{
    IfxPort_Mode_inputNoPullDevice      = 0,      /**< \brief Input, No pull device connected. */
    IfxPort_Mode_inputPullDown          = 8U,     /**< \brief Input, pull-down device connected. */
    IfxPort_Mode_inputPullUp            = 0x10U,  /**< \brief Input, pull-up device connected. */
    IfxPort_Mode_outputPushPullGeneral  = 0x80U,  /**< \brief Push-pull, General-purpose output */
    IfxPort_Mode_outputPushPullAlt1     = 0x88U,  /**< \brief Push-pull, Alternate output function 1. */
    IfxPort_Mode_outputPushPullAlt2     = 0x90U,  /**< \brief Push-pull, Alternate output function 2. */
    IfxPort_Mode_outputPushPullAlt3     = 0x98U,  /**< \brief Push-pull, Alternate output function 3. */
    IfxPort_Mode_outputPushPullAlt4     = 0xA0U,  /**< \brief Push-pull, Alternate output function 4. */
    IfxPort_Mode_outputPushPullAlt5     = 0xA8U,  /**< \brief Push-pull, Alternate output function 5. */
    IfxPort_Mode_outputPushPullAlt6     = 0xB0U,  /**< \brief Push-pull, Alternate output function 6. */
    IfxPort_Mode_outputPushPullAlt7     = 0xB8U,  /**< \brief Push-pull, Alternate output function 7. */
    IfxPort_Mode_outputOpenDrainGeneral = 0xC0U,  /**< \brief Open-drain, General-purpose output. */
    IfxPort_Mode_outputOpenDrainAlt1    = 0xC8U,  /**< \brief Open-drain, Alternate output function 1. */
    IfxPort_Mode_outputOpenDrainAlt2    = 0xD0U,  /**< \brief Open-drain, Alternate output function 2. */
    IfxPort_Mode_outputOpenDrainAlt3    = 0xD8U,  /**< \brief Open-drain, Alternate output function 3. */
    IfxPort_Mode_outputOpenDrainAlt4    = 0xE0U,  /**< \brief Open-drain, Alternate output function 4. */
    IfxPort_Mode_outputOpenDrainAlt5    = 0xE8U,  /**< \brief Open-drain, Alternate output function 5. */
    IfxPort_Mode_outputOpenDrainAlt6    = 0xF0U,  /**< \brief Open-drain, Alternate output function 6. */
    IfxPort_Mode_outputOpenDrainAlt7    = 0xF8U   /**< \brief Open-drain, Alternate output function 7. */
} IfxPort_Mode;
  • PDISC(Pin脚AD功能选择寄存器(Pin Function Decision Control Register,PDISC))

英飞凌芯片的部分Pin脚是支持复用为AD采样的引脚,如果复用为AD采样引脚,就无法再读取引脚的输入,每个Port端口有一个PDISC寄存器,16个位域各控制一个引脚,Pinx的输入控制,0表示数字输入,为普通Pin脚,1表示模拟输入,ADC Pin脚;、。通过port->PDISC.U &= ~(1 << pinIndex);将指定的pinindex的引脚对应的位域写为0,表示为普通的Pin脚

void IfxPort_setPinMode(Ifx_P *port, uint8 pinIndex, IfxPort_Mode mode)
{
    volatile Ifx_P_IOCR0 *iocr      = &(port->IOCR0);
    uint8                 iocrIndex = (pinIndex / 4);
    uint8                 shift     = (pinIndex & 0x3U) * 8;

    if (port == &MODULE_P40)
    {
        uint16 passwd = IfxScuWdt_getCpuWatchdogPassword();
        IfxScuWdt_clearCpuEndinit(passwd);
        port->PDISC.U &= ~(1 << pinIndex);
        IfxScuWdt_setCpuEndinit(passwd);
    }

    __ldmst(&iocr[iocrIndex].U, (0xFFUL << shift), (mode << shift));
}

1.4 IfxPort_setPinState&IfxPort_getPinState

这两个函数一个是用来获取GPIO的状态,一个是用来设置GPIO的状态

void control_LED(void)
{
    /* With the routine getPinState() the value of a particular pin can be retrieved. This
     * function can be used to retrieve any port state by just specifying the port number
     * as illustrated.
     */
    if(IfxPort_getPinState(BUTTON) == 0)
    {
        /* With the routine setPinState() the state of the port can be set to drive either
         * LOW or HIGH. This function can be used to retrieve any port state by just
         * specifying the port number as illustrated.
         */
        IfxPort_setPinState(LED1, IfxPort_State_low);
        IfxPort_setPinState(LED2, IfxPort_State_high);
    }
    else
    {
        IfxPort_setPinState(LED1, IfxPort_State_high);
        IfxPort_setPinState(LED2, IfxPort_State_low);
    }
}
  • IfxPort_setPinState

设置Pin脚状态的API主要是通过修改Port输出修改寄存器(Port Output Modification Register,OMR)的值来实现。每个Port有一个OMR寄存器,每个OMR寄存器有32个bit,对应PSx
(x = 0-15,set位)和PCLx(x = 0-15,clear位)两组寄存器,如果要拉高某个Pin脚,就将PSx置1,拉低则将PCLx置1,如果要翻转两个都置1,而其他没有设置位的Pin脚则不会受影响。

#define LED1     &MODULE_P00,5   /* Port pin for the LED     */
#define LED2     &MODULE_P00,6   /* Port pin for the LED     */

/** \brief Ifx_P output modification modes definition.
 *
 * \see Ifx_P.OMR, IfxPort_setPinState()
 */
typedef enum
{
    IfxPort_State_notChanged = (0 << 16) | (0 << 0),  /**< \brief Ifx_P pin is left unchanged. */
    IfxPort_State_high       = (0 << 16) | (1U << 0), /**< \brief Ifx_P pin is set to high. */
    IfxPort_State_low        = (1U << 16) | (0 << 0), /**< \brief Ifx_P pin is set to low. */
    IfxPort_State_toggled    = (1U << 16) | (1U << 0) /**< \brief Ifx_P pin is toggled. */
} IfxPort_State;


IFX_INLINE void IfxPort_setPinState(Ifx_P *port, uint8 pinIndex, IfxPort_State action)
{
    port->OMR.U = action << pinIndex;
}

 

  • IfxPort_getPinState

获取Pin脚状态的API主要是通过Port输入寄存器(Port Input Register,IN)来实现,每个Port口有一个IN寄存器来读取Pin脚的当前状态,无论Pin脚是输入还是输出模式都可以通过该寄存器读取Pin脚的电平状态。如果读取到的是0,则代表当前Pin脚是低电平,如果是1,则代表当前电平是高电平。

#define BUTTON  &MODULE_P00,7   /* Port pin for the button  */

IFX_INLINE boolean IfxPort_getPinState(Ifx_P *port, uint8 pinIndex)
{
    return (__getbit(&port->IN.U, pinIndex) != 0) ? TRUE : FALSE;
}

 

2,实验分享

通过在Core0的main函数里面一直调用control_LED来监控Button的状态,进而控制LED。

如果当前Button没有按下,则LED2亮起来,如果Button按下了,则当前LED2灭掉,另外一个LED1亮起来。

LED_GPIO

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值