【MCAL】TC397+EB-tresos之Port&Dio配置实战 - LED灯闪烁

本文详细描述了在TC397平台使用EB-tresos工具配置Port和Dio驱动模块的过程,以实现P33.1引脚控制D107LED的1秒闪烁。涉及Port和Dio的原理、配置步骤以及相关软件和硬件环境。

本篇文章介绍了在TC397平台使用EB-tresos对Port和Dio驱动模块进行配置的实战过程,配置完成之后,烧录到开发板上之后,对应的D107发光二极管会以一秒为周期进行闪烁。

目录

概述

Port简介

Dio简介

环境与目标 

EB-tresos配置

Port配置 

PortGeneral

PortContainer

Dio配置

DioGeneral

DioPort 

DioChannel

DioChannelGroup 

MCU配置 

ResourceM配置 

Port&Dio驱动使用与调试


概述

每个端口都有自己独立的“Port slice”,它们控制一组对应的输入/输出(GPIO) 硬线,这些硬线
由芯片封装外露引脚或焊盘连接至对应独立的pad之后再按照不同端口连接到对应的“Port slice”。

下图为TC3xx系列芯片的端口引脚的一般结构。

下图中红色全出的部分为Port与Dio在AUTOSAR架构中的位置,注意Port与Dio不可同日而语,Port是对硬线的配置,包括数字IO以及各种外设复用,而Dio提供数字IO的一层索引号,方便应用层控制数字IO高低。


Port简介

Port驱动程序可帮助用户将不同端口的引脚分配给外设或当作普通数字IO使用,并提供配置由底层硬件提供的特性或配套功能。由于引脚有限,这些不同端口引脚共享片上外设,往往一个端口可以配置成不同的模式。但是需要注意的是,在任何给定时间点,端口引脚都只会工作在一个特定的模式(分配给特定的片内外设)。下面这张图介绍了软硬件调用关系(Mapping of hardware-software interfaces)。


Dio简介

Port外设的使用责任由AUTOSAR拆分为两个模块。Port驱动程序配置和设置端口引脚的属性。Dio 驱动程序读取或写入到数字IO引脚 。Dio 驱动程序提供基于Port的通道和通道组读写访问
来驱动内部数字IO端口。Dio 驱动程序中的所有读取和写入服务均未缓冲。通道对应于单个通用 IO 引脚,通道组是指由一个逻辑组表示的多个相邻 Dio 通道的配置的逻辑组合。请注意,Dio 通道组应属于一个 Dio Port。一个Dio Port对应一个芯片的“Port slice”。下图为Dio模块的软硬件调用关系(Mapping of hardware-software interfaces)。


环境与目标 

本文使用的为英飞凌提供的开发板KIT_A2G_TC397XA_TFT,参照原理图可以看到P33.1~P33.4连接到了D107~D110四个发光二极管

涉及的软件如下。

涉及的参考文档如下表。

序号参考资料内容
1《MC-ISAR_TC3xx_UM_Mcu.pdf》英飞凌提供的针对TC3xx芯片MCAL配置用户手册
《ApplicationKitManual-TC3X7-ADAS-V21.pdf》开发板KIT_A2G_TC397XA_TFT说明
2《MC-ISAR_TC3xx_Config_Verification_Manual_Port.pdf》英飞凌提供的针对TC3xx芯片Port配置验证手册,介绍动态代码与配置项的对应。
3《MC-ISAR_TC3xx_Config_Verification_Manual_Dio.pdf》英飞凌提供的针对TC3xx芯片Dio配置验证手册,介绍动态代码与配置项的对应。
4《MC-ISAR_TC3xx_UM_Dio.pdf》英飞凌提供的TC39x芯片Dio用户手册
5《MC-ISAR_TC3xx_UM_Port.pdf》英飞凌提供的TC39x芯片Port用户手册

配置目标如下。

芯片引脚对端方向模式
P33.1D107OUTGPIO

EB-tresos配置

打开EB工程,增加Dio和Port模块至工程中。


Port配置 

PortGeneral

这里我们主要关注两个配置项。

  • PortSetPinDirectionApi:用于配置Port_SetPinDirection()接口是否提供给应用层可用,API端口引脚运行时引用引脚的方向。下图为API说明。

  • PortSetPinModeApi:用于配置Port_SetPinMode()驱动接口是否提供给应用层可用。API用于设置Pin的复用模式,例如CAN或者SPI之类的。下图为API说明。


