涉及内容
- 环境搭建:AURIX Development Studio英飞凌 AURIX Development Studio 安装和使用,助力 Funpack2-2 - 哔哩哔哩 (bilibili.com)
- TC275 的VADC、GPT、Atom、ASCLIN模块的使用
项目描述
使用板载的LED表示出电位器上电压的大小,并把数值通过串口打印到PC。
1.电位器接口:AN0 大小:10 kOhm
2.LED:LED1 - P00.5 LED2 - P00.6
3.VADC - AN0
TC275 共有 8 路 48 个 AD 通道,36 路专用通道与 12 路复用通道,它们每个都可以进行高达12位分辨率的转换
Analog/Digital可以由多个请求源进行请求:
– Queued scan 请求源,特定于单个组的。
– Channel scan 请求源, 包括:
– Group scan source, 特定于单个组的。
– Background scan source,可以请求所有组的所有通道。
每个请求源最多可以触发三种转换模式:
– Fixed Channel Conversion -- 固定通道转换
– Channel Sequence Conversion -- 通道序列转换
– Auto Scan Conversion -自动扫描转换
4.GTM ATOM可用于产生一个PWM信号,仅有驱动一个LED的强度。
-
- 通用定时器模块(GTM)是一个模块化计时器单元设计,以适应许多计时器应用程序
- 它有一个内置的高级路由器单元(ARU),可以用来在子模块之间交换特定的数据,而不需要进行CPU交互
- ARU-connected 定时器输出模块(ATOM)是GTM的一部分,能够产生复杂的输出信号
- 时钟管理单元 Clock Management Unit(CMU)负责GTM的时钟生成。可配置的时钟生成子单元 Configurable Clock Generation Subunit(CFGU)为GTM子模块提供了8个时钟源: TIM、TBU、MON和ATOM
5.GPT12
-
- 通用定时器单元The General Purpose Timer Uni(GPT12)由两个GPT块(GPT1和GPT2)组成
- 每个块都有一个多功能计时器结构,其中包含几个16位计时器› Block GPT1 contains three 块GPT1包含三个计时器:核心计时器T3和两个辅助计时器T2和T4
- GPT1模块的所有计时器都可以在以下四种模式中之一运行:定时器模式、门控定时器模式、计数器模式或增量接口模式
- 在本项目中,计时器T3在计时器模式下被使用。计数方向配置为“计数”。在计时器T3的下流事件中,计时器T2的值被转换为计时器T3
6.流程图:
主要代码:
- 定时器中断
#include "Ifx_Types.h" #include "IfxGpt12.h" #include "IfxPort.h" #include "TIMER.h" #include "ASC.h" #include "PWM_Generation.h" #include "ADC.h" #define ISR_PRIORITY_GPT12_TIMER 6 /* Define the GPT12 Timer interrupt priority */ #define ISR_PROVIDER_GPT12_TIMER IfxSrc_Tos_cpu0 /* Interrupt provider */ #define RELOAD_VALUE 975u /* Reload value to have an interrupt each 500ms */ #define LED &MODULE_P00, 5 /* LED which toggles in the Interrupt Service Routine */ IFX_INTERRUPT(interruptGpt12, 0, ISR_PRIORITY_GPT12_TIMER); void initGpt12Timer(void) { /* Initialize the GPT12 module */ IfxGpt12_enableModule(&MODULE_GPT120); /* Enable the GPT12 module */ IfxGpt12_setGpt1BlockPrescaler(&MODULE_GPT120, IfxGpt12_Gpt1BlockPrescaler_16); /* Set GPT1 block prescaler */ /* Initialize the Timer T3 */ IfxGpt12_T3_setMode(&MODULE_GPT120, IfxGpt12_Mode_timer); /* Set T3 to timer mode */ IfxGpt12_T3_setTimerDirection(&MODULE_GPT120, IfxGpt12_TimerDirection_down); /* Set T3 count direction */ IfxGpt12_T3_setTimerPrescaler(&MODULE_GPT120, IfxGpt12_TimerInputPrescaler_64); /* Set T3 input prescaler */ IfxGpt12_T3_setTimerValue(&MODULE_GPT120, RELOAD_VALUE); /* Set T3 start value */ /* Initialize the Timer T2 */ IfxGpt12_T2_setMode(&MODULE_GPT120, IfxGpt12_Mode_reload); /* Set T2 to reload mode */ IfxGpt12_T2_setReloadInputMode(&MODULE_GPT120, IfxGpt12_ReloadInputMode_bothEdgesTxOTL); /* Set reload trigger */ IfxGpt12_T2_setTimerValue(&MODULE_GPT120, RELOAD_VALUE); /* Set T2 reload value */ /* Initialize the interrupt */ volatile Ifx_SRC_SRCR *src = IfxGpt12_T3_getSrc(&MODULE_GPT120); /* Get the interrupt address */ IfxSrc_init(src, ISR_PROVIDER_GPT12_TIMER, ISR_PRIORITY_GPT12_TIMER); /* Initialize service request */ IfxSrc_enable(src); /* Enable GPT12 interrupt */ /* Initialize the LED */ IfxPort_setPinModeOutput(LED, IfxPort_OutputMode_pushPull, IfxPort_OutputIdx_general); IfxGpt12_T3_run(&MODULE_GPT120, IfxGpt12_TimerRun_start); /* Start the timer */ } /* Interrupt Service Routine of the GPT12 */ char p_data[50]; uint16 Led_PWM = 0; void interruptGpt12(void) { SetLED((uint16)run_vadc()); }
定时器周期的计算
- Atom模块
#include "PWM_Generation.h" #include "Ifx_Types.h" #include "IfxGtm_Atom_Pwm.h" /*********************************************************************************************************************/ /*------------------------------------------------------Macros-------------------------------------------------------*/ /*********************************************************************************************************************/ #define ISR_PRIORITY_ATOM 20 /* Interrupt priority number */ #define LED IfxGtm_ATOM1_4_TOUT14_P00_5_OUT /* LED which will be driven by the PWM */ #define PWM_PERIOD 4095 /* PWM period for the ATOM */ #define FADE_STEP PWM_PERIOD / 100 /* PWM duty cycle for the ATOM */ #define CLK_FREQ 1000000.0f /* CMU clock frequency, in Hertz */ /*********************************************************************************************************************/ /*-------------------------------------------------Global variables--------------------------------------------------*/ /*********************************************************************************************************************/ IfxGtm_Atom_Pwm_Config g_atomConfig; /* Timer configuration structure */ IfxGtm_Atom_Pwm_Driver g_atomDriver; /* Timer Driver structure */ uint32 g_fadeValue = 0; /* Initialization of the fade value */ sint8 g_fadeDir = 1; /* Initialization of the fade direction variable */ /*********************************************************************************************************************/ /*-----------------------------------------------Function Prototypes-------------------------------------------------*/ /*********************************************************************************************************************/ void setDutyCycle(uint32 dutyCycle); /*********************************************************************************************************************/ /*--------------------------------------------Function Implementations-----------------------------------------------*/ /*********************************************************************************************************************/ /* This function initializes the ATOM */ void initGtmATomPwm(void) { IfxGtm_enable(&MODULE_GTM); /* Enable GTM */ IfxGtm_Cmu_setClkFrequency(&MODULE_GTM, IfxGtm_Cmu_Clk_0, CLK_FREQ); /* Set the CMU clock 0 frequency */ IfxGtm_Cmu_enableClocks(&MODULE_GTM, IFXGTM_CMU_CLKEN_CLK0); /* Enable the CMU clock 0 */ IfxGtm_Atom_Pwm_initConfig(&g_atomConfig, &MODULE_GTM); /* Initialize default parameters */ g_atomConfig.atom = LED.atom; /* Select the ATOM depending on the LED */ g_atomConfig.atomChannel = LED.channel; /* Select the channel depending on the LED */ g_atomConfig.period = PWM_PERIOD; /* Set timer period */ g_atomConfig.pin.outputPin = &LED; /* Set LED as output */ g_atomConfig.synchronousUpdateEnabled = TRUE; /* Enable synchronous update */ IfxGtm_Atom_Pwm_init(&g_atomDriver, &g_atomConfig); /* Initialize the PWM */ IfxGtm_Atom_Pwm_start(&g_atomDriver, TRUE); /* Start the PWM */ } /* This function is creating the fade effect for the LED */ void SetLED(uint16_t PWM) { setDutyCycle((uint32)PWM); /* Call the function which is setting the duty cycle of the PWM */ } /* This function sets the duty cycle of the PWM */ void setDutyCycle(uint32 dutyCycle) { g_atomConfig.dutyCycle = dutyCycle; /* Set duty cycle */ IfxGtm_Atom_Pwm_init(&g_atomDriver, &g_atomConfig); /* Re-initialize the PWM */ }
- Vadc模块
#include "ADC.h" #include "ASC.h" #include <stdio.h> /*********************************************************************************************************************/ /*------------------------------------------------------Macros-------------------------------------------------------*/ /*********************************************************************************************************************/ #define N_CHANNELS 1 /* Number of ADC channels that will be used */ #define ASCII_SHIFT 48 /* Shift in the ASCII table: '0', '1', '2'[...], start at value 48 */ /*********************************************************************************************************************/ /*-------------------------------------------------Global variables--------------------------------------------------*/ /*********************************************************************************************************************/ IfxAsclin_Asc g_asc; /* Handle for the ASC communication module registers */ IfxVadc_Adc g_vadc; /* Handle for VADC registers */ IfxVadc_Adc_Group g_adcGroup; /* Handle for the VADC group registers */ IfxVadc_Adc_Channel g_adcChannel[N_CHANNELS]; /* Handle for the VADC channel registers */ /* Define the used channels */ IfxVadc_ChannelId g_vadcChannelIDs[] = {IfxVadc_ChannelId_0}; void init_vadc(void) { /* Create and initialize the module configuration */ IfxVadc_Adc_Config adcConf; /* Define a configuration structure for the VADC module */ IfxVadc_Adc_initModuleConfig(&adcConf, &MODULE_VADC); /* Fill it with default values */ IfxVadc_Adc_initModule(&g_vadc, &adcConf); /* Apply the configuration to the module */ /* Create and initialize the group configuration */ IfxVadc_Adc_GroupConfig adcGroupConf; /* Define a configuration structure for the VADC group */ IfxVadc_Adc_initGroupConfig(&adcGroupConf, &g_vadc); /* Fill it with default values */ /* Configuration of the group */ adcGroupConf.groupId = IfxVadc_GroupId_0; /* 选择组0 */ adcGroupConf.master = adcGroupConf.groupId; /* Select the master group */ adcGroupConf.arbiter.requestSlotScanEnabled = TRUE; /* Enable scan source */ adcGroupConf.scanRequest.autoscanEnabled = TRUE; /* Enable auto scan mode */ /* Enable all gates in "always" mode (no edge detection) */ adcGroupConf.scanRequest.triggerConfig.gatingMode = IfxVadc_GatingMode_always; IfxVadc_Adc_initGroup(&g_adcGroup, &adcGroupConf); /* Apply the configuration to the group */ /* Create and initialize the channels configuration */ uint32 chnIx; /* Create channel configuration */ IfxVadc_Adc_ChannelConfig adcChannelConf[N_CHANNELS]; /* Define a configuration structure for the VADC channels */ for(chnIx = 0; chnIx < N_CHANNELS; ++chnIx) { IfxVadc_Adc_initChannelConfig(&adcChannelConf[chnIx], &g_adcGroup); /* Fill it with default values */ adcChannelConf[chnIx].channelId = g_vadcChannelIDs[chnIx]; /* Select the channel ID */ adcChannelConf[chnIx].resultRegister = (IfxVadc_ChannelResult)(chnIx); /* Use dedicated result register */ /* Initialize the channel */ IfxVadc_Adc_initChannel(&g_adcChannel[chnIx], &adcChannelConf[chnIx]); /* Add the channel to the scan sequence */ uint32 enableChnBit = (1 << adcChannelConf[chnIx].channelId); /* Set the the corresponding input channel */ uint32 mask = enableChnBit; /* of the respective group to take part in */ IfxVadc_Adc_setScan(&g_adcGroup, enableChnBit, mask); /* the background scan sequence. */ } /* Start the scan */ IfxVadc_Adc_startScan(&g_adcGroup); } int run_vadc(void) { uint32 chnIx; char Vadc_data[50]; /* Get the VADC conversions */ for(chnIx = 0; chnIx < N_CHANNELS; ++chnIx) { Ifx_VADC_RES conversionResult; /* Wait for a new valid result */ do { conversionResult = IfxVadc_Adc_getResult(&g_adcChannel[chnIx]); } while(!conversionResult.B.VF); /* B for Bitfield access, VF for Valid Flag */ sprintf(Vadc_data,"AN0:%d\n",conversionResult.B.RESULT); UART_Write(Vadc_data,20); int a = (int)conversionResult.B.RESULT; return a; } }
ASCLI-UART模块
#include "IfxAsclin_Asc.h"
#include "IfxCpu_Irq.h"
#include <stdio.h>
/*********************************************************************************************************************/
/*------------------------------------------------------Macros-------------------------------------------------------*/
/*********************************************************************************************************************/
#define UART_BAUDRATE 115200 /* UART baud rate in bit/s */
#define UART_PIN_RX IfxAsclin0_RXA_P14_1_IN /* UART receive port pin */
#define UART_PIN_TX IfxAsclin0_TX_P14_0_OUT /* UART transmit port pin */
/* Definition of the interrupt priorities */
#define INTPRIO_ASCLIN0_RX 18
#define INTPRIO_ASCLIN0_TX 19
#define UART_RX_BUFFER_SIZE 64 /* Definition of the receive buffer size */
#define UART_TX_BUFFER_SIZE 64 /* Definition of the transmit buffer size */
#define SIZE 13 /* Size of the string */
/*********************************************************************************************************************/
/*-------------------------------------------------Global variables--------------------------------------------------*/
/*********************************************************************************************************************/
/* Declaration of the ASC handle */
static IfxAsclin_Asc g_ascHandle;
/* Declaration of the FIFOs parameters */
static uint8 g_ascTxBuffer[UART_TX_BUFFER_SIZE + sizeof(Ifx_Fifo) + 8];
static uint8 g_ascRxBuffer[UART_RX_BUFFER_SIZE + sizeof(Ifx_Fifo) + 8];
/* Definition of txData and rxData */
uint8 g_txData[] = "Hello World!";
uint8 g_rxData[SIZE] = {''};
/* Size of the message */
Ifx_SizeT g_count = sizeof(g_txData);
/*********************************************************************************************************************/
/*---------------------------------------------Function Implementations----------------------------------------------*/
/*********************************************************************************************************************/
/* Adding of the interrupt service routines */
IFX_INTERRUPT(asclin0TxISR, 0, INTPRIO_ASCLIN0_TX);
void asclin0TxISR(void)
{
IfxAsclin_Asc_isrTransmit(&g_ascHandle);
}
IFX_INTERRUPT(asclin0RxISR, 0, INTPRIO_ASCLIN0_RX);
void asclin0RxISR(void)
{
IfxAsclin_Asc_isrReceive(&g_ascHandle);
}
/* This function initializes the ASCLIN UART module */
void init_ASCLIN_UART(void)
{
/* Initialize an instance of IfxAsclin_Asc_Config with default values */
IfxAsclin_Asc_Config ascConfig;
IfxAsclin_Asc_initModuleConfig(&ascConfig, &MODULE_ASCLIN0);
/* Set the desired baud rate */
ascConfig.baudrate.baudrate = UART_BAUDRATE;
/* ISR priorities and interrupt target */
ascConfig.interrupt.txPriority = INTPRIO_ASCLIN0_TX;
ascConfig.interrupt.rxPriority = INTPRIO_ASCLIN0_RX;
ascConfig.interrupt.typeOfService = IfxCpu_Irq_getTos(IfxCpu_getCoreIndex());
/* FIFO configuration */
ascConfig.txBuffer = &g_ascTxBuffer;
ascConfig.txBufferSize = UART_TX_BUFFER_SIZE;
ascConfig.rxBuffer = &g_ascRxBuffer;
ascConfig.rxBufferSize = UART_RX_BUFFER_SIZE;
/* Pin configuration */
const IfxAsclin_Asc_Pins pins =
{
NULL_PTR, IfxPort_InputMode_pullUp, /* CTS pin not used */
&UART_PIN_RX, IfxPort_InputMode_pullUp, /* RX pin */
NULL_PTR, IfxPort_OutputMode_pushPull, /* RTS pin not used */
&UART_PIN_TX, IfxPort_OutputMode_pushPull, /* TX pin */
IfxPort_PadDriver_cmosAutomotiveSpeed1
};
ascConfig.pins = &pins;
IfxAsclin_Asc_initModule(&g_ascHandle, &ascConfig); /* Initialize module with above parameters */
}
/* This function sends and receives the string "Hello World!" */
void send_receive_ASCLIN_UART_message(void)
{
IfxAsclin_Asc_write(&g_ascHandle, g_txData, &g_count, TIME_INFINITE); /* Transmit data via TX */
IfxAsclin_Asc_read(&g_ascHandle, g_rxData, &g_count, TIME_INFINITE); /* Receive data via RX */
}
void UART_WriteByte(uint8 data)
{
IfxAsclin_Asc_blockingWrite(&g_ascHandle, data);
}
void UART_Write(uint8 *p_data, Ifx_SizeT count)
{
uint8 *p_send = p_data;
if(count > 0)
IfxAsclin_Asc_write(&g_ascHandle, p_data, &count, TIME_INFINITE);
else
{
while(*p_send != (uint8)'\0')
UART_WriteByte(*p_send++);
}
}
心得体会:
本次活动任务相当简单,在快速入门TC275的时候,这让我想起21年电赛A题,当时没有准备TI的开发板,就有了快速入门TI - MSP432的经历,一样的流程如今在来一番有特别的感受,相较而言英飞凌的文档和教程做的相当完善,官方历程每一条都有注释,非常非常的友好,而当时ti就比较困难,我们是参考第三方教程,根据唯一的一份数据手册去完成ADC+DMA的1M采样率和DSP库的添加。同样,我也感到经过这一年来自己的读文档能力有了不小的提升。这是我第一次接触英飞凌的单片机,这颗TCP275的多核还没有用到,这块板子上还有CAN接口,可以在今后继续学习和使用!同时非常感谢硬禾学堂老师们的付出!