13、恩智浦-S32K11X:ADC实验

1、S32K11X ADC简介

S32K11x包含一个12位的ADC模块,ADC0。

1.1、ADC通道数量

每个ADC最多支持32个外部模拟输入通道,但设备上出现的确切ADC通道号与软件包不同,如下表所示:
在这里插入图片描述
芯片的ADCx_SC1n[ADCH]位场配置符合该芯片的最大通道配置:
在这里插入图片描述

1.2、ADC连接/通道分配

在这里插入图片描述

1.3、DMA对ADC的支持

应用程序可能需要对ADC的连续采样(4K样本/秒),这可能对CPU有相当大的负载。虽然使用可编程延迟块(PDB)来触发ADC可能会减少一些CPU负载,但ADC支持DMA请求,当ADC以非常高的速率采样或在绕过PDB的情况下,该功能具有更高的性能。ADC可以在转换完成时触发DMA(通过DMA请求)。

在大多数情况下,可以从ADC转换完成后直接触发DMA请求。该设备还支持另一种触发DMA的方式:通过TRGMUX。TRGMUX将根据不同的应用要求,使用软件为用户提供更灵活的DMA触发方案,例如,DMA可以在多次ADC转换完成后触发,而不是每次ADC转换完成后触发。

1.4、ADC参考选项

ADC支持以下参考资料:

VREFH/VREFL-连接作为主要参考选项;

VALTH/VREFL-连接作为备用参考选项。

ADCx_SC2[REFSEL]位选择ADC的电压参考源。

在所有的S32K1xx设备中,VALTH与VDDA相同。在没有专用VREFH/VREFL引脚的包中,VREFH在包中连接到VDDA,VREFL连接到VSSA。如果外部可用,正参考应连接到与VDDA相同的电位,或者可能由外部源驱动到最小VREFH和VDDA电位之间的水平。VREFH永远不能超过VDDA。VREFL应被连接到与VSSA相同的电压电位上。

1.5、ADC特征

线性连续近似算法高达12位分辨率;
32单端外部模拟输入;
单端12位,10位和8位输出模式;
以正确的无符号格式的单端输出;
单一的或连续的转换模式;
在单次转换后自动恢复到空闲状态;
可配置样本时间和转换速度/功率;
转换完成/硬件平均完成标志和间隔;
输入时钟可从多达四个源中进行选择;
在低功率模式下操作,以实现低噪音;
可选择的硬件转换触发器与硬件通道的选择;
自动比较与中断的小于、大于或等于、在范围内、或超出范围内的可编程值;
硬件平均功能;可选择的电压参考;外部或备用的自校准模式。

1.6、ADC模块的方框图

在这里插入图片描述

1.7、ADC寄存器描述

所有的ADC寄存器都支持8位、16位和32位的读取,但只支持32位的写入。执行8位或16位的写入将导致传输错误。

1.7.1、ADC状态控制寄存器1 (SC1):

SC1A用于软件和硬件触发操作模式。

在任何一个时间点,只有一个SC1n寄存器在积极地控制ADC的顺序转换。允许在SC1n主动控制转换时更新SC1A,而对于特定于此MCU的任何SC1n寄存器,反之亦然。

当SC1A主动控制转换时,写入SC1A寄存器会中止当前转换。在软件触发模式(SC2[ADTRG]=0时),向SC1A写入启动新的转换。这适用于SC1A[ADCH]的所有值(模块禁用)。

当特定的SC1n寄存器主动控制转换时,写入任何SC1n寄存器将中止当前转换。没有一个SC1B-SC1n寄存器用于软件触发操作,因此写入SC1BSC1n寄存器不会启动新的转换。

在这里插入图片描述
主要配置0~5位。

1.7.2、ADC配置寄存器1 (CFG1)

配置寄存器1(CFG1)选择操作模式、时钟源、时钟划分。

在这里插入图片描述

寄存器位功能
1-0 ADC时钟输入时钟选择,选择输入时钟源以生成内部时钟,ADCK。00b-备用时钟1(ALTCLK1)、01b-备用时钟2(ALTCLK2)、10b-备用时钟3(ALTCLK3)、11b-备用时钟4(ALTCLK4)。
3-2 模式转换模式选择;00b-8位转换、01b-12位转换、10b-10位转换、11b-预留.

1.7.3、ADC配置寄存器2 (CFG2)

配置寄存器2(CFG2)在长采样模式下选择长采样时间持续时间。

