Funpack第二季第二期:KIT_AURIX_TC275_LITE实现呼吸灯
设计一个呼吸灯,通过旋转板卡上的电位计,改变呼吸灯闪烁速率,同时将ADC采集的数据通过串口/CAN,发送到另一台设备上显示
标签
嵌入式系统
工业消费电子
英飞凌
ADS
wjhgbpqm
更新2022-10-10
杭州电子科技大学
561

Funpack第二季第二期:KIT_AURIX_TC275_LITE实现控制改变呼吸灯闪烁频率

一.KIT_AURIX_TC275_LITE硬件介绍

      AURIX TM TC275 lite 套件配备了基于 32 位单芯片 AURIX TM TriCore TM的微控制器 Aurix TM TC275。它可以与一系列开发工具一起使用,包括 AURIX TM Development Studio、英飞凌免费的基于 Eclipse 的 IDE,或来自 Hightec/PLS/Infineon 的基于 Eclipse 的“FreeEntryToolchain”板子外观如图一所示。

主要特性:

  • Arduino 连接器
  • Arduino ICSP 连接器
  • 稳压器 5V 至 3.3V
  • 可选 0 欧姆电阻器(1210 英制中的 R39_opt/R40_opt)
  • Arduino 连接器(数字)
  • 用于 AURIX™ TM的 20 MHz 晶振和用于 OCDS 的 12 MHz 晶振
  • 用于 WIFI/BLE 的 Mikrobus 连接器
  • 英飞凌 CAN 收发器 TLE9251VSJ 和 CAN 连接器
  • 针连接器 X2
  • 电源指示灯 (D5)
  • LED D1/D2 用于 ADBUS7/4 和 LED3 用于 ESR0 信号(低电平有效)
  • Arduino 针连接器(电源和模拟输入)
  • 电位器 (10 kOhm) 和可焊接的 0 Ohm 电阻器(0805 英制中的 R33)
  • 微型 USB(推荐 USB3.0)
  • 10 针 DAP 连接器
  • 复位按钮
  • 2 x Shield2GO 连接器,用于 Infineon Maker Shields
  • EEPROM 1Kbit

 

 

Fu3q1NW7UnYX8KLDjSW5ewAUoXwh

 

图一.板子外观

AURIX TM TC275 lite 套件评估板各模块布局如图二所示。
 

 

FjfzV6tx_QNMOEOHHrR4LktGOiXX

图二.板子各模块布局

 
二.KIT_AURIX_TC275_LITE软件开发
2.1开发软件介绍

AURIX™ Development Studio(以下简称ADS)是英飞凌公司于2019年底推出的免费*的集成开发环境,支持英飞凌TriCore™内核AURIX™ 系列MCU;ADS是一个完整的开发环境,包含了Eclipse IDE、C编译器、Multi-core调试器、英飞凌底层驱动库(low-level driver,iLLD),同时对于编辑、编译及调试应用代码没有时间及代码大小的限制。

ADS软件由以下组成:

  1. AURIX™ Development Studio 1.1.8
  2. DAS 7.1.9: 英飞凌AURIX™驱动
  3. iLLD 1.0.1.11.0: 英飞凌底层驱动库
  4. Oracle JRE11: Java Runtime Environment
  5. TASKING Debugger v1.1r2 –仅能使用于非商业目的
  6. TASKING Compiler v1.1r1–仅能使用于非商业目的
  7. CMake 3.14.0
  8. GNU Make 4.2.1
  9. GNU Coreutils 5.3.0

相关论坛/网站:

1)Aurix Forum,英飞凌官方的论坛,都是英文:https://www.infineonforums.com/forums/13-Aurix-Forum?_ga=2.212753875.675854992.1584004040-127082800.1584004040

2)英飞凌汽车电子生态圈:https://www.infineon-autoeco.com/

3)Aurix产品模块公开课程:由昆明理工的姚国仲老师录制,超过50节课时,详细介绍Aurix各个模块,并有动手实验总结:https://videos.infineon-autoeco.com/pc/page/detail/159?id=215  软件界面如如三所示。

