当前位置: 代码网 > it编程>前端脚本>Python > 英飞凌(Infineon)TC264单片机---LED

英飞凌(Infineon)TC264单片机---LED

2024年08月02日 Python 我要评论
本文介绍如何应用Infineon官方提供的免费IDE开发环境Development Studio和TC264开发板(龙邱科技提供)实现LED的闪烁。

本文介绍如何应用infineon官方提供的免费ide开发环境aurix development studio和tc264开发板(龙邱科技提供)实现led的闪烁。

1. aurix development studio

aurix development studio(下简称ads), 是英飞凌推出在针对自家aurix芯片的免费编译环境,软件使用无需license,长期免费。该开发环境基于业内流行的eclipse打造而成,界面非常友好,对于刚刚接触英飞凌的朋友们而言更是易于上手。ads集成了编译器、调试器、illd底层开发库等必备组件,无需开发者四处寻找调试器和底层库代码。ads的编译器和调试器是基于tasking编译器、调试器打造而成,稳定性上无需额外担心,调试器比较难用,全当是一个高阶版的下载器吧。

2. 硬件环境

本次实现的硬件环境是用龙邱科技提供的tc264核心板+母版+下载器:

3.代码

3.1新建工程

打开adas,选择工作区(略)之后,在file→new,新建aurix工程

 

填写工程名称,选择next下一步: 

 选择对应的芯片(tc26x b-step),点击finish:

 在产生的结构树中新建一个“src”文件夹,用于存放自己写的代码:

建立以下代码文件: 

3.2 关键代码

先说明下,以下为该开发板默认的led接口:
led0p p10_6 龙邱tc母板核心板上led0 翠绿
led1p p10_5 龙邱tc母板核心板上led1 蓝灯
led2p p20_6 龙邱tc母板上led0
led3p p20_7 龙邱tc母板上led1

3.2.1 lq_gpio

为了实现对gpio引脚的基本操作,先建立lq_gpio的头文件,lq_gpio主要目的是:

  • 定义相关针脚枚举类gpio_name,如p10_5 = 0xb005(b005的前两位b0实际是module编号,05实际是pin的编号)

 该地址可参考英飞凌tc264用户手册第十四章《general purpose i/o ports and peripheral i/o lines (ports)

如上表,每个moudule的所有寄存器加起来需要的内存大小有256个字节(00-ff),以下为illd中ifxport_regdef.h中对port结构体的定义,可以看出共有256字节的相关的寄存器: 

port结构体:

/** \brief  port object */
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;

定义gpio的模式,本例最终用的是推挽输出模式
定义宏:根据gpio_name获取port的module首地址
定义宏:根据gpio_name获取pin的编号
声明gpio的pin初始化函数_void pin_initconfig(gpio_name_t pin,ifxport_mode mode, uint8 output);_
声明gpio的pin的写入函数_void pin_write(gpio_name_t pin,uint8 output);_通过该函数来更新电平状态,(output为0则高电平,为1则低电平)
声明gpio的pin电平翻转函数void pin_reverse(gpio_name_t pin);


lq_gpio的头文件(.h文件)如下:

#ifndef src_lq_gpio_h_
#define src_lq_gpio_h_

#include "platform_types.h"
#include "ifxport_regdef.h"
#include "ifxport.h"

// gpio port no.
typedef enum //
{
    p21_4 = 0xc104,
    p21_5 = 0xc105,
    p20_8 = 0xc008,
    p20_9 = 0xc009,
}gpio_name_t;

//gpio mode
#define pin_mode_output          ifxport_mode_outputpushpullgeneral    /*!< 推挽输出  */
#define pin_mode_output_od       ifxport_mode_outputopendraingeneral   /*!< 开漏输出  */
#define pin_mode_input           ifxport_mode_inputnopulldevice        /*!< 浮空输入  */
#define pin_mode_input_pullup    ifxport_mode_inputpullup              /*!< 上拉输入  */
#define pin_mode_input_pulldown  ifxport_mode_inputpulldown            /*!< 下拉输入  */

// get the gpio port module base address
#define pin_getmodule(gpio_name)    (ifx_p*)(0xf0030000u | (gpio_name & 0xff00))
// get the gpio port pin index
#define pin_getindex(gpio_name)    (uint8)(gpio_name & 0x000f)

void pin_initconfig(gpio_name_t pin,ifxport_mode mode, uint8 output);
void pin_write(gpio_name_t pin,uint8 output);
void pin_reverse(gpio_name_t pin);

#endif /* src_lq_gpio_h_ */

其中typedef enum中的地址为下图对应的地址

