S32K344之ADC

前言

ADC介绍

CT组件

CT组件 Adc_Sar_IP组件

1、AdcSarGeneral

描述:

General configuration (parameters) of the Adc_Sar_lp Driver software module.

Adc_Sar_lp驱动程序软件模块的常规配置(参数)。

配置选项:

  • Name
  • Adc Sar Dev Error Detect
    此参数启用/禁用Adc-Sar的开发错误检测。
  • Adc Sar Timeout Method
    选择Adc Sar延时类型
  • Adc Sar timeout value
    Adc Sar延时数值
  • Enable Adc Sar User Mode Support
    启用此参数后,Adc模块将适应从用户模式运行。     
    注意:从用户模式运行ADC驱动程序无需采取特殊措施;Adc驱动程序代码可以在任何时候从管理员和用户模式执行。
  • Adc Sar Enable Watchdog Api
    此参数可全局启用Adc Watchdog功能。如果禁用此参数,则Watchdog处理代码将在预编译时被删除,并且对于anu变体,任何单元中都不能配置与此功能相关的任何内容。如果启用此参数,则可以配置AnalogWatchdong功能。                         
    注:这是一个具体实施的参数。
  • Adc Sar Enable End Of Channel Notification
    此参数全局启用 Adc 通道结束通知。
    注:这是一个具体实施的参数。 
  • Adc Sar Enable Tempsense Api
    启用此参数时,TempSense的APl可供使用。
  • TempSense Voltage Supply
    TempSense模块的Adc电压源,以符号的定点1位表示。该值必须由用户根据实际的板设置填写。它和将用于计算TempSense测量的值。

2、AdcHWUnit

描述:

ADC硬件单元配置

每一个ADC采样通道都可以通过加号添加配置。

配置选项:

  • Adc Hardware Unit:哪个ADC
  • Adc Connversion Mode:ADC转换模式,一次or连续扫描
  • Adc Prescaler Value:可选ADC模块特定的时钟预缩放因子,如果硬件支持的话。
    实现类型:Adc_PrescaleType。
    NORMAL模式的Prescaler值。只允许以下内容:
    1:ADC模块时钟频率。
    2:ADC模块时钟频率/2。
    4:ADC模块时钟频率/4。
  • Adc Calibration Prescale:指定用于校准的已用时钟输入。
    1:ADC模块时钟频率。
    2:ADC模块时钟频率/2。
    4:ADC模块时钟频率/4。
  • Adc Enable High Speed:启用/禁用高速转换或校准。
    转换时钟的频率必须在数据表中定义的范围内。
    如果模块时钟频率高于功能转换期间或校准期间允许的转换时钟的最大频率(参见芯片数据表),则必须配置ADC转换时钟分频器,以便转换时钟的频率在允许的范围内。
    对于某些转换时钟频率,必须启用此功能。有关更多详细信息,请参阅参考手册或数据表。
  • Adc Power Down Delay:断电位重置和转换开始之间的延迟
  • Adc Mux Delay:外部解码信号与采样相位开始之间的延迟。
    当ADC在正常系统频率上运行时,它用于考虑外部多路复用器的稳定时间。
    解码信号延迟计算为(DSD x 1/Adc_Clock的频率)
    DSDR寄存器为12位。
    注意:这是一个特定于实现的参数。
  • Adc Auto Clock Off:自动关闭时钟。有可能是在空闲时自动关闭时钟。
  • Adc Bypass sampling:选择是否在预采样之后进行比较。
    禁用:预采样之后将对所选输入进行采样。
    启用:预采样后将执行逐次逼近算法,转换数据将写入所选输入的转换数据寄存器。
  • Adc Result Overwrite Enable:指定在读取当前转换数据之前,转换数据寄存器是否接受新数据。启用时,无论旧转换数据的有效性如何,新转换结果都会覆盖旧数据。
    当CDRn[VALID]=1时,尚未读取转换数据。
  • Adc Presampling channel 0-31:选择通道0-31的Adc预采样内部电压
  • Adc Presampling channel 32-63:
  • Adc Presampling channel 64-95:
  • Adc Ctu mode:BCTU的模式,控制模式和触发模式。(不知道为什么写CTU)
  • Injected external trigger mode:指定注入的外部触发器模式。(上升沿、下降沿)
  • Normal external trigger mode:指定正常的外部触发器模式。(上升沿、下降沿)