Fr0L_IQXebu35fkMEL8KNxHJL3T4

图三.软件界面图

2.1软件编写

本项目实现的是任务二

​任务二:

设计一个呼吸灯,通过旋转板卡上的电位计,改变呼吸灯闪烁速率,同时将ADC采集的数据通过串口/CAN,发送到另一台设备上显示。任务二主要使用了板子的UART串口,GPIO,定时器模块以及ADC模块,为此,移植了相关驱动程序。

设计逻辑:

我的主要设及逻辑是:

  1. 是各种驱动模块的移植(PWM,ADC,串口,GPIO)
  2. PWM实现LED呼吸灯的控制
  3. 获取电位器的ADC值
  4. 改变呼吸灯的闪烁周期
  5. ADC采集值发送到串口

程序部分

  1. GPIO的PWM驱动移植,参考了官方例程,LED呼吸灯的主要控制函数是void fade_LED(uint32 time);time用来控制呼吸灯闪烁的周期,详细代码如下:
#include "GTM_TOM_PWM.h"
#include "Ifx_Types.h"
#include "IfxGtm_Tom_Pwm.h"
#include "Bsp.h"
/*********************************************************************************************************************/
/*------------------------------------------------------Macros-------------------------------------------------------*/
/*********************************************************************************************************************/
#define ISR_PRIORITY_TOM    20                                      /* Interrupt priority number                    */
#define LED                 IfxGtm_TOM1_4_TOUT14_P00_5_OUT          /* LED which will be driven by the PWM          */
#define PWM_PERIOD          50000                                   /* PWM period for the TOM                       */
#define FADE_STEP           PWM_PERIOD / 100                        /* PWM duty cycle for the TOM                   */

/*********************************************************************************************************************/
/*-------------------------------------------------Global variables--------------------------------------------------*/
/*********************************************************************************************************************/
IfxGtm_Tom_Pwm_Config g_tomConfig;                                  /* Timer configuration structure                */
IfxGtm_Tom_Pwm_Driver g_tomDriver;                                  /* Timer Driver structure                       */
uint32 g_fadeValue = 0;                                             /* Fade value, starting from 0                  */
sint8 g_fadeDir = 1;                                                /* Fade direction variable                      */

/*********************************************************************************************************************/
/*-----------------------------------------------Function Prototypes-------------------------------------------------*/
/*********************************************************************************************************************/
void setDutyCycle(uint32 dutyCycle);                                /* Function to set the duty cycle of the PWM    */

/*********************************************************************************************************************/
/*--------------------------------------------Function Implementations-----------------------------------------------*/
/*********************************************************************************************************************/
/* This function initializes the TOM */
void initGtmTomPwm(void)
{
    IfxGtm_enable(&MODULE_GTM);                                     /* Enable GTM                                   */

    IfxGtm_Cmu_enableClocks(&MODULE_GTM, IFXGTM_CMU_CLKEN_FXCLK);   /* Enable the FXU clock                         */

    /* Initialize the configuration structure with default parameters */
    IfxGtm_Tom_Pwm_initConfig(&g_tomConfig, &MODULE_GTM);

    g_tomConfig.tom = LED.tom;                                      /* Select the TOM depending on the LED          */
    g_tomConfig.tomChannel = LED.channel;                           /* Select the channel depending on the LED      */
    g_tomConfig.period = PWM_PERIOD;                                /* Set the timer period                         */
    g_tomConfig.pin.outputPin = &LED;                               /* Set the LED port pin as output               */
    g_tomConfig.synchronousUpdateEnabled = TRUE;                    /* Enable synchronous update                    */

    IfxGtm_Tom_Pwm_init(&g_tomDriver, &g_tomConfig);                /* Initialize the GTM TOM                       */
    IfxGtm_Tom_Pwm_start(&g_tomDriver, TRUE);                       /* Start the PWM                                */
}