查看原理图,发现开发板的四个等分别是p21.4,p21.5,p20.8,p20.9所以0xc104,0xc105,0xc008,0xc009。这个根据自己开发板而定。

对应的实现源文件(.c文件)是: 

#include "lq_gpio.h"

void pin_initconfig(gpio_name_t pin,ifxport_mode mode,uint8 output)
{
    ifx_p *port = pin_getmodule(pin);
    unsigned char pinindex = pin_getindex(pin);

    // 配置gpio模式
    ifxport_setpinmode(port, pinindex, mode);
    ifxport_setpinpaddriver(port, pinindex, ifxport_paddriver_cmosautomotivespeed2);

    /* gpio输出模式时 输出状态 */
    if (0 == output)
    {
        ifxport_setpinstate(port, pinindex, ifxport_state_low);
    }
    else
    {
        ifxport_setpinstate(port, pinindex, ifxport_state_high);
    }
}


void pin_write(gpio_name_t pin,unsigned char output)
{
    ifx_p *port = pin_getmodule(pin);
    unsigned char pinindex = pin_getindex(pin);

    // gpio output mode
    if (output == 0)
    {
        ifxport_setpinstate(port, pinindex, ifxport_state_low);
    }
    else
    {
        ifxport_setpinstate(port, pinindex, ifxport_state_high);
    }
}

void pin_reverse(gpio_name_t pin)
{
    ifx_p *port = pin_getmodule(pin);
    unsigned char pinindex = pin_getindex(pin);

    ifxport_togglepin(port, pinindex);
}
3.2.2 lq_gpio_led

建立led与gpio引脚的关系并定义相关操作,编写lq_gpio_led头文件,该头文件主要目的是:

定义led灯的编号枚举类ledn_e
定义led灯的状态枚举类leds_e
定义led灯编号与pin name的对应关系
声明led初始化函数_void gpio_led_init(void);_
声明led控制函数_void led_ctrl(ledn_e ledn,leds_e leds);_
声明led测试函数void test_gpio_led(void);
相关头文件(.h文件):

#ifndef src_lq_gpio_led_h_
#define src_lq_gpio_led_h_

#include "lq_gpio.h"

// define enum for led number
typedef enum
{
    led0 = 0,
    led1 = 1,
    led2 = 2,
    led3 = 3,
    led_all = 4
} ledn_e;

// define enum for led state
typedef enum
{
    on = 0,
    off = 1,
    rvs = 2 
}leds_e;

// led and pin
#define led0p   p20_8
#define led1p   p20_9
#define led2p   p21_4
#define led3p   p21_5

void gpio_led_init(void);
void led_ctrl(ledn_e ledn,leds_e leds);
void test_gpio_led(void);

#endif /* src_lq_gpio_led_h_ */

 对应的源文件(.c文件):

#include "lq_gpio_led.h"
#include "lq_stm.h"


void gpio_led_init(void)
{
    // 初始化,输入口,高电平
    pin_initconfig(led0p, pin_mode_output, 0);
    pin_initconfig(led1p, pin_mode_output, 0);
    pin_initconfig(led2p, pin_mode_output, 0);
    pin_initconfig(led3p, pin_mode_output, 0);
}


void led_ctrl(ledn_e ledno,leds_e sta)
{
    switch(ledno)
    {
        case led0:
            if(sta==on)    pin_write(led0p, 0);
            else if(sta==off)    pin_write(led0p, 1);
            else if(sta==rvs)   pin_reverse(led0p);
        break;

        case led1:
          if(sta==on)        pin_write(led1p,0);
          else if(sta==off) pin_write(led1p,1);
          else if(sta==rvs) pin_reverse(led1p);
        break;

        case led2:
          if(sta==on)        pin_write(led2p,0);
          else if(sta==off) pin_write(led2p,1);
          else if(sta==rvs) pin_reverse(led2p);
        break;

        case led3:
          if(sta==on)        pin_write(led3p,0);
          else if(sta==off) pin_write(led3p,1);
          else if(sta==rvs) pin_reverse(led3p);
        break;

        case led_all:
          if(sta==on)
          {
              pin_write(led0p,0);
              pin_write(led1p,0);
              pin_write(led2p,0);
              pin_write(led3p,0);
          }
          else if(sta==off)
          {
              pin_write(led0p,1);
              pin_write(led1p,1);
              pin_write(led2p,1);
              pin_write(led3p,1);
          }
          else if(sta==rvs)
          {
              pin_reverse(led0p);
              pin_reverse(led1p);
              pin_reverse(led2p);
              pin_reverse(led3p);
          }
        break;
        default:
        break;
    }
}