PortContainer

因为我们要操作的是P33.1,则我们如下图根据PortNumber选择到了序号为14的Container。

点进去之后,因为我们是P33.1,则选择PortPin_1。双击打开配置。

下图就是具体P33.1的配置界面。

下面介绍一下我们常用的配置项。

  • Name:引脚命名,修改为PortPin_D107表意到开发板上发光二极管的丝印。
  • PortPinDirection:引脚方向,配置为PORT_PIN_OUT,输出。
  • PortPinDirectionChangeable:引脚的方向可以在程序运行时修改。
  • PortPinInitialMode:引脚的模式,可以通过查芯片手册查看不同复用模式,这里我们就用作普通IO口,所以选择GPIO即可
  • PortPinLevelValue:初始电平状态,因为我们需要上电D107是熄灭的,根据原理图可得此处应该配置为高。
  • PortPinModeChangeable:引脚的模式可以在程序运行时修改。
  • PortPinInputPullResistor:是否内接上/下拉电阻,此处不需要,选择PORT_PIN_IN_NO_PULL即可。
  • PortPinOutputPinDriveMode:引脚的驱动模式,可以按需要配置为推挽或者是开漏,此处配置为推挽。

Dio配置

DioGeneral

我们主要关注一下配置。

  • DioFlipChannelApi:打开电平反转函数Dio_FlipChannel(),API说明如下。

  • DioDevErrorDetect:默认错误跟踪器 (Det) 检测和通知开关,我们这里不用,不勾选即可。
  • DioSafetyEnable:安全检查和所有相关通知,这里我们不用,不勾选即可。


DioPort 

添加一条,修改DioPortId为33(因为我们操作的IO口为P33下的)。


DioChannel

点进去这个DioPort,选择DioChannel容器,增加一个Channel,注意DioChannelID需要选择为1(因为我们操作的IO口为P33.1),Channel名称表意连接的是D107发光二极管。


DioChannelGroup 

这里提供同时操作一组IO口的Channel组,我们暂时用不到,主要是DioPortMask配置,如果配置成0x06,即可控制Pin1和Pin2。


MCU配置 

因为示例中需要用到延时,需要使用系统定时器,这里只用了Stm的Tick,所以不需要添加STM模块,使用MCU的STM即可。


ResourceM配置 

配置核心使用资源,在CORE0中添加STM。


Port&Dio驱动使用与调试

将代码在EB生成之后,因为动态代码会生成到HighTec工程里,则不需要再剪切到工程里,直接使用HighTec编译之后,使用UDE下载到板卡中即可。下面是示例代码的Cpu0_Main.c如下。

#include "Ifx_Ssw_Infra.h"
#include "IFX_Os.h"

#include "Port.h"
#include "Dio.h"
#include "McalLib.h"


//stm 100MHZ ticks 0.00000001s, 1s 100000000
void delay_ms(uint32 ms)
{
  uint32 CurrSTMTick = Mcal_DelayGetTick();
  uint32 BaseSTMTick = CurrSTMTick;
  while ((uint32)((CurrSTMTick - BaseSTMTick) & 0xffffffff) <
           ms * 100000)
  {
    CurrSTMTick = Mcal_DelayGetTick();
  }
}


void core0_main (void)
{
  volatile unsigned short LoopFlag = 1U;
  unsigned short cpuWdtPassword;
  unsigned short safetyWdtPassword;

  ENABLE();
  /*
   * !!WATCHDOG0 AND SAFETY WATCHDOG ARE DISABLED HERE!!
   * Enable the watchdog in the demo if it is required and also service the watchdog periodically
   * */
  cpuWdtPassword = Ifx_Ssw_getCpuWatchdogPassword(&MODULE_SCU.WDTCPU[0]);
  safetyWdtPassword = Ifx_Ssw_getSafetyWatchdogPassword();
  Ifx_Ssw_disableCpuWatchdog(&MODULE_SCU.WDTCPU[0], cpuWdtPassword);
  Ifx_Ssw_disableSafetyWatchdog(safetyWdtPassword);

  /* init gpio high, led close */
  Port_Init(&Port_Config);

  while (LoopFlag == 1U)
  {
    /* close led */
    Dio_WriteChannel(DioConf_DioChannel_D107_LED_P33_1, STD_HIGH);
    delay_ms(500);
    /* open led */
    Dio_WriteChannel(DioConf_DioChannel_D107_LED_P33_1, STD_LOW);
    delay_ms(500);
  }
}