/* This function creates the fade effect for the LED */
//控制呼吸灯的闪烁周期
//time是延迟时间
void fade_LED(uint32 time)
{

    for(uint8 i=0;i<=100;i++)
        {
            setDutyCycle(i*500);

            waitTime(IfxStm_getTicksFromMilliseconds(BSP_DEFAULT_TIMER, time));   /* Delay of 10ms                    */

        }
        for(uint8 i=100;i>0;i--)
        {
            setDutyCycle(i*500);
            waitTime(IfxStm_getTicksFromMilliseconds(BSP_DEFAULT_TIMER, time));

        }
                                         /* Set the duty cycle of the PWM                */
}
/* This function creates the fade effect for the LED */
void fadeLED(void)
{
    if((g_fadeValue + FADE_STEP) >= PWM_PERIOD)
    {
        g_fadeDir = -1;                                             /* Set the direction of the fade                */
    }
    else if((g_fadeValue - FADE_STEP) <= 0)
    {
        g_fadeDir = 1;                                              /* Set the direction of the fade                */
    }
    g_fadeValue += g_fadeDir * FADE_STEP;                           /* Calculation of the new duty cycle            */
    setDutyCycle(g_fadeValue);                                      /* Set the duty cycle of the PWM                */
}

/* This function sets the duty cycle of the PWM */
void setDutyCycle(uint32 dutyCycle)
{
    g_tomConfig.dutyCycle = dutyCycle;                              /* Change the value of the duty cycle           */
    IfxGtm_Tom_Pwm_init(&g_tomDriver, &g_tomConfig);                /* Re-initialize the PWM                        */
}

2.UART串口的驱动移植包括串口初始化函数void init_UART(void),详细程序如下:

#include "IfxAsclin_Asc.h"
#include "IfxCpu_Irq.h"

/*********************************************************************************************************************/
/*------------------------------------------------------Macros-------------------------------------------------------*/
/*********************************************************************************************************************/
#define SERIAL_BAUDRATE         115200                                      /* Baud rate in bit/s                   */

#define SERIAL_PIN_RX           IfxAsclin0_RXA_P14_1_IN                     /* RX pin of the board                  */
#define SERIAL_PIN_TX           IfxAsclin0_TX_P14_0_OUT                     /* TX pin of the board                  */

#define INTPRIO_ASCLIN0_TX      19                                          /* Priority of the ISR                  */

#define ASC_TX_BUFFER_SIZE      64                                          /* Definition of the buffer size        */

/*********************************************************************************************************************/
/*-------------------------------------------------Global variables--------------------------------------------------*/
/*********************************************************************************************************************/
IfxAsclin_Asc g_asc;                                                        /* Declaration of the ASC handle        */
uint8 g_ascTxBuffer[ASC_TX_BUFFER_SIZE + sizeof(Ifx_Fifo) + 8];             /* Declaration of the FIFOs parameters  */

/*********************************************************************************************************************/
/*---------------------------------------------Function Implementations----------------------------------------------*/
/*********************************************************************************************************************/
IFX_INTERRUPT(asclin0_Tx_ISR, 0, INTPRIO_ASCLIN0_TX);                       /* Adding the Interrupt Service Routine */

void asclin0_Tx_ISR(void)
{
    IfxAsclin_Asc_isrTransmit(&g_asc);
}