void test_gpio_led(void)
{
    gpio_led_init();
    while(1)
    {
        led_ctrl(led_all, rvs);
        delayms(100);
    }
}

3.2.3 lq_stm

由于实现对led的翻转闪烁控制,需要实现计时功能,即要借助于tc264的系统定时器(stm),并实现自己的定时功能,lq_stm实现以下功能:

定义stm枚举类stm_t,包含stm0和stm1,其实这个对应于tc264两个cpu的时钟源,我们这里当然选stm0
声明微妙级的延时函数_void stm_delayus(stm_t stm, unsigned long us);_
声明毫秒级的延时函数_void delayms(unsigned short stmms);_


声明两个延时函数:第一个是通过调用illd中的ifxstm_getticksfrommicroseconds函数实现精确的微妙级计时;第二个是调用汇编指令nop(无操作)实现不怎么精确的计时。
本例中用#if条件汇编指令默认选用第一种方法

头文件(.h文件):

#ifndef lq_stm_h_
#define lq_stm_h_

#include "platform_types.h"
#include "ifxstm_regdef.h"
#include "ifxstm.h"
#include "ifxstm_cfg.h"

// stm module enumerate
typedef enum{
    stm0 = 0,
    stm1 = 1
}stm_t;

void stm_delayus(stm_t stm, unsigned long us);
void delayms(unsigned short stmms);

# endif

对应的源文件(.c文件):

#include "lq_stm.h"

// stm delay
 void stm_delayus(stm_t stm, uint32 us)
 {
    ifx_stm * stm = ifxstm_getaddress((ifxstm_index)stm);
    uint32 tick = ifxstm_getticksfrommicroseconds(stm, us);

    ifxstm_waitticks(stm, tick);
 }


// delay function
void delayms(unsigned short stmms)
{
    #if 1
    // accurate delay
    while(stmms--){
        stm_delayus(stm0,1000);
    }
    #else 
    // not accurate delay
    volatile unsigned long i = 0;
    while(stmms--)
    {
        for(i=0;i<16580;++i){
            __asm("nop");
        }
    }
    #endif
}
3.2.4 cpu0_main.c

我们只利用cpu0进行led的控制,以下为源文件:

#include "lq_gpio_led.h"
#include "ifxcpu.h"
#include "ifxscuwdt.h"
#include "ifxscuccu.h"
#include "lq_stm.h"


ifxcpu_mutexlock mutexcpu0initisok = 1; // flag of cpu0 initialization

int core0_main(void)
{
    // close the cpu interrupt
    ifxcpu_disableinterrupts();
    // close the watch dog
    ifxscuwdt_disablecpuwatchdog(ifxscuwdt_getcpuwatchdogpassword());
    ifxscuwdt_disablesafetywatchdog(ifxscuwdt_getsafetywatchdogpassword());
    // initial led
    gpio_led_init();
    // open cpu interrupt
    ifxcpu_enableinterrupts();
    // tell cpu1, the cpu0 finished initialization
    ifxcpu_releasemutex(&mutexcpu0initisok);

    while(1)
    {
        led_ctrl(led_all,rvs);
        delayms(100);
    }
    return (1);
}
3.2.5 cpu1_main.c

对应的cpu1的源文件:

#include "ifx_types.h"
#include "ifxcpu.h"
#include "ifxscuwdt.h"

extern ifxcpu_mutexlock mutexcpu0initisok;

int core1_main(void)
{
    // 开启cpu总中断
    ifxcpu_enableinterrupts();
    // 关闭看门狗
    ifxscuwdt_disablecpuwatchdog (ifxscuwdt_getcpuwatchdogpassword ());
    // 等待cpu0 初始化完成
    while(!ifxcpu_acquiremutex(&mutexcpu0initisok));
    while(1)//主循环
    {

    }
}

 4. build & debug

注意:在这一步的编译和debug中,如果提示“找不到ftd2××.dll”,都是因为开发板和电脑没有连接上,可以打开设备管理器,找到对应串口安装

4.1 编译

点击build按钮,对代码进行编译:

编译结束后,务必保证无error: 

 同时,在debug文件夹下会产生.elf文件,用于debug和下载

4.2 debug

点击debug按钮旁边的小三角,选择debug configurations

双击tasking c/c++ debugger:

① 选择出现的"lq_gpio_led",② 选择默认出现的file,③ 将其删除 ④ 选择add,在弹出的对话框中添加刚才的.elf文件 ⑤ 点击debug
 弹出对话框,选择“switch”:

出现debug界面,可以进行debug:

4.3 烧录

点击这个就能烧录了。

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com