配置选项:

  • User Offset:选择转换结果的数据位。8 10 12 14
  • User Gain
  • Conversion resolution
  • Bypass resolution processing:禁用结果的解析处理,允许APl从CDR寄存器返回原始结果数据。
    启用此功能将允许APl读取的结果与使用DMA读取的结果具有相同的位宽,因为DMA将始终从CDR寄存器获得未处理的数据。
    结果的分辨率将与上面配置的分辨率相同,但其位数将始终为15。
    阈值还需要在15个比特上给出。
  • DMA Enable
  • DMA Clear Source
  • End of channel conversion notification:在通道转换结束时引发的通知。需要一个函数
    带有uint8参数(将引发中断的通道的id)。
    Watchdog out of range notification:当通道监视程序超出范围时引发通知。需要一个带有两个uint8参数的函数(一个是将引发中断的相应通道的索引,另一个是引发通知的标志)。
  • End of normal chain notification:正常链 转换完成通知函数(回调函数)
  • End of injected chain notification:注入链
  • End of Ctu conversion notification:BCTU
  • Data alignment:转换结果寄存器中的数据对齐。(左对齐、右对齐)
  • Adc Voltage Reference:Adc电压参考,以定点格式表示,符号为1位,整数部分为11位,小数部分为4位。
    该值必须由用户根据实际的电路板设置填写。它和将用于计算TempSense测量的值。
  • Adc Hardware Average Enable:启用ADC的硬件平均功能。
  • Adc Hardware Average Select:4 8 16 32次平均
  • Adc Unit Normal Sampling Duration 0:采样周期???
  • Adc Unit Normal Sampling Duration 1:...
  • Adc Unit Normal Sampling Duration 2:...

Channel configurations array

此容器包含的配置通道数取决于硬件的容量。该数据结构的组织可能包含对微控制器的依赖性,因此这由实现者决定,其位置由配置决定。注意:由于AdcChannel可以是多个AdcGroup的一部分,因此此容器不是作为AdcGroup子容器实现的,而是作为AdcHwUnit的子容器实现。

通道配置组,在这里配置不同通道(点击+添加通道)。

配置选项:

  • Name:命名
  • Adc Physical Channel Name:选择实际物理通道
  • Enable in Normal Chain:使能正常链
  • Enable in Injected Chain:使能注入链
  • Adc Enable Presampling:使能预采样
  • Adc Enable Threshold:如果为true,此参数将启用所选通道的阈值检测功能。
  • Adc Threshold Control Register
  • End of conversion notification enable:使能转换结束通知
  • Watchdog notification enable
  • End of conversion DMA enable

Watchdog threshold configurations array

为所选通道配置阈值检测功能。

实战

官方例程说明如下(具体查看官方的说明):

1.示例说明
此演示应用程序的目的是介绍S32K3xx MCU的ADC_SAR和BCTU IP驱动程序的基本用法。
1.1应用软件功能
该示例使用软件触发器触发ADC正常转换和注入转换,也使用BCTU的软件触发器。
使用的ADC通道是带隙(~1.2V,对应于15位分辨率的11900)。将比较原始读取的ADC数据
具有提供的价值。
该示例分为两部分:
-第1部分:转换序列使用ADC的SW触发触发,有两种模式:正常模式和注入模式
-第2部分:使用BCTU的SW触发触发转换序列,ADC结果存储在FIFO索引1中
示例的两个部分都使用了ADC和BCTU中断。
-初始化ADC/BCTU模块
-在中断控制器中启用ADC/BCTU IRQ
-校准ADC模块
-通过ADC的正常和注入的软件触发启动ADC转换
-读取原始ADC数据转换并与提供的值进行比较
-配置BCTU,并将单个转换和结果存储在FIFO中。
-通过BCTU的软件触发启动ADC转换
-读取原始ADC数据转换
 

简而言之,官方例程测量内部Bandgap通道,故在引脚上没有任何配置。

通过研究例程并阅读用户手册,完成对评估板的电位器ADC电压测量。

1、确定硬件通道

查看评估板用户手册——S32K3X4EVB-Q172 HWUM,搜索ADC,可以看到:

默认ADC引脚是接到PTA11。

也可以查看原理图:

据我所知,DNP是默认不连接的意思(Do Not Populate),也就是说0402的0欧姆电阻不焊接,所以ADC测量引脚被路由(连接)到PTA11

继续查看,找到PTA11对应的ADC通道——ADC1_S10

为什么原理图上有很多0欧姆电阻?原因是0欧姆电阻相当于导线,起连接作用,当该处不需要使用时,可以将0欧姆电阻移除。

2、配置引脚

由于引脚默认是用于ADC1_S10,如果单单只配置这个引脚,并不会生成任何实质性的代码,除非再添加其他引脚的配置并生成实质性代码。

(因为当时配置完后,调用有关的初始化函数会报错,如:    Siul2_Port_Ip_Init(NUM_OF_CONFIGURED_PINS0, g_pin_mux_InitConfigArr0);  因为并没有生成任何配置代码,比如这个变量:g_pin_mux_InitConfigArr0)

3、添加组件

