【CP AUTOSAR】Adc Driver分析和使用


前言

本文介绍CP AUTOSAR 架构下的Adc组件,基于S32K144芯片、NXP提供的MCAL包,使用EB Tresos工具进行配置的经验,不具体介绍芯片Adc外设的功能。
Adc组件实现Adc的驱动,具有单次转换、连续转换、软件触发、硬件触发等模式,为上层组件IoHwAb提供接口。
Adc组件位于I/O Drivers层里。
在这里插入图片描述


一、原理解析

在这里插入图片描述如上图,AUTOSAR里定义了多种ADC的实现方式,有如下几种概念:
(一)、Unit、Channel、Group
Unit:
芯片外设里实现ADC功能的单元,如ADC1、ADC2等,每个ADC单元里有若干个ADC通道,在使用前需要对ADC单元进行配置,如ADC的参考电压、分辨率、时钟源等。
Channel:
ADC通道有两个概念,一个是ADC外设上的物理通道,也就是芯片上对应的ADC通道,在使用ADC时需要选择要转换的ADC通道,如ADC1_In0、ADC1_In1等。一个是软件逻辑上的通道,每个逻辑通道映射一个物理通道,映射的物理通道没有严格的对应关系,在一个单元内可以映射任何一个通道,逻辑通道顺序序号从0开始,下面文章涉及的通道指的都是软件逻辑通道。
Group:
操作ADC进行转换的基本单位为Group,Group里至少有一个Channel,每个不同的Group可以有相同的Channel比如Group1和Group2同时有Channel1,Group里的Channel需要在同一个Unit里面比如Group1里的Channel只能是Unit1里的通道或Unit2里的通道。
当进行Group转换时,一个Unit下只能转换一组Group,其他Group想要转换时,需要停止当前Unit的转换,如Unit1的Group1和Group2不能同时转换只能转换其中一个,是否能同时转换取决于芯片的硬件能力。
在这里插入图片描述

(二)、SoftwareTrigger和HardwareTrigger
SoftwareTrigger:
Group的软件触发是通过调用软件触发API来实现ADC的触发。
软件触发下的One-Shot Conversion不能使用Streaming access。
HardwareTrigger:
Group的硬件触发是通过芯片外设的控制来触发ADC驱动,如PWM、GPT等来触发ADC转换。
硬件触发下不支持使用Continuous Conversion。

(三)、One-Shot Conversion和Continuous Conversion
One-Shot Conversion:
Group的单次转换是在调用软件API后执行一次Group的转换,软件触发模式只执行一次转换除非下次继续调用,硬件触发模式只需调用一次就能一直转换除非在Linear模式采样次数到了后停止转换。
单次转换在SoftwareTrigger下不支持Streaming access。
Continuous Conversion:
Group的连续转换是在软件触发或硬件触发后执行Group的持续转换,转换结束后是在中断里继续执行开始转换,除非调用软件API停止转换或者在Linear模式采样次数到了后停止转换。
连续转换下不支持HardwareTrigger。

(四)、Single access和Streaming access
Single access:
Group的单次访问是当Group转换完成后存储一次转换结果,其效果和Streaming access下的Circular模式只执行一次的效果是一样的。
Streaming access:
Group的流访问又分为Circular模式和Linear模式,可以执行多次采样。Circular模式转换完又继续转换,Linear模式转换完就停止转换了。
比如一个Group有两个Channel,设为流访问,采样次数设为2次,当执行Linear模式时,进行两次转换,转换完成后变停止转换,采样Buffer里更新为四个数据。当执行Circular模式Circular模式,进行两次转换,两次转换完后接着转换除非手动停止,采样Buffer里的四个数据不断在更新。
流访问下不支持One-Shot Conversion。

根据上面描述的几个功能,Group有若干个转换方式,转换结果如下:
假设当前Group有Channel1、Channel2,当流访问时采样次数为2.
(一)、硬件触发、单次转换、单次访问
在这里插入图片描述
(二)、硬件触发、单次转换、流访问、线性模式:
在这里插入图片描述(三)、硬件触发、单次转换、流访问、循环模式:
在这里插入图片描述(四)、软件触发、单次转换、单次访问:
在这里插入图片描述(五)、软件触发、连续转换、单次访问:
在这里插入图片描述(六)、软件触发、连续转换、流访问、线性模式:
在这里插入图片描述(七)、软件触发、连续转换、流访问、循环模式:
在这里插入图片描述

二、代码架构