void init_UART(void)
{
    /* Initialize an instance of IfxAsclin_Asc_Config with default values */
    IfxAsclin_Asc_Config ascConfig;
    IfxAsclin_Asc_initModuleConfig(&ascConfig, SERIAL_PIN_TX.module);

    /* Set the desired baud rate */
    ascConfig.baudrate.baudrate = SERIAL_BAUDRATE;

    /* ISR priorities and interrupt target */
    ascConfig.interrupt.txPriority = INTPRIO_ASCLIN0_TX;
    ascConfig.interrupt.typeOfService = IfxCpu_Irq_getTos(IfxCpu_getCoreIndex());

    /* FIFO configuration */
    ascConfig.txBuffer = &g_ascTxBuffer;
    ascConfig.txBufferSize = ASC_TX_BUFFER_SIZE;

    /* Port pins configuration */
    const IfxAsclin_Asc_Pins pins =
    {
        NULL_PTR,         IfxPort_InputMode_pullUp,     /* CTS pin not used     */
        &SERIAL_PIN_RX,   IfxPort_InputMode_pullUp,     /* RX pin not used      */
        NULL_PTR,         IfxPort_OutputMode_pushPull,  /* RTS pin not used     */
        &SERIAL_PIN_TX,   IfxPort_OutputMode_pushPull,  /* TX pin               */
        IfxPort_PadDriver_cmosAutomotiveSpeed1
    };
    ascConfig.pins = &pins;

    IfxAsclin_Asc_initModule(&g_asc, &ascConfig);                       /* Initialize module with above parameters  */
}

void send_UART_message(char *tx_data,Ifx_SizeT length)
{
    //uint8 txData[] = "Hello World!";                                    /* Message to send                          */
   // Ifx_SizeT count = 12;                                               /* Size of the message                      */
    IfxAsclin_Asc_write(&g_asc, tx_data, &length, TIME_INFINITE);         /* Transfer of data                         */
}
 
3.ADC驱动程序移植,包括ADC初始化函数void initializeLEDs(void),获取ADC值的函数void get_adc_Value(void),以及通过获取到ADC值控制LED闪烁周期和转化成相应的电压值发送数据到串口的函数void send_adc_data( uint32 adcVal),详细程序如下:
#include "IfxVadc_Adc.h"
#include "ADC_Single_Channel.h"
#include "GTM_TOM_PWM.h"

/*********************************************************************************************************************/
/*------------------------------------------------------Macros-------------------------------------------------------*/
/*********************************************************************************************************************/
#define LED1                        &MODULE_P00, 5              /* LED1                                             */
#define LED2                        &MODULE_P00, 6              /* LED2                                             */
#define LIMIT_HIGH                  0xAAA                       /* Higher limit to be compared with the measurement */
#define LIMIT_LOW                   0x555                       /* Lower limit to be compared with the measurement  */
#define VADC_GROUP                  IfxVadc_GroupId_0           /* Use the ADC group 0                              */
#define CHANNEL_ID                  0                           /* Use the Channel 0                                */
#define CHANNEL_RESULT_REGISTER     5                           /* Use the Result Register 5                        */

#define INDEX     0//通道an0
#define TX_LENGTH           21    /* Size of the results message, sent to the user    */
#define ASCII_SHIFT                 48          /* Shift in the ASCII table: '0', '1', '2'[...], start at value 48  */
#define change_data             0.8057      //电压和测量值的转换 3300/4096
/*********************************************************************************************************************/
/*-------------------------------------------------Global variables--------------------------------------------------*/
/*********************************************************************************************************************/
ApplicationVadcBackgroundScan g_vadcBackgroundScan;

/*********************************************************************************************************************/
/*---------------------------------------------Function Implementations----------------------------------------------*/
/*********************************************************************************************************************/
/* The initialization of the port pins to control the LEDs is done by this function */
void initializeLEDs(void)
{
    /* Initialize the Port Pins */
    IfxPort_setPinMode(LED1, IfxPort_Mode_outputPushPullGeneral);
    IfxPort_setPinMode(LED2, IfxPort_Mode_outputPushPullGeneral);

    /* Turn off the LEDs */
    IfxPort_setPinHigh(LED1);
    IfxPort_setPinHigh(LED2);
}