在CT中打开外设组件,并添加Adc_Sar驱动层并打开。

4、配置硬件单元

在AdcHwUnit栏中,点击旁边的加号,添加ADC硬件单元。

大部分配置参考官方例程即可。我的配置大致如下:

ADC1,单次采样,采样结果复写,本次不使用BCTU,给正常链的回调函数取个名,其他都和官方例程的一样,最后三栏的220好像是采样周期吧?

5、配置该硬件单元下的通道

在1中确定的硬件通道在此处选填,并使能正常链,使能转换完成通知。

6、部分代码

#include "Adc_Sar_Ip.h"

ISR(Adc_Sar_1_Isr);
volatile uint16 data;


void ADC1S10_EndOfNormalChainNotif(void)
{
    data = Adc_Sar_Ip_GetConvData(ADCHWUNIT_1_VS_0_INSTANCE, 34);

    float temp;
    temp=data*5.0/16383;//2^14=16383 //通过获取的数字量,计算转换成实际电压值
    data=temp*1000;
    dummyData[0]=data/1000;
    dummyData[1]=0x0d; // 小数点标识符
   	dummyData[2]=data%1000/100;
   	dummyData[3]=data%100/10;
   	dummyData[4]=data%10;

    //通过CAN发送出去,数据格式 比如3.666V, 03 0d 06 06 06 ...
   	FlexCAN_Ip_Send(INST_FLEXCAN_0, TX_MB_IDX, &tx_info, MSG_ID, (uint8 *)&dummyData);

}


int main(void)
{
 /* Write your code here */
	StatusType status;
	uint8 Index;
	Clock_Ip_StatusType clockStatus;
/
	/* Initialize and configure drivers */
	clockStatus = Clock_Ip_Init(&Clock_Ip_aClockConfig[0]);
	while (clockStatus != CLOCK_IP_SUCCESS)
	{
		clockStatus = Clock_Ip_Init(&Clock_Ip_aClockConfig[0]);
	}
/
	Siul2_Port_Ip_Init(NUM_OF_CONFIGURED_PINS0, g_pin_mux_InitConfigArr0);
    status = (StatusType) Adc_Sar_Ip_Init(ADCHWUNIT_1_VS_0_INSTANCE, &AdcHwUnit_1_VS_0);
    while (status != E_OK);

    /* Install and enable interrupt handlers */
    IntCtrl_Ip_InstallHandler(ADC1_IRQn, Adc_Sar_1_Isr, NULL_PTR);
    IntCtrl_Ip_EnableIrq(ADC1_IRQn);
    /* Call Calibration function multiple times, 
       to mitigate instability of board source*/
    for(Index = 0; Index <= 5; Index++)
    {
        status = (StatusType) Adc_Sar_Ip_DoCalibration(ADCHWUNIT_1_VS_0_INSTANCE);
        if(status == E_OK)
        {
            break;
        }
    }

    Adc_Sar_Ip_EnableNotifications(ADCHWUNIT_1_VS_0_INSTANCE, 
                                   ADC_SAR_IP_NOTIF_FLAG_NORMAL_ENDCHAIN 
                                  |ADC_SAR_IP_NOTIF_FLAG_INJECTED_ENDCHAIN);

    .........

}


//我另外写了一个按键函数,通过按键按下,开始一次ADC采样。(详细配置参考按键那章)
//主要是通过调用这个函数开始一次ADC采样 Adc_Sar_Ip_StartConversion
//按键5 回调函数
void User_SW5_Callback(void)
{
	Siul2_Dio_Ip_TogglePins(LEDB_PORT, (1<<LEDB_PIN));
    Adc_Sar_Ip_StartConversion(ADCHWUNIT_1_VS_0_INSTANCE, ADC_SAR_IP_CONV_CHAIN_NORMAL);

	return;
}

想写个死循环,在里面用延时函数一直读取ADC。结果找不到官方的延时函数。

后面就:

int i=0;

while(i)

{

        i++;

        if((i%50)==0)

                读取ADC;

}

结果给我优化了,他喵的。

i的值一直没有变化,显示optimized out,导致if()里面进不去,还报错误 within this loop

意思是,循环死在这里,无法返回return。

离谱就,优化太严重了。

  • Band Gap通道,Bandgap电压是精度较高的1V电压,用于ADC内部的自校准,同时也可以通过ADC通道读出其电压。

  • VREFSH和VREFSL通道,ADC参考电压的上限和下限

关于Band Gap:

bandgap的理解(内部带隙电压基准)_stc15f 带隙电压-CSDN博客