在这里插入图片描述S32k144的ADCDriver组件如上图组成,Adc.c提供AUTOSAR ADC的接口,Adc_Adc12bsarv2.c实现Adc外设的功能、寄存器配置,Adc_Pdb.c实现Pdb外设的功能、寄存器配置,然后统一通过Adc_Ipw.h封装一层通过给Adc.c。
通过S32k144数据手册可知,此芯片的Adc有软件触发、硬件触发两种。软件触发通过使能Adc寄存器来进行ADC转换。硬件触发通过Pdb或Trgmux作为输入源来触发ADC转换,Pdb是可编程延时模块,可以进行计时延时使能ADC,也能用Trgmux作为输入源使能Pdb再使能ADC,Trgmux是灵活触发器,能将一个外设作为输入源触发另一个外设。
在这里插入图片描述研究Adc组件代码发现,不管是软件触发还是硬件触发,ADC寄存器都是配置为硬件触发,并且输入源都是用Pdb模块作为输入源。
在这里插入图片描述如果Group的触发方式选择软件触发,那则是通过使能Pdb来触发Adc,如果是选择硬件触发,那则是将Pdb的输入源选择为Trgmux,Trgmux模块则要配置另一个外设作为输入源来触发Pdb。
在这里插入图片描述研究Adc组件代码发现,不管是单次转换还是连续转换,代码里寄存器配置的都是单次转换,在转换完成后进入中断去查询Group是不是连续转换或者是流访问才接着去使能转换。
在这里插入图片描述在这里插入图片描述

如下图ADC的DMA转换完后进行中断都会调用Adc_Adc12bsarv2_DmaTransferComplete0(),Adc_Adc12bsarv2_EndDmaPartialConversion()里处理该Group的流访问转换和连续转换功能。
在这里插入图片描述如下图ADC转换完后进行中断都会调用Adc_Adc12bsarv2_EndGroupConvUnit0(),Adc_Adc12bsarv2_EndGroupConversion()里处理该Group的流访问转换和连续转换功能。
在这里插入图片描述

三、主要变量和类型描述

无。

四、主要代码描述

(一)、Adc_SetupResultBuffer(VAR(Adc_GroupType, AUTOMATIC) Group,CONSTP2VAR(Adc_ValueGroupType, AUTOMATIC, ADC_APPL_DATA) DataBufferPtr)
Adc_SetupResultBuffer()给对应的Group设置外部数据区,尤其是有流访问的一定要设置外部数据区。Group转换完成后将数据存到外部数据区内。

(二)、Adc_StartGroupConversion(VAR(Adc_GroupType, AUTOMATIC) Group)
是软件触发的Group调用此API进行开始转换。

(三)、Adc_ReadGroup(VAR(Adc_GroupType, AUTOMATIC) Group,P2VAR(Adc_ValueGroupType, AUTOMATIC, ADC_APPL_DATA) DataBufferPtr)
如果该Group没使能中断,Adc_ReadGroup便直接访问ADC寄存器来提供数据。如果该Group使能了中断,Adc_ReadGroup将提供Adc_SetupResultBuffer设置过后的外部数据区里最新的数据,如果有流访问,采样次数大于1,则提供最新转换过后的数据而不是所有的采样数据。
此函数每次调用如果Group的状态是ADC_STREAM_COMPLETED的话会更新为ADC_BUSY或ADC_IDLE。

(四)、Adc_EnableHardwareTrigger(VAR(Adc_GroupType, AUTOMATIC) Group)
是硬件触发的Group调用此API进行开始转换。

(五)、Adc_EnableGroupNotification(VAR(Adc_GroupType, AUTOMATIC) Group)
设置Group转换后的回调函数,每一轮转换后都会调用,比如采样次数为3次,那每一次转换完都会调用回调函数。

(六)、Adc_GetGroupStatus(VAR(Adc_GroupType, AUTOMATIC) Group)
如果采样次数大于1,每次转换完还没大于采样次数的话,会返回ADC_COMPLETED,转换次数等于采样次数的话,就返回ADC_STREAM_COMPLETED。
如果Group没使能中断的话,Adc_GetGroupStatus返回的状态只有ADC_BUSY或ADC_IDLE。