在这里插入图片描述

寄存器位功能
7-0 SMPLTS样本时间选择;选择一个从2个到256个ADCK时钟周期的样本时间。写入此寄存器字段的值是期望的采样时间减去1。不支持示例时间为1。允许更高的阻抗输入被精确地采样或转换速度被最大化为更低的阻抗输入。如果不需要高转换率,则在启用连续转换时,还可以使用更长的采样时间来降低整体功耗。
31-8保留

1.7.4、ADC状态控制寄存器2 (SC2)

状态和控制寄存器2(SC2)包含ADC模块的转换激活、硬件/软件触发选择、比较功能和电压参考选择。

在这里插入图片描述

寄存器位功能
1-0电压参考选择;00b-默认电压参考引脚对,即外部引脚VREFH和VREFL、01b-备用参考电压,即VALTH。根据单片机的配置,该电压可以是额外的外部针脚或内部电源。有关此单片机的详细信息,请参见芯片配置信息。
2DMA使能;0b-DMA已被禁用、1b-DMA被启用,并将在ADC转换完成事件期间断言ADCDMA请求,这在断言任何SC1n[COCO]标志时表示。
6转换触发器选择;软件触发器:当选择软件触发器时,在写入SC1A后启动转换;硬件触发器:当选择硬件触发器时,在ADHWTSn输入的一个脉冲后,根据ADHWT输入的断言,启动一个转换。0b-选择了软件触发器、1b-已选择了硬件触发器。
7转换活动;表示正在进行转换或硬件平均操作。ADACT在转换启动时设置,并在转换完成或中止时清除。0b-没有进行转换、1b-正在进行中的转换。

1.7.5、ADC状态控制寄存器3(SC3)

状态和控制寄存器3(SC3)控制ADC模块的校准、连续转换和硬件平均功能。

在这里插入图片描述

1-0硬件平均选择;确定平均多少ADC转换以创建ADC平均结果。00b-4个样本、01b-8个样本、10b-16个样本、11b-32个样本
2硬件平均使能;0b-硬件平均功能已被禁用。1b-已启用硬件平均功能。
3连续转换使能;0b-启动转换后,将执行一个转换(如果设置了AVGE,则执行一组转换)、1b-在转换启动后,将执行连续转换(或如果设置了AVGE,则执行连续转换集)。

2、硬件设计

在这里插入图片描述
本实验使用ADC0去采集待测点电压。

3、软件设计

adc.c

#include "adc.h"
//初始化ADC0
void ADC0_init(void)
{
	/*!
	 * ADC0 Clocking:
	 * ===================================================
	 */
  PCC->PCCn[PCC_ADC0_INDEX] &=~ PCC_PCCn_CGC_MASK;  /* Disable clock to change PCS 禁掉ADC时钟 */
  PCC->PCCn[PCC_ADC0_INDEX] |= PCC_PCCn_PCS(1);     /* PCS=1: Select SOSCDIV2 PCS=1: 时钟源SOSCDIV2 = 8MHZ		*/
  PCC->PCCn[PCC_ADC0_INDEX] |= PCC_PCCn_CGC_MASK;   /* Enable bus clock in ADC 使能ADC时钟	*/

	/*!
	 * ADC0 Initialization:
	 * ===================================================
	 */
  ADC0->SC1[0] |= ADC_SC1_ADCH_MASK;	/* ADCH=1F: Module is disabled for conversions	ADCH=1F: 输入通道选择为保留*/
                                  	  	/* AIEN=0: Interrupts are disabled 	AIEN=0: 禁用转换完成中断		*/
  ADC0->CFG1 |= ADC_CFG1_ADIV_MASK
		  	   |ADC_CFG1_MODE(1);	/* ADICLK=0: Input clk=ALTCLK1=SOSCDIV2 ADICLK=0: 输入时钟选择ALTCLK1=SOSCDIV2	*/
                                  	/* ADIV=0: Prescaler=1 	ADIV=0: Prescaler=1  分频/1 时钟速率为输入时钟		*/
                                  	/* MODE=1: 12-bit conversion MODE=1: 转换模式选择为12-bit	*/

  ADC0->CFG2 = ADC_CFG2_SMPLTS(12);	/* SMPLTS=12(default): sample time is 13 ADC clks SMPLTS=12(default):采样时间12 ADC时钟周期 	*/
  ADC0->SC2 = 0x00000000;         	/* ADTRG=0: SW trigger ADTRG=0: 转换触发选择为软件触发	*/
                                  	/* ACFE,ACFGT,ACREN=0: Compare func disabled	ACFE,ACFGT,ACREN=0: 比较函数禁用	*/
                                  	/* DMAEN=0: DMA disabled 	DMAEN=0: DMA禁用*/
                                    /* REFSEL=0: Voltage reference pins= VREFH, VREEFL REFSEL=0: 电压参考引脚选择为 VREFH, VREEFL*/
  ADC0->SC3 = 0x00000000;       	/* CAL=0: Do not start calibration sequence CAL=0: 不启动校准程序 当CAL=1时,会启动校准程序*/
                                    /* ADCO=0: One conversion performed ADCO=0: 不连续转换,选择一次转换*/
                                    /* AVGE,AVGS=0: HW average function disabled AVGE,AVGS=0: 禁用硬件平均功能*/
}