测试的结果可以看到灯以1秒周期闪烁。使用示波器直接量R106主控芯片一侧与地电压如下。


十六宿舍 原创作品,转载必须标注原文链接。

©2023 Yang Li. All rights reserved.

欢迎关注 『十六宿舍』,大家喜欢的话,给个👍,更多关于嵌入式相关技术的内容持续更新中。

<think>嗯,用户之前问过如何用STM控制方波宽度,我给出了详细的步骤,包括代码示例。现在用户的新问题集中在EB(可能指EB tresos,一种汽车电子开发工具)自动生成代码和手动编写代码的区别上。用户提到EB会自动生成动态代码,但之前的回答中我提到了编写代码的部分,这让他感到困惑。用户的具体需求是利用EB配置DIO、PORT和STM模块来实现输出方波,例如运行一秒钟后输出宽度为一秒的方波,想知道哪些部分由EB生成,哪些需要手写。 首先,我需要确认用户对EB tresos的理解是否正确。EB tresos是用于配置MCU外设并生成初始化代码的工具,用户通过图形界面配置参数,然后生成底层驱动代码。但应用逻辑,如中断服务函数和主程序中的控制流程,通常需要手动编写。用户可能误以为所有代码都可以自动生成,但实际上只有配置相关的代码是自动生成的,而业务逻辑需要自己添加。 接下来,我需要明确用户的具体需求:在运行一秒钟后输出一个宽度为一秒的方波。这意味着需要两个定时器:一个用于延时一秒,另一个用于生成方波。或者使用同一个定时器分阶段配置。用户可能没有意识到定时器的不同工作模式或如何组合多个配置来实现这个功能。 然后,我需要分析之前的回答,查看是否有地方让用户误解。之前的步骤中提到了配置STM模块、计算比较值、设置中断和GPIO,以及编写中断服务函数和主函数。这些步骤中,配置部分(如时钟源、分频、GPIO模式)可以通过EB自动生成,而中断服务函数和主函数中的控制逻辑需要手动编写。可能在之前的回答中没有明确区分自动生成和手写部分,导致用户困惑。 现在需要明确回答用户的问题,区分EB自动生成的部分和需要手写的部分,并结合他的具体需求(延时一秒后输出方波)来说明。可能需要详细说明EB生成的代码结构,例如生成的配置函数、初始化代码,以及用户需要补充的中断处理和应用逻辑。 同时,用户可能对如何整合自动生成的代码和手写代码存在疑问,需要给出具体的例子,比如在main函数中调用生成的初始化函数,然后添加自己的定时器启动和中断处理。此外,用户提到的“动态代码”可能指的是EB根据配置自动生成的初始化代码,而用户需要编写的是动态控制的部分,如修改占空比、处理中断等。 另外,用户的需求中有一个延时一秒后输出方波,这可能需要使用另一个定时器或者利用STM模块的不同通道来实现。需要解释如何配置两个定时器或者如何在一个定时器中实现不同的阶段。例如,先配置定时器为1秒的延时,然后在中断中重新配置定时器为方波生成模式。 最后,需要检查是否有术语使用不当,比如“动态代码”是否正确,是否需要更准确的解释,避免用户混淆。同时,可能需要提供更具体的代码示例,说明哪些部分由EB生成,哪些需要手动添加,帮助用户明确开发流程。</think>### **EB自动生成代码与手动编程的详细区分** 对于使用EBEB tresos配置STM、DIO和Port模块实现方波输出的场景,以下是自动生成代码与手动编程的明确分界: --- #### **1. EB自动生成的部分(无需手写)** EB通过图形化配置工具生成底层硬件驱动代码,包括: 1. **硬件寄存器初始化** - STM时钟源选择、分频系数设置 - GPIO引脚方向(输入/输出)配置 - 中断优先级和向量表配置 2. **生成初始化函数** ```c void STM_Init(void); // STM模块初始化 void Port_Init(void); // GPIO引脚初始化 void IRQ_Init(void); // 中断控制器配置 ``` 3. **硬件抽象层接口** - 寄存器访问宏定义(例如`STM0_COMPARE`地址映射) - 中断服务函数框架(需用户填充具体逻辑) --- #### **2. 需要手动编写的部分** 以下代码需用户根据业务逻辑自行实现: 1. **中断服务函数(核心控制逻辑)** ```c // EB生成中断函数框架,但内部逻辑需用户填充 void STM_CompareMatch_ISR(void) { Dio_WriteChannel(PIN_14_0, TOGGLE); // 手动编写电平翻转 STM_ClearCompareFlag(STM0); // 手动清除中断标志 } ``` 2. **动态参数调整代码** ```c // 修改方波宽度(EB不会生成此逻辑) void UpdatePulseWidth(uint32 new_width) { STM_StopTimer(STM0); STM_SET_COMPARE(STM0, new_width); STM_StartTimer(STM0); } ``` 3. **主程序控制流** ```c int main(void) { Port_Init(); // EB生成 STM_Init(); // EB生成 STM_StartTimer(STM0); // 手动启动定时器 // 手动添加1秒延时逻辑 delay(1000); // 需自行实现或调用系统延时 UpdatePulseWidth(1000000); // 修改脉宽为1秒 } ``` --- ### **针对需求的具体实现方案** **目标**:系统运行1秒后,输出一个宽度为1秒的方波。 --- #### **步骤1:EB图形化配置** 1. **STM模块配置** - 选择`STM0`通道,时钟源设为`FCLK=100MHz`,分频系数=0 - 使能比较匹配中断(Compare Match Interrupt) 2. **Port模块配置** - 配置P14.0引脚为输出模式,初始电平为低 3. **生成代码** - 点击Generate Code,EB自动生成`Stm.c`、`Port.c`等驱动文件 --- #### **步骤2:手动编写的关键代码** 1. **中断服务函数(填充EB生成的框架)** ```c volatile uint32_t timer_counter = 0; // 全局计时变量 void STM_CompareMatch_ISR(void) { if (timer_counter < 1) { // 第1秒内保持低电平 Dio_WriteChannel(PIN_14_0, LOW); timer_counter++; } else { // 1秒后触发1秒宽度的方波 Dio_WriteChannel(PIN_14_0, HIGH); STM_StopTimer(STM0); // 保持高电平1秒 } STM_ClearCompareFlag(STM0); } ``` 2. **主函数逻辑** ```c int main(void) { Port_Init(); // EB生成 STM_Init(); // EB生成 STM_SetCompareValue(STM0, 100000); // 初始比较值=0.1ms(仅用于触发中断) STM_StartTimer(STM0); while(1) { // 无操作,依赖中断控制 } } ``` --- ### **自动生成代码 vs 手动代码对比表** | 代码类型 | 示例 | 是否由EB生成 | |------------------|-------------------------------|--------------| | 硬件初始化 | `STM_Init();` `Port_Init();` | ✔️ | | 寄存器定义 | `#define STM0_BASE 0xF0000000`| ✔️ | | 中断框架 | `void STM_CompareMatch_ISR()` | ✔️(框架) | | 电平翻转逻辑 | `Dio_WriteChannel(...)` | ❌ | | 动态参数修改 | `UpdatePulseWidth()` | ❌ | | 主程序流程控制 | `while(1)`中的逻辑 | ❌ | --- ### **常见误区解释** 1. **"EB自动生成所有代码"** - EB仅生成与硬件配置相关的**静态代码**,无法自动实现**动态业务逻辑**(如条件判断、状态机)。 2. **"中断函数可以完全自动生成"** - EB会生成中断函数框架,但**何时触发IO翻转**、**如何修改比较值**等逻辑必须手动编写。 3. **"周期和脉宽可以直接在EB界面设置"** - EB只能配置硬件工作模式,**具体数值**(如1秒)需通过代码动态计算和赋值。 --- ### **调试建议** 1. **验证自动生成代码** - 检查`Stm_Cfg.c`中`STM0`的配置是否与EB界面一致: ```c const Stm_ConfigType StmConfig = { .channel = STM0, .clockSource = STM_CLKSRC_FCLK, .prescaler = 0 }; ``` 2. **使用调试器跟踪中断** - 在`STM_CompareMatch_ISR()`中设置断点,观察`timer_counter`变量变化。 3. **示波器验证波形** - 测量P14.0引脚输出,确认: - 前1秒保持低电平 - 之后持续1秒高电平 是否需要进一步解释如何结合EB配置与手动代码实现更复杂的时序?
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值