/* This function retrieves the conversion value and indicates it by LEDs */
void indicateConversionValue(void)
{
    Ifx_VADC_RES conversionResult;

    /* Retrieve the conversion value until valid flag of the result register is true */
    do
    {
        conversionResult = IfxVadc_Adc_getResult(&g_vadcBackgroundScan.adcChannel);
    }
    while (!conversionResult.B.VF);

    if(conversionResult.B.RESULT < LIMIT_LOW)       /* LED1 lights up if the conversion value is smaller than 0x555 */
    {
        IfxPort_setPinLow(LED1);
        IfxPort_setPinHigh(LED2);
    }
    else if(conversionResult.B.RESULT > LIMIT_HIGH) /* LED2 lights up if the conversion value is greater than 0xAAA */
    {
        IfxPort_setPinHigh(LED1);
        IfxPort_setPinLow(LED2);
    }
    else                                            /* LED1 and LED2 light up if the conversion value is in between */
    {
        IfxPort_setPinLow(LED1);
        IfxPort_setPinLow(LED2);
    }
 }
void get_adc_Value(void)
{
    Ifx_VADC_RES conversionResult;

    /* Retrieve the conversion value until valid flag of the result register is true */
    do
    {
        conversionResult = IfxVadc_Adc_getResult(&g_vadcBackgroundScan.adcChannel);
    }
    while (!conversionResult.B.VF);

    send_adc_data(conversionResult.B.RESULT);
 }

void send_adc_data( uint32 adcVal)
{

    char str[TX_LENGTH] = {'C','h','.','X',':',' ','X','X','X','X',' ',' ','V',':','X','.','X','X','X','\n','\r'};  /* X to be replaced by correct values*/


     str[3] = (char) INDEX + ASCII_SHIFT;


    uint32 time = 0, voltage = 0;
    //最长周期5s对应adc值4096
    //最短周期0s对应adc值0
    time =50 *adcVal / 4096.0;  //计算延迟时间
    voltage = adcVal * change_data;
    fade_LED(time);


         /* Turns the digital converted value into its ASCII characters, e.g. 1054 -> '1','0','5','4' */
         /* 12-bits range value: 0-4095 */
    str[6] = (adcVal / 1000) + ASCII_SHIFT;                                     /* Thousands                        */
    str[7] = ((adcVal % 1000) / 100) + ASCII_SHIFT;                             /* Hundreds                         */
    str[8] = ((adcVal % 100) / 10) + ASCII_SHIFT;                               /* Tens                             */
    str[9] = (adcVal % 10) + ASCII_SHIFT;                                       /* Units                            */
    str[14] = (voltage / 1000) + ASCII_SHIFT;                                     /* Thousands                        */
    str[16] = ((voltage % 1000) / 100) + ASCII_SHIFT;                             /* Hundreds                         */
    str[17] = ((voltage % 100) / 10) + ASCII_SHIFT;                               /* Tens                             */
    str[18] = (voltage % 10) + ASCII_SHIFT;                                       /* Units                            */


         /* Print via UART */
         send_UART_message(str, TX_LENGTH);

}



/* The VADC module and group are initialized */
void vadcBackgroundScanInit(void)
{
    /* VADC module configuration */
    /* Create VADC configuration */
    IfxVadc_Adc_Config adcConfig;

    /* Initialize the VADC configuration with default values */
    IfxVadc_Adc_initModuleConfig(&adcConfig, &MODULE_VADC);

    /* Initialize the VADC module using the VADC configuration */
    IfxVadc_Adc_initModule(&g_vadcBackgroundScan.vadc, &adcConfig);

    /* VADC group configuration */
    /* Create group configuration */
    IfxVadc_Adc_GroupConfig adcGroupConfig;

    /* Initialize the group configuration with default values */
    IfxVadc_Adc_initGroupConfig(&adcGroupConfig, &g_vadcBackgroundScan.vadc);

    /* Define which ADC group is going to be used */
    adcGroupConfig.groupId = VADC_GROUP;
    adcGroupConfig.master = VADC_GROUP;

    /* Enable background scan source */
    adcGroupConfig.arbiter.requestSlotBackgroundScanEnabled = TRUE;

    /* Enable background auto scan mode */
    adcGroupConfig.backgroundScanRequest.autoBackgroundScanEnabled = TRUE;

    /* Enable the gate in "always" mode (no edge detection) */
    adcGroupConfig.backgroundScanRequest.triggerConfig.gatingMode = IfxVadc_GatingMode_always;

    /* Initialize the group using the group configuration */
    IfxVadc_Adc_initGroup(&g_vadcBackgroundScan.adcGroup, &adcGroupConfig);
}