1、ADC测量的影响因素,举个简单的例子。
我们给单片机供电是2.8V,此时用ADC去测量一个1.3V,ADCRH最后得到的值,可能就是142.如果单片供电是3.3V,这时候再去测量1.3V,ADCRH最后得到的值可能就不再是142了.如果是5V,得到的数据可能更低。
以上这个简单的例子,相信已经能说明一个简单的问题,ADC得到的数据,会随着供电电压的改变而改变。为了解决这个问题,人们想出了使用外部基准的办法,大致的方法就是使用两个ADC通道,一个通道测量外部基准(如TI431),一个通道进行对目标的测量。知道了基准值,就可以得到一个相对准确的测量值。但这种方法需要占用两个ADC通道,并且需要外部器件,成本较高。这时候就可以使用单片机内置的带隙电压了~
2、带隙电压的构成。
大概如下图所示。R3/R4使用正负温度系数材料,是为了避免温度对分压电阻造成的影响,这样温差造成的影响可以进行互补,避免带隙电压不稳。

N76E003之ADC带隙电压(Band-gap) - 百度文库

STM32 规则组用于常规使用,注入组用于突发事件。

S32K344 标准触发 注入触发

注入触发就像中断。

小猫爪:S32K3学习笔记05-S32K3之ADC_s32k3adc的原理-CSDN博客

  • 10
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
在 S32K344 中,使用 BCTU 触发 ADC 转换时,如果转换数据不更新,可能是以下几个原因: 1. BCTU 定时器未启动或未配置正确。需要先配置好 BCTU 定时器,并启动定时器,确保在设定的时间内触发 ADC 转换。 2. ADC 触发源没有选择为 BCTU。需要在 ADC 控制寄存器(ADC_CTRL)中将触发源选择为 BCTU,确保 ADC 可以接收到 BCTU 触发信号。 3. ADC 转换模式或通道选择不正确。需要在 ADC 控制寄存器(ADC_CTRL)和 ADC 序列控制寄存器(ADC_SEQ_CTRLx)中选择正确的转换模式和通道,确保 ADC 能够正确转换指定的通道。 4. ADC 转换未完成或未启动。需要在 ADC 控制寄存器(ADC_CTRL)中启动 ADC 转换器,并在转换完成后读取 ADC 数据寄存器(ADC_DATAx)中的转换结果。 以下是一份基于 S32K344 的 ADC 使用 BCTU 触发的示例代码,您可以参考下面的代码进行修改: ``` #include "S32K344.h" void BCTU_Init(void) { // 设置 BCTU 时钟源为 PCLK SYSCON->CLKSEL2 &= ~(0x03 << 12); SYSCON->CLKSEL2 |= (0x01 << 12); // 设置 BCTU 时钟分频系数为 1 SYSCON->SYSAHBCLKDIV &= ~(0xFF << 0); SYSCON->SYSAHBCLKDIV |= (0x01 << 0); // 设置 BCTU 定时器重载值 BCTU->TIMER_RELOAD = 1000; // 设置 BCTU 定时器触发时间 BCTU->TIMER_MATCH = 500; // 启动 BCTU 定时器 BCTU->TIMER_CTRL |= (1 << 0); } void ADC_Init(void) { // 选择 ADC 时钟源为 PCLK SYSCON->CLKSEL1 &= ~(0x03 << 25); SYSCON->CLKSEL1 |= (0x01 << 25); // 选择 ADC 时钟分频系数为 2 SYSCON->SYSAHBCLKDIV &= ~(0xFF << 8); SYSCON->SYSAHBCLKDIV |= (0x02 << 8); // 选择 ADC 转换时钟为 4 分频 ADC->CTRL &= ~(0x07 << 4); ADC->CTRL |= (0x02 << 4); // 选择 BCTU 触发源 ADC->CTRL &= ~(0x07 << 24); ADC->CTRL |= (0x03 << 24); // 禁止软件触发 ADC->CTRL &= ~(1 << 8); // 设置 ADC 采样时间为 10 个时钟周期 ADC->SMPR &= ~(0x07 << 0); ADC->SMPR |= (0x00 << 0); // 选择 ADC 通道 0 ADC->SEQ_CTRL &= ~(0x0F << 0); ADC->SEQ_CTRL |= (0x00 << 0); // 选择 ADC 单次转换模式 ADC->CTRL &= ~(0x03 << 16); ADC->CTRL |= (0x00 << 16); // 启动 ADC 转换器 ADC->CTRL |= (1 << 0); } int main(void) { // 初始化 BCTU 和 ADC BCTU_Init(); ADC_Init(); // 等待 ADC 转换完成 while (!(ADC->STATUS & (1 << 0))); // 读取 ADC 转换结果 uint32_t adc_value = ADC->DATA0; return 0; } ``` 注意,这只是一份简单的示例代码,您需要根据具体的硬件平台和应用场景进行调整和优化。如果问题仍然存在,请检查硬件连接和时序,确保 BCTU 和 ADC 工作正常。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值