(七)、Adc_GetStreamLastPointer(VAR(Adc_GroupType, AUTOMATIC) Group,P2P2VAR(Adc_ValueGroupType, AUTOMATIC, ADC_APPL_DATA) PtrToSamplePtr)
该函数返回当前转换的次数,比如采用次数为3次的话,已经转换了2次就返回2,PtrToSamplePtr返回当前转换的最新结果,如果该Group有很多Channel,返回的是第一个Channel的最新结果。
此函数每次调用如果Group的状态是ADC_STREAM_COMPLETED的话会更新为ADC_BUSY或ADC_IDLE。
在这里插入图片描述

五、EBTresos配置

主要配置如下:
在这里插入图片描述此地方配置ADC的Unit、Group、Channel。
在这里插入图片描述配置Unit的参考电压、转换精度、传输类型是通过DMA还是ADC中断。
在这里插入图片描述此地方配置Group的Channel、流访问还是单次访问、单次转换还是连续转换、软件触发还是硬件触发、采样次数、是否中断等。在流访问和连续转换下,中断是一定要使能的。
在这里插入图片描述在这里插入图片描述此地方配置是否添加ADC中断,如果前面的传输类型选择的是ADC中断那这地方是一定要添加ADC中断的。
在这里插入图片描述在这里插入图片描述如果前面选择了DMA传输,那在Mcl组件里要给DMA添加ADC的传输源。
在这里插入图片描述如果前面选择了硬件触发,需要在Mcl组件里给选择硬件触发源。前面说过Adc都是Pdb触发的,如果选择了硬件触发那就是通过外设信号给到TrgMux模块,TrgMux模块再输入给Pdb,Pdb再输入给ADC,如图所示这里选择了FTM0输入给TrgMux。
在这里插入图片描述在这里插入图片描述在这里插入图片描述
如上图不管是选择ADC中断传输还是DMA中断传输,代码里都要记得使能中断并且在中断向量表里添加代码里的中断接口。

六、使用范例

(一)、软件触发、单次访问、单次转换、中断关闭

/**忽略中断配置、时钟配置、引脚配置等**/
unit8 data;
Adc_Init(&AdcConfigSet);
Adc_Calibrate(ADC_0, &AdcCalibStatus);
Adc_StartGroupConversion(0);
if((Std_ReturnType)E_OK == Adc_ReadGroup(0, data))
{
	if (Adc_GetGroupStatus(0) != ADC_BUSY)
	{
		Adc_StartGroupConversion(0);
	}
}

(二)、软件触发、流访问、连续转换、中断打开

/**忽略中断配置、时钟配置、引脚配置等**/
unit8 data[10];
unit8 mdata[30];
unit8 cnt;
Adc_Init(&AdcConfigSet);
Adc_Calibrate(ADC_0, &AdcCalibStatus);
Adc_SetupResultBuffer(0, maaa);
Adc_StartGroupConversion(0);
if(ADC_STREAM_COMPLETED == Adc_GetGroupStatus(0))
{
	Adc_ReadGroup(0, data);
}
else if(ADC_COMPLETED== Adc_GetGroupStatus(0))
{
	/*cnt是转换了的次数*/
	cnt = Adc_GetStreamLastPointer(0,data);
	Adc_ReadGroup(0, data);
}

(三)、硬件触发、流访问、单次转换、中断打开

/**忽略中断配置、时钟配置、引脚配置等**/
unit8 data[10];
unit8 mdata[30];
unit8 cnt;
Adc_Init(&AdcConfigSet);
Adc_Calibrate(ADC_0, &AdcCalibStatus);
Adc_SetupResultBuffer(0, maaa);
Adc_EnableHardwareTrigger(0);
if(ADC_STREAM_COMPLETED == Adc_GetGroupStatus(0))
{
	Adc_ReadGroup(0, data);
}
else if(ADC_COMPLETED== Adc_GetGroupStatus(0))
{
	/*cnt是转换了的次数*/
	cnt = Adc_GetStreamLastPointer(0,data);
	Adc_ReadGroup(0, data);
}

七、参考资料

https://www.autosar.org/fileadmin/standards/R22-11/CP/AUTOSAR_SRS_ADCDriver.pdf
https://www.autosar.org/fileadmin/standards/R22-11/CP/AUTOSAR_SWS_ADCDriver.pdf
https://www.autosar.org/fileadmin/standards/R23-11/CP/AUTOSAR_CP_EXP_LayeredSoftwareArchitecture.pdf


总结

使用ADC前,对应的引脚要在Port组件里把引脚设置为ADC引脚,Mcu组件里使能ADC外设时钟,如果ADC用了硬件触发,Mcl组件里也要设置硬件触发源,如果用了中断,也要使能中断。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值