/* The input channels to be used are setup and the VADC is set into run mode */
void vadcBackgroundScanRun(void)
{
    /* Initialize the channel configuration of application handle g_vadcBackgroundScan with default values */
    IfxVadc_Adc_initChannelConfig(&g_vadcBackgroundScan.adcChannelConfig, &g_vadcBackgroundScan.adcGroup);

    g_vadcBackgroundScan.adcChannelConfig.channelId = (IfxVadc_ChannelId)CHANNEL_ID;
    g_vadcBackgroundScan.adcChannelConfig.resultRegister = (IfxVadc_ChannelResult)CHANNEL_RESULT_REGISTER;
    g_vadcBackgroundScan.adcChannelConfig.backgroundChannel = TRUE;

    /* Initialize the channel of application handle g_VadcBackgroundScan using the channel configuration */
    IfxVadc_Adc_initChannel(&g_vadcBackgroundScan.adcChannel, &g_vadcBackgroundScan.adcChannelConfig);

    /* Enable background scan for the channel */
    IfxVadc_Adc_setBackgroundScan(&g_vadcBackgroundScan.vadc,
                                  &g_vadcBackgroundScan.adcGroup,
                                  (1 << (IfxVadc_ChannelId)CHANNEL_ID),
                                  (1 << (IfxVadc_ChannelId)CHANNEL_ID));

    /* Start background scan conversion */
    IfxVadc_Adc_startBackgroundScan(&g_vadcBackgroundScan.vadc);
}

4.主程序首先是串口,pwm,ADC等模块初始化,然后在while(1)内循环运行adc值采集函数,并通过获得的ADC值控制控制LED闪烁周期,详细代码如下

#include "Ifx_Types.h"
#include "IfxCpu.h"
#include "IfxScuWdt.h"
#include "GTM_TOM_PWM.h"
#include "Bsp.h"
#include "ADC_Single_Channel.h"
#include "UART_VCOM.h"
/*********************************************************************************************************************/
/*------------------------------------------------------Macros-------------------------------------------------------*/
/*********************************************************************************************************************/
#define WAIT_TIME   10              /* Number of milliseconds to wait between each duty cycle change                */

IfxCpu_syncEvent g_cpuSyncEvent = 0;

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);
    
    /* Initialize a time variable */
   // Ifx_TickTime ticksFor10ms = IfxStm_getTicksFromMilliseconds(BSP_DEFAULT_TIMER, WAIT_TIME);
    /* Initialize VADC */
      vadcBackgroundScanInit();

      /* Start the background scan */
      vadcBackgroundScanRun();
    /* Initialize GTM TOM module */
    initGtmTomPwm();
    init_UART();            /* Initialize the module            */

    while(1)
    {
        
        get_adc_Value();
    }
    return (1);
}

 

四.结果与总结

4.1结果

板子连接上电脑后,打开AURIX™ Development Studio软件,把程序下载到板子里,打开串口监视器串口波特率设置为115200,通过旋钮控制LED灯,LED灯的闪烁周期发生了变化,同时采集到的ADC值在电脑上的串口助手成功显示,如图四所示。

Fmqq35yTbzOmIdaUyaOPyJjiKkbZ

图四.串口助手接受到的信息

 

4.2总结

很高兴参加硬禾学堂和得捷电子举办的这一期的活动,学习了英飞凌 AURIX TM TC275 lite 套件如何快速开发的相关知识,主要包括GPIO模块,ADC模块,串口模块,PWM模块等,同时更加熟悉了AURIX™ Development Studio软件的使用,锻炼了阅读芯片手册的能力,以及快速搭建开发环境的能力。

 

 

附件下载
tc275.rar
团队介绍
评论
0 / 100
查看更多
目录
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2023 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号