本文主要是介绍【Autosar】MCAL - ADC(NXP - S32K14x),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
文章目录
- MCAL - ADC(NXP - S32K14x)
- 1. 概述
- 1.1 输入时钟
- 1.2 数据转换
- 1.3 触发方式
- 1.4 触发模式
- 2. API
- 3. 配置介绍
- 3.1 General
- 3.2 AdcHwUnit
- 3.2.1 General
- 3.2.2 AdcPdbSettings
- 3.2.3 AdcChannel
- 3.2.4 AdcGroup
- 3.2.3.1 General(通道组通用配置)
- 3.2.3.2 AdcGroupNormalCobersionTimings(硬件平均值设置)
- 3.2.3.3 AdcGroupDefinition
- 3.2.3.4 AdcChannelDelay(触发延时时间)
- 3.3 AdcInterrupt
- 3.4 数据缓存(Single/Streaming)
- 3.4.1 Single
- 3.4.2 Streaming
- 3.4.3 buffer size 计算
- 3.5 数据读取(ReadGroup / ReadStreaming)
- 3.5.1 ReadGroup
- 3.5.2 ReadStreaming
MCAL - ADC(NXP - S32K14x)
MCAL - 汇总
- 配置工具:EB Tresos Studio
- 芯片类型:S32K146
1. 概述
ADC模块是将模拟信号(连续)转换成数字信号(离散)。MCU采集到的外部数据如温度、电压、电流等物理量是无法直接被CPU识别并处理的,因此要通过ADC模块将这些模拟信号转换成数字信号才能够被CPU处理。
S32K146的ADC模块如下图所示:
1.1 输入时钟
ADC模块可选的输入时钟有:SOSCDIV2_CLK
、SIRCDIV2_CLK
、FIRCDIV2_CLK
、SPLLDIV2_CLK
。
1.2 数据转换
ADC模块通过采集通道获取采集的电压值,将该值与参考电压进行比较,通过转换模块转换成数字信号。比如参考电压是10V,采集电压是5V,采样精度为12bit(4096),那么转换后得到值为4096 / 10 * 5 = 2048。可选的采样精度有8bit、10bit、12bit。
1.3 触发方式
ADC模块的触发方式分为两种:软件触发、硬件触发。
软件触发是通过写ADCH
寄存器触发转换。
硬件触发是通过其他模块对ADHWT
输入脉冲来触发转换。S32K146芯片的默认硬件触发源是PDB模块。
1.4 触发模式
S32K14x ADC模块的触发逻辑如下:软件触发使用的也是PDB模块、硬件触发可以是PDB或者其他TRGMUX
ADC的触发模式有两种:单次触发、连续触发。
单次触发就是触发一次ADC转换后就结束,只会触发一次ADC中断。在NXP的ADC模块中,利用PDB(延时触发)实现单次触发,触发之后停止。
连续触发就是触发一次ADC转换,转换完成后继续触发下一次,当用户配置停止转换后才会结束。在NXP的ADC模块中,连续触发模式是利用PDB(延时触发)模块实现。PDB模块类似定时器,有一个设定值(MOD)和计数值(CNT),当计数值累计到设定值时,对ADHWT
输出脉冲,触发ADC模块进行转换,当完成一次转换后触发ADC中断,在中断服务函数中对PDB模块的计数值清零,开始下一次延时触发。
以下为软件触发流程图:在Adc_Adc12bsarv2_UpdateSoftwareGroupState
函数中可以找到触发后的处理逻辑。
2. API
函数 | 描述 |
---|---|
Adc_Init | ADC模块初始化 |
Adc_SetupResultBuffer | 设置转换结果缓存区 |
Adc_DeInit | 将ADC驱动模块恢复至默认状态 |
Adc_StartGroupConversion | 打开通道组所有通道开始转换 |
Adc_StopGroupConversion | 停止通道组所有通道转换 |
Adc_ReadGroup | 获取通道组转换结果 |
Adc_EnableHardwareTrigger | 使能ADC转换组为硬件触发方式 |
Adc_DisableHardwareTrigger | 关闭ADC转换组为硬件触发方式 |
Adc_EnableGroupNotification | 使能ADC转换通道组的事件通知 |
Adc_DisableGroupNotification | 关闭ADC转换通道组的事件通知 |
Adc_GetGroupStatus | 获取ADC转换通道组的状态 |
Adc_GetStreamLastPointer | 获取结果缓存的最后指针 |
Adc_GetVersionInfo | 获取ADC模块版本信息 |
3. 配置介绍
3.1 General
Adc Hw Trigger API:
硬件触发API
Adc StartStopGroup API:
开始/停止转换API
Adc ReadGroup API:
读取通道组转换结果
Adc Notification Capability:
打开中断回调功能,勾选了以后才能触发中断回调
#if (ADC_GRP_NOTIF_CAPABILITY == STD_ON)
/* Implement user notification function if available */
Adc_Adc12bsarv2_HwSwCheckNotification(Group);
#endif /* (ADC_GRP_NOTIF_CAPABILITY == STD_ON) */
3.2 AdcHwUnit
硬件单元配置:S32K146有ADC0、ADC1,所以这里可以建两个配置。
3.2.1 General
ADC硬件通用配置
Adc Transfer Type:
传输类型,可选的有DMA和Interrupt,DMA是直接绕过CPU将转换结果存到RAM;Interrput是触发ADC中断,然后用户读取转换结果。
Adc Voltage Reference Selection:
参考电压选择,一般情况下都选VREFH_VREFL
。
Adc Resolution:
采样精度
3.2.2 AdcPdbSettings
PDB部分配置
Adc Pdb Prescaler Divider Slect:PDB时钟预分频
Adc Pdb Multiplication Factor Select for Prescaler:乘法因子
上面这两个参数决定了PDB模块的时钟:PDB时钟 = SYS_CLK / (Prescaler Divider * Multiplication Factor)
3.2.3 AdcChannel
采样通道配置:在这里新建采样通道,然后在AdcGroup
中引用,一个group中可以统一管理多个channel。
3.2.4 AdcGroup
3.2.3.1 General(通道组通用配置)
Adc Group Access Mode:
Buffer访问方式(单次/流)
Adc Group Conversion Mode:
转换模式(连续\单次)
Adc Group Trigger Source:
触发方式(硬件\软件)
Adc Group Notification:
中断回调
Adc Group Streaming Buffer Mode:
流模式Buffer模式(线性/回环)
Adc Group Streaming Number Samples:
流模式采样个数
Adc Group In Back to Back Mode:
Adc Group Without Interrupts:
启动后不会触发ADC中断,结果只能通过Read_Group直接从寄存器读取(未启用情况下是中断触发后,先将数据读到buffer,调用Read_Group时从Buffer获取数据),启动后连续模式将有PDB实现(PDB可以配置成连续模式自动触发)。
Adc Group Uses Channel Delays:
启动延时转换
3.2.3.2 AdcGroupNormalCobersionTimings(硬件平均值设置)
Adc Haedware Average Select:
采样个数(采样N个值以后计算平均值后触发中断)
Adc Sample Time Duration:
采样时间(N个ADC时钟周期,采样时间越长数据越精确)
Adc Clock Divide Select:
ADC时钟分频
从下图可以知道如何计算ADC总的转换时间。
3.2.3.3 AdcGroupDefinition
通过通道组统一操作通道,因此将需要的Channel添加到通道组中。
3.2.3.4 AdcChannelDelay(触发延时时间)
PDB计时到后触发ADC进行转换。
公式:延时时间 = SYS_CLK / (Prescaler * mult) * delay
3.3 AdcInterrupt
使能ADC中断
3.4 数据缓存(Single/Streaming)
3.4.1 Single
Single模式下,Buffer模式只能选择Liner
,Streaming Number Samples
只能设置为1,这种情况下理论上是采样完一次后就应该停止转换(看很多博主都是这样介绍),但是可以看到NXP如下的代码中,并不会去判断Single模式,所以在Single模式下会一直转换。实际配置完成后现象也是如此。
3.4.2 Streaming
Liner
:线性模式
Liner模式下,Streaming Number Samples
配置为n,当采样次数达到n次后,停止转换。简而言之就是将buffer存满后,停止转换。
Circular
:回环模式
Circular模式下,Streaming Number Samples
配置为n,当采样次数达到n次后,从头开始覆盖。
3.4.3 buffer size 计算
在我们的程序中需要调用Adc_SetupResultBuffer
设置结果缓存区,所以我们要合理的设置缓存区大小避免内存溢出。
buffer size = channer number(通道组中的通道数) * Streaming Number
3.5 数据读取(ReadGroup / ReadStreaming)
调用这两个函数都会重置采样个数。因此假如我配置的是循环、线性模式,在触发中断后采样数会重置,导致无法累计到采样停止转换,会一直循环。在线性模式下,采样个数要>1会发生这种现象,因为中断先判断采样次数,发现已达上限,则停止,然后才是触发中断回调
if (ADC_COMPLETED == Adc_aGroupStatus[Group].eConversion){Adc_aGroupStatus[Group].ResultIndex = 0U; //下一次转换之前会判断这个值是否大于设定的采样个数/* ADC331 -- ADC222*/Adc_aGroupStatus[Group].eConversion = ADC_BUSY;}
效果如图所示,我配置的sample number为5,但是每次中断调用上述这两个函数后,会重置采样数,导致数据一直存在第一个缓存区里面,并且会一直循环。
如果不调用这两个函数读取数据,单纯打印缓存区数据,如下图所示,数据会依顺序存入:
3.5.1 ReadGroup
void ADC_Group0_Notification(void)
{uint16_t vbat = 0;printf("buffer:[1]%d\t[2]%d\t[3]%d\t[4]%d\t[5]%d\t\r\n", group0_result_buffer[0],group0_result_buffer[1],group0_result_buffer[2],group0_result_buffer[3],group0_result_buffer[4]);Adc_ReadGroup(0, &vbat);printf("current:%d\r\n", vbat);
}
3.5.2 ReadStreaming
void ADC_Group0_Notification(void)
{uint16_t *buffer[1] = {0};uint16_t sampleNum;printf("buffer:[1]%d\t[2]%d\t[3]%d\t[4]%d\t[5]%d\t\r\n", group0_result_buffer[0],group0_result_buffer[1],group0_result_buffer[2],group0_result_buffer[3],group0_result_buffer[4]);sampleNum = Adc_GetStreamLastPointer(0, buffer);printf("sampleNum:%d current:%d\r\n", sampleNum, *buffer[0]);
}
参考资料:
S32K-RM.pdf - NXP
AUTOSAR_MCAL_ADC_UM[1].pdf - NXP
这篇关于【Autosar】MCAL - ADC(NXP - S32K14x)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!