【电机控制】TC275芯片——ADC外设驱动的配置与实现
文章目录
- 前言
- 一、TC275芯片ADC外设介绍
- 二、代码配置
- 1.ADC初始化
- 2.ADC采样
- 总结
前言
ADC驱动外设用于将模拟信号转换为数字信号,是嵌入式系统中的重要组件。它负责将模拟信号(如电压、温度、压力等)转换为可被处理器理解的数字信号;同时从传感器或其他外部模拟设备获取数据,并将其转换为数字形式供后续处理,在电机控制中电流,电压,温度等参数的精确获取对电机控制性能有着至关重要的作用,因此对ADC外设的合理配置显得至关重要。
一、TC275芯片ADC外设介绍
示例:pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。
上述两张照片中可以发现TC275芯片的ADC外设资源一共有8组,每组有8个频道,合计一共有64个接口,而TC275芯片为三核,则一共有192个接口,参考电压为VAREF2(5\3.3V),芯片上的每个引脚对应一个采样通道。
上述两张照片中主要说明了在ADC采样过程中,采样率,采样时间以及采样结果的配置方式,其中需要注意的是采样率和采样时间参数配置方式是通过两个输入组globalInputClass[0]
和globalInputClass[1]
来配置的,在下面的代码配置会有提到的。
二、代码配置
在英飞凌的ADS编译器中,导入ADC驱动例程中,可以发现有五种采样方式:
- ADC Background Scan(背景扫描):这种方式下,ADC在后台运行,不需要CPU干预。多个通道可以自动依次进行转换,适合在系统中持续监控多个传感器的情况。
- ADC Filtering(滤波采样):用于对输入的模拟信号进行滤波处理,以去除噪声或不必要的干扰。可以通过软件或硬件滤波对信号进行预处理,适合信号噪声较大时使用。
- ADC Group Scan(组扫描):将ADC通道分组,每个组内的通道可以依次进行扫描。适合多通道传感器应用中,按组别进行测量的情况。
- ADC Queued Scan(队列扫描):允许用户将多个通道加入到队列中,按照预定顺序进行扫描。适合需要特定顺序采样的应用场景,且灵活度较高。
- ADC Single Channel(单通道采样):只采集单个ADC通道的数据,适合只需单个传感器数据的简单应用场景。
下面我以组扫描为模版进行配置(建议仔细研究一下这五种ADC采样方式),分为ADC初始化和ADC扫描这两个方面来进行代码配置。
1.ADC初始化
void SingleADC_Init(uint8 group_i, uint8 chnIx) /*only config a single channel to the scan mode*/
{
IfxVadc_Adc_Config adcConfig;
IfxVadc_Adc_initModuleConfig(&adcConfig, &MODULE_VADC);
adcConfig.startupCalibration = TRUE;
adcConfig.globalInputClass[0].resolution = IfxVadc_ChannelResolution_12bit;
adcConfig.globalInputClass[0].sampleTime = 1.0e-6;
IfxVadc_Adc_initModule(&vadc, &adcConfig);
IfxVadc_Adc_GroupConfig adcGroupConfig;
IfxVadc_Adc_initGroupConfig(&adcGroupConfig, &vadc);
{
adcGroupConfig.groupId = group_i;
adcGroupConfig.master = adcGroupConfig.groupId;
adcGroupConfig.arbiter.requestSlotScanEnabled = TRUE;
adcGroupConfig.scanRequest.triggerConfig.gatingMode = IfxVadc_GatingMode_always;
IfxVadc_Adc_initGroup(&adcGroup[group_i], &adcGroupConfig);
}
{
IfxVadc_Adc_ChannelConfig adcChannelConfig[8];
IfxVadc_Adc_initChannelConfig(&adcChannelConfig[chnIx], &adcGroup[group_i]);
adcChannelConfig[chnIx].channelId = (IfxVadc_ChannelId)(chnIx);
adcChannelConfig[chnIx].resultRegister = (IfxVadc_ChannelResult)(chnIx);
adcChannelConfig[chnIx].resultServProvider = IfxSrc_Tos_cpu0;
adcChannelConfig[chnIx].channelServProvider = IfxSrc_Tos_cpu0;
IfxVadc_Adc_initChannel(&adcChannel[group_i][chnIx], &adcChannelConfig[chnIx]);
unsigned channels = (1 << adcChannelConfig[chnIx].channelId);
unsigned mask = channels;
IfxVadc_Adc_setScan(&adcGroup[group_i], channels, mask);
}
}
- 这里我编写了
void SingleADC_Init(uint8 group_i, uint8 chnIx)
函数,通过传入group_i
(组号)和chnIx
(通道号)来实现对需要的通道进行初始化,不需要利用for
循环对多组和多通道进行初始化了,提高了代码的运行效率。 - 使用
globalInputClass[0]
配置采样精度为IfxVadc_ChannelResolution_12bit
即4096,采样时间为1.0e-6
。 1 << adcChannelConfig[chnIx].channelId
如果 channelId = 3,则操作相当于 1 << 3,结果是 0b00001000,即第4个位置(从0开始计数)是 1,表示通道3被选择。左移 1 是为了生成一个位掩码,以选择对应的ADC通道。每个通道都对应掩码中的某一位,左移操作可以将数字1移动到指定通道的位置,标记该通道的选择状态。
1 << 0 = 0b00000001 (表示通道 0)
1 << 1 = 0b00000010 (表示通道 1)
1 << 2 = 0b00000100 (表示通道 2)
1 << 3 = 0b00001000 (表示通道 3)
2.ADC采样
void Temp_Voltage_DetectScan(void)
{
Ifx_VADC_RES conversionResult;
IfxVadc_Adc_startScan(&adcGroup[3]);
do
{
conversionResult = IfxVadc_Adc_getResult(&adcChannel[3][5]);
} while (!conversionResult.B.VF);
ADC_result[3][5] = conversionResult.B.RESULT;
do
{
conversionResult = IfxVadc_Adc_getResult(&adcChannel[3][2]);
} while (!conversionResult.B.VF);
ADC_result[3][2] = conversionResult.B.RESULT;
do
{
conversionResult = IfxVadc_Adc_getResult(&adcChannel[3][1]);
} while (!conversionResult.B.VF);
ADC_result[3][1] = conversionResult.B.RESULT;
IfxVadc_Adc_startScan(&adcGroup[2]);
do
{
conversionResult = IfxVadc_Adc_getResult(&adcChannel[2][4]);
} while (!conversionResult.B.VF);
ADC_result[2][4] = conversionResult.B.RESULT;
do
{
conversionResult = IfxVadc_Adc_getResult(&adcChannel[2][5]);
} while (!conversionResult.B.VF);
ADC_result[2][5] = conversionResult.B.RESULT;
Vphase_Vpower = ADC_result[3][2] * Factor_phase_Vpower * Factor_DAC;
g_bldc.Voltage_BUS = (uint8)Vphase_Vpower;
Vphase_U = ADC_result[2][5] * Factor_phase_Vpower * Factor_DAC;
Vphase_V = ADC_result[2][4] * Factor_phase_Vpower * Factor_DAC;
Vphase_W = ADC_result[3][1] * Factor_phase_Vpower * Factor_DAC;
}
- 这里注意在不同组开始扫描时注意需要重新开启组扫描,
IfxVadc_Adc_startScan(&adcGroup[2])
和IfxVadc_Adc_startScan(&adcGroup[3])
; - 电压采集后需要乘以精度系数
Factor_DAC
(参考电压5V/采样精度4096)以及电路放大倍数Factor_phase_Vpower
.得到实际电压值。 - 通过
do {} while (!conversionResult.B.VF)
循环,不断检查是否获得有效的ADC值,然后将采集的得到ADC值保存到对应的数组中。
总结
在TC275芯片中ADC采样中有多种采样方式,大家根据自己实际需求去选择合适的采样方法,希望这篇文章能帮助到大家!