//选择ADC通道 0~15
void convertAdcChan(uint16_t adcChan)
{
	/*!
	 * For SW trigger mode, SC1[0] is used
	 * ===================================================
	 */
  ADC0->SC1[0]&=~ADC_SC1_ADCH_MASK;	      /* Clear prior ADCH bits 清除之前的ADCH位	*/
  ADC0->SC1[0] = ADC_SC1_ADCH(adcChan);   /* Initiate Conversion	开始转换*/
}

//判断ADC读取是否完成
uint8_t adc_complete(void)
{
  return ((ADC0->SC1[0] & ADC_SC1_COCO_MASK)>>ADC_SC1_COCO_SHIFT); 	/* Wait for completion 等待转换完成*/
}

//读取ADC值
uint32_t read_adc_chx(void)
{
  uint16_t adc_result=0;
  adc_result=ADC0->R[0];      					/* For SW trigger mode, R[0] is used 读取ADC数据结果寄存器*/
	return  (uint32_t) (adc_result); /* 返回ADC值 0~4095*/
	
//  return  (uint32_t) ((5000*adc_result)/0xFFF); /* Convert result to mv for 0-5V range */
}

//平均值滤波
//N:平均滤波次数
uint32_t ADC_Ave(uint16_t N)
{
	uint32_t tmp = 0;
	uint8_t  i;
	
	for(i = 0; i < N; i++)
	{
		tmp += read_adc_chx();
	}
	
	tmp = tmp / N;
	return (uint32_t)tmp;
}


adc.h

#ifndef ADC_H_
#define ADC_H_
#include "device_registers.h"	/* include peripheral declarations S32K11x */

void convertAdcChan(uint16_t);
void ADC_init(void);
void ADC_init_HWTrigger(char Channel);
uint8_t adc_complete(void);
uint32_t read_adc_chx(void);
uint32_t ADC_Ave(uint16_t N);
#endif /* ADC_H_ */


main.c

void WDOG_disable (void)
{
  WDOG->CNT=0xD928C520;     /* Unlock watchdog 		*/
  WDOG->TOVAL=0x0000FFFF;   /* Maximum timeout value 	*/
  WDOG->CS = 0x00002100;    /* Disable watchdog 		*/
}



int main(void)
{
	/*!
	 * Initialization:
	 * =======================
	 */
  WDOG_disable();        /* Disable WDOG */
  SOSC_init_40MHz(); 	/* Initialize system oscillator for 40 MHz xtal */
  RUN_mode_48MHz();		/* Init clocks: 48 MHz sys, core and bus,   	  	  	  	  	  	  	  	  	24 MHz flash. */
	
	ADC_init(); //ADC初始化
	uartInit(UART0,9600);
	
	while(1)
	{
		nxpPrintf("ADC test \n\r");
		convertAdcChan(6); /* Convert Channel AD12 to pot on EVB 	*/
		while(adc_complete()==0){} /* Wait for conversion complete flag 	*/
		uint32_t adcResultInMv = read_adc_chx();       /* Get channel's conversion results in mv */	
		nxpPrintf("adc0 ch3 conversion result:%d\n\r",adcResultInMv);
	}	
		
	return 0;
	
}

4、下载验证

在这里插入图片描述

5、资源获取

项目的程序工程已经放在下面公众号里面,可以关注公众号:Kevin的学习站,输入关键字:“054”,就可以获取啦!创作不易,但您的点赞、关注、收藏就是对我最大的鼓励!
在这里插入图片描述

  • 1
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Kevin的学习站

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值