我是靠谱客的博主 欣慰小刺猬,最近开发中收集的这篇文章主要介绍LK32T102学习3-ADC基本特征 ,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

有很多的信号是模拟量,我们需要将模拟信号转换为数字信号MCU才能处理。

LK32T102 内部有1个 12 位 ADC,有16个管脚的输入可以分时输入进行转换,最大转换速率是 1M/s。这16路管脚在用户编程手册的7部分有关于管脚的说明。

基本特征

  • 12 位转换器;
  • 双采样保持电路;
  • 支持连续采样模式;
  • 0V 5.5V 的输入范围,或按照 VREFHI/VREFLO 比例;
  • 多达 16 个转换通道,多路复用输入;
  • 16 个独立转换,每一个都可以任意配置触发源、采样窗口和转换通道;
  • 16 个独立的结果寄存器;
  • 可选择多个触发源(软件触发,PWM0-2PWM4GPIOINTADCINT 1/2T0TIM6 等);
  • 可在任意转换之后配置中断

从图中可以看出共有16个可输入模拟信号,另外ADCA6,ADCA7,ADCB6、ADCB7也可以配置为经过内部放大器放大后的结果(OPA0O,OPA1O,OPA2O,OPA3O)。

模拟信号然后会进入保持电路,保持电路的信号再进入ADC转换器转换,当SOC(转换源)信号来时进行首先会将信号采样,然后采样的结果再送入ADC转换器中转换,转换结果将保存在ADCRESULT0~16中,并可能产生一个转换事件(EOC)ADCINT(ADC转换中断)信号。

图中的右下脚是表明了转换启动信号的来源是哪个,总采样时间(=采样保持窗口ACQPS+ADC转换时间19个周期)、哪个模拟信号进行转换CHSEL[2:0]

右上角说明转换的参考电压来源。

ADC转换是基于SOC的,即单通道的单次转换。每个转换主要需要配置三项内容:触发源,通道和采样窗口。

模板给了一个采样软件启动ADCB5的例子,但是代码不完全,模板采用ADC中断,装换结束后启动中断将结果从串口输出。输入从PB10管脚,且需要注意将用跳线将 J5的1、2管脚短接。

/*
LCD显示实验
*/
//一定需要的2个头文件
#include <SC32F5832.h>
#include <DevInit.h>
//使用模板才需要的头文件
#include "keyboard4x4.h"
#include "delay.h"
#include "UART.h"
#include "printf.h"
#include "ds18b20.h"
#include "LCD12864.h"
#include "segment.h"
#include "motor.h"
#define BUZZER_OFF 	PA -> OUTSET = (1 << 12)  //蜂鸣器响
#define BUZZER_ON 	PA -> OUTCLR = (1 << 12)  //蜂鸣器关断
/**
	* @brief  LCD12864接线
	* @param  SC32F5832 -> LCD12864
	*							PC6 	-> 	CN3-RS
	*							PC4 	-> 	CN3-RW
	*							PC3 	-> 	CN3-E
	*							PC7 	-> 	CN3-PSB
	*							PC15 	-> 	CN3-RST
*/
/*
                             PB10->变阻器,J5跳线1~2短接,查看
*/
int main( void )
{
	int result=0;
    char buff[10];
	Device_Init();//在其中要启用ADC_Init()
	
   //LCD12864============================
	delay_ms(500);	
	LCD_GPIO_Init();//LCD12864 GPIO初始化
	PSB_0;
	CS_1;
    lcd_init();//LCD12864初始化
		
    delay_ms(100);
	lcd_clear();//清屏
	delay_ms(100);
	
  
    lcd_wstr(2, 0, "例程");//
    lcd_wstr(2,7,"15℃");
	write_figer(2,5,1234);
	
	
	BUZZER_OFF;
	
	while(1){
       	LED2_ON;
		//PB10作为模拟量的输入接口
		ADC -> ADCSOCFRC1 |= (1 << 5);//ADC - SOC5强制转换	
		delay_ms(1000);//等1秒时间让出ADC结果
		LED1_OFF;
		LED2_OFF;
        result=ADC->ADCRESULT5_b.RESULT;
        sprintf(buff,"%d",result);//用sprintf比较浪费内存,不严格可以使用
        lcd_wstr(4,0,buff);
		delay_ms(1000);
    }
	
	
}

其中ADC的初始化:

int ChSel[16]   = {14,15,0,1,0,13,0,0,0,0,0,0,0,0,0,0};               		// 定义ADC通道数组
/*通道选择表
		0h ADCINA0												
		1h ADCINA1											
		2h ADCINA2											
		3h ADCINA3												
		4h ADCINA4											
		5h ADCINA5												
		6h ADCINA6												
		7h ADCINA7

		8h ADCINB0							
		9h ADCINB1										
		Ah ADCINB2								
		Bh ADCINB3											
		Ch ADCINB4											
		Dh ADCINB5												
		Eh ADCINB6												
		Fh ADCINB7	
*/
int ACQPS[16]   = {9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9};   									// 定义各通道窗口大小数组,采样保持窗口时间,最小值为9
int TrigSel[16] = {5,5,5,5,5,0,5,5,5,5,5,5,5,5,5,5};		       					// 定义各通道触发源数组
/*触发源选择表
	00:软件触发
		01h:保留
		02h:保留
		03h:保留
		04h:保留
		05h:PWM0_SOCA
		06h:PWM0_SOCB
		07h:PWM1_SOCA
		08h:PWM1_SOCB
		09h:PWM2_SOCA
		0Ah:PWM2_SOCB
		0Bh:保留
		0Ch:保留
		0Dh:PWM4_SOCA
		0Eh:PWM4_SOCB
		0Fh:保留
		10h:保留
		11h:保留
		12h:保留
		13h:保留
		14h:保留
		15h:ERU_EVENT0
		16h:ERU_EVENT1
		17h:ERU_EVENT2
		18h:ERU_EVENT3
*/
void ADC_Init()
{
	
	ADC_RESET;	// ADC模块复位
	ADC_ENABLE;	// ADC模块使能
	
	ACCESS_ENABLE;
	ADC -> ADCCTL1_b.ADCPD = 0;      // ADC断电,高电平有效
	ACCESS_ENABLE;
	ADC -> ADCCTL1_b.ADCSHPD = 0;    // ADC采样模块断电,高电平有效
	ACCESS_ENABLE;
	ADC -> ADCCTL1_b.AADCREFPD = 0;  // 参考源缓冲电路断电控制,(高有效)
	ACCESS_ENABLE;
	ADC -> ADCCTL1_b.ADCCOREPD = 0;  // ADC数字core断电,高电平有效
	
	ACCESS_ENABLE;
	ADC -> ADCCTL2_b.clkdiv = ADC_CLKDIV_3;     // 时钟 3分频后 24MHz 作为ADC模块时钟
	ACCESS_ENABLE;
	ADC -> ADCCTL2_b.smp_conv_delay = 3;  // 采样和开始转换之间的延时
	ACCESS_ENABLE;
	ADC -> ADCCTL2_b.start_width = 3;     // 开始转换的脉冲宽度
	
	ADC_NONOVERLAP;		// 采样与转换不重叠
	ADC_MODE2;			// 工作模式,强制设定
	ADC_VOL_SEL_50V;	// 工作电压选择5.0V
	
	ADC -> ADCTRIM_b.meas_i = 0; 	// 模拟模块低电压选择
	ADC -> ADCTRIM_b.ntrim = 0;  	// NTrim参考电压
	ADC -> ADCTRIM_b.itrim = 11;	// 偏置电流校准位  (本参数为出厂设置,请勿修改)
	
	ADC_INT_AT_EOC;		// 在ADC结果存入结果寄存器的前一个周期产生INT脉冲	
	ADC_REF_INTERNAL;	// 内部外部参考源选择,选择内部带隙参考源
	
	ACCESS_ENABLE;
	//ADC -> INTSEL5N6_b.INT5E = 1;         // ADCINT5中断使能---模板中采用中断,这里注释掉

	ACCESS_ENABLE;
//	ADC->INTSEL5N6_b.INT5CONT = 1;      // ADCINT1连续模式使能:只要EOC脉冲产生,就可以产生ADCINTx脉冲
	ADC -> INTSEL5N6_b.INT5CONT = 0;      // ADCINT5连续模式使能:只要EOC脉冲产生,就可以产生ADCINTx脉冲

	ACCESS_ENABLE;
	ADC -> INTSEL5N6_b.INT5SEL = 5;       // ADCINT5源选择:EOC5作为ADCINTx的触发源
	
//	ADC_B6_SEL_PIN;											// B6通道选择管脚输入
//	ADC_B7_SEL_OPA2;										// B7通道选择运放2的输出作为输入
	
/******************************************************************************
												ADC通道选择
*******************************************************************************/

//	ACCESS_ENABLE;ADC->ADCSOC0CTL_b.CHSEL = ChSel[0];
//	ACCESS_ENABLE;ADC->ADCSOC1CTL_b.CHSEL = ChSel[1];
//	ACCESS_ENABLE;ADC->ADCSOC2CTL_b.CHSEL = ChSel[2];
//	ACCESS_ENABLE;ADC->ADCSOC3CTL_b.CHSEL = ChSel[3];
//	ACCESS_ENABLE;ADC->ADCSOC4CTL_b.CHSEL = ChSel[4];
	ACCESS_ENABLE;ADC->ADCSOC5CTL_b.CHSEL = ChSel[5];
//	ACCESS_ENABLE;ADC->ADCSOC6CTL_b.CHSEL = ChSel[6];
//	ACCESS_ENABLE;ADC->ADCSOC7CTL_b.CHSEL = ChSel[7];
//	ACCESS_ENABLE;ADC->ADCSOC8CTL_b.CHSEL = ChSel[8];
//	ACCESS_ENABLE;ADC->ADCSOC9CTL_b.CHSEL = ChSel[9];
//	ACCESS_ENABLE;ADC->ADCSOC10CTL_b.CHSEL = ChSel[10];
//	ACCESS_ENABLE;ADC->ADCSOC11CTL_b.CHSEL = ChSel[11];
//	ACCESS_ENABLE;ADC->ADCSOC12CTL_b.CHSEL = ChSel[12];
//	ACCESS_ENABLE;ADC->ADCSOC13CTL_b.CHSEL = ChSel[13];
//	ACCESS_ENABLE;ADC->ADCSOC14CTL_b.CHSEL = ChSel[14];
//	ACCESS_ENABLE;ADC->ADCSOC15CTL_b.CHSEL = ChSel[15];

/****************************************************************************
											 ADC触发源选择
*****************************************************************************/

//	ACCESS_ENABLE;ADC->ADCSOC0CTL_b.TRIGSEL = TrigSel[0];
//	ACCESS_ENABLE;ADC->ADCSOC1CTL_b.TRIGSEL = TrigSel[1];
//	ACCESS_ENABLE;ADC->ADCSOC2CTL_b.TRIGSEL = TrigSel[2];
//	ACCESS_ENABLE;ADC->ADCSOC3CTL_b.TRIGSEL = TrigSel[3];
//	ACCESS_ENABLE;ADC->ADCSOC4CTL_b.TRIGSEL = TrigSel[4];
	ACCESS_ENABLE;ADC->ADCSOC5CTL_b.TRIGSEL = TrigSel[5];
//	ACCESS_ENABLE;ADC->ADCSOC6CTL_b.TRIGSEL = TrigSel[6];
//	ACCESS_ENABLE;ADC->ADCSOC7CTL_b.TRIGSEL = TrigSel[7];
//	ACCESS_ENABLE;ADC->ADCSOC8CTL_b.TRIGSEL = TrigSel[8];
//	ACCESS_ENABLE;ADC->ADCSOC9CTL_b.TRIGSEL = TrigSel[9];
//	ACCESS_ENABLE;ADC->ADCSOC10CTL_b.TRIGSEL = TrigSel[10];
//	ACCESS_ENABLE;ADC->ADCSOC11CTL_b.TRIGSEL = TrigSel[11];
//	ACCESS_ENABLE;ADC->ADCSOC12CTL_b.TRIGSEL = TrigSel[12];
//	ACCESS_ENABLE;ADC->ADCSOC13CTL_b.TRIGSEL = TrigSel[13];
//	ACCESS_ENABLE;ADC->ADCSOC14CTL_b.TRIGSEL = TrigSel[14];
//	ACCESS_ENABLE;ADC->ADCSOC15CTL_b.TRIGSEL = TrigSel[15];

/******************************************************************************
											 ADC窗口大小选择
******************************************************************************/

//	ACCESS_ENABLE;ADC->ADCSOC0CTL_b.ACQPS = ACQPS[0];
//	ACCESS_ENABLE;ADC->ADCSOC1CTL_b.ACQPS = ACQPS[1];
//	ACCESS_ENABLE;ADC->ADCSOC2CTL_b.ACQPS = ACQPS[2];
//	ACCESS_ENABLE;ADC->ADCSOC3CTL_b.ACQPS = ACQPS[3];
//	ACCESS_ENABLE;ADC->ADCSOC4CTL_b.ACQPS = ACQPS[4];
	ACCESS_ENABLE;ADC->ADCSOC5CTL_b.ACQPS = ACQPS[5];
//	ACCESS_ENABLE;ADC->ADCSOC6CTL_b.ACQPS = ACQPS[6];
//	ACCESS_ENABLE;ADC->ADCSOC7CTL_b.ACQPS = ACQPS[7];
//	ACCESS_ENABLE;ADC->ADCSOC8CTL_b.ACQPS = ACQPS[8];
//	ACCESS_ENABLE;ADC->ADCSOC9CTL_b.ACQPS = ACQPS[9];
//	ACCESS_ENABLE;ADC->ADCSOC10CTL_b.ACQPS = ACQPS[10];
//	ACCESS_ENABLE;ADC->ADCSOC11CTL_b.ACQPS = ACQPS[11];
//	ACCESS_ENABLE;ADC->ADCSOC12CTL_b.ACQPS = ACQPS[12];
//	ACCESS_ENABLE;ADC->ADCSOC13CTL_b.ACQPS = ACQPS[13];
//	ACCESS_ENABLE;ADC->ADCSOC14CTL_b.ACQPS = ACQPS[14];
//	ACCESS_ENABLE;ADC->ADCSOC15CTL_b.ACQPS = ACQPS[15];
	
}

初始化函数中采用了软件触发ADC的方式。,

/*****************************************************************************/

上面的话全是废话,看完之后你还是不会用!看下面

在使用AD转换时我们考虑如下几个问题:

1.哪个(或哪些)信号需要转换,也就是信号从哪个管脚输入的问题

2.如何转换?

3.何时转换?

4.转换以后干什么?

5.从何处获得转换值?

>第1个问题:哪个(或哪些)信号需要转换,也就是信号从哪个管脚输入的问题

 GPIO_AF_SEL()

例:GPIO_AF_SEL(ANALOGY, PB, 10, 0);     //ADCB5 端口配置 

>第2个问题:.如何转换?

也就是配置上图的12位ADC,主要有时钟、参考电压等,跟ADC原理有关,代码太多

	
	ADC_RESET;	// ADC模块复位
	ADC_ENABLE;	// ADC模块使能
	
	ACCESS_ENABLE;
	ADC -> ADCCTL1_b.ADCPD = 0;      // ADC断电,高电平有效
	ACCESS_ENABLE;
	ADC -> ADCCTL1_b.ADCSHPD = 0;    // ADC采样模块断电,高电平有效
	ACCESS_ENABLE;
	ADC -> ADCCTL1_b.AADCREFPD = 0;  // 参考源缓冲电路断电控制,(高有效)
	ACCESS_ENABLE;
	ADC -> ADCCTL1_b.ADCCOREPD = 0;  // ADC数字core断电,高电平有效
	
	ACCESS_ENABLE;
	ADC -> ADCCTL2_b.clkdiv = ADC_CLKDIV_3;     // 时钟 3分频后 24MHz 作为ADC模块时钟
	ACCESS_ENABLE;
	ADC -> ADCCTL2_b.smp_conv_delay = 3;  // 采样和开始转换之间的延时
	ACCESS_ENABLE;
	ADC -> ADCCTL2_b.start_width = 3;     // 开始转换的脉冲宽度
	
	ADC_NONOVERLAP;		// 采样与转换不重叠
	ADC_MODE2;			// 工作模式,强制设定
	ADC_VOL_SEL_50V;	// 工作电压选择5.0V
	
	ADC -> ADCTRIM_b.meas_i = 0; 	// 模拟模块低电压选择
	ADC -> ADCTRIM_b.ntrim = 0;  	// NTrim参考电压
	ADC -> ADCTRIM_b.itrim = 11;	// 偏置电流校准位  (本参数为出厂设置,请勿修改)
	
	ADC_INT_AT_EOC;		// 在ADC结果存入结果寄存器的前一个周期产生INT脉冲	
	ADC_REF_INTERNAL;	// 内部外部参考源选择,选择内部带隙参考源
	
	ACCESS_ENABLE;
	//ADC -> INTSEL5N6_b.INT5E = 1;         // ADCINT5中断使能---模板中采用中断,这里注释掉

	ACCESS_ENABLE;
//	ADC->INTSEL5N6_b.INT5CONT = 1;      // ADCINT1连续模式使能:只要EOC脉冲产生,就可以产生ADCINTx脉冲
	ADC -> INTSEL5N6_b.INT5CONT = 0;      // ADCINT5连续模式使能:只要EOC脉冲产生,就可以产生ADCINTx脉冲

	ACCESS_ENABLE;
	ADC -> INTSEL5N6_b.INT5SEL = 5;       // ADCINT5源选择:EOC5作为ADCINTx的触发源
	
//	ADC_B6_SEL_PIN;											// B6通道选择管脚输入
//	ADC_B7_SEL_OPA2;										// B7通道选择运放2的输出作为输入
	

>第3个问题:何时转换?

>第4个问题:转换以后干什么?

可能是装换结束后触发一个中断、事件或仅仅通知转换结束(这是要查询),具体如何要配置

>第5个问题:从何处获得转换值?


		ACCESS_ENABLE;
		ADC_SOC5_Result = ADC -> ADCRESULT5_b.RESULT;
		printf("ADC采样值:%dn", ADC_SOC5_Result);
		ADC_SOC5_Result = 0;
		ACCESS_ENABLE;
		ADC -> ADCINTFLGCLR_b.ADCINT5 = 1;

从寄存器ADCRESULT0-ADCRESULT15获取,上例中采取ADC->ADCRESULT5_b.RESULT获取

/********************************************************************************/ 

很遗憾,有很多的东西我没有办法一一给大家回复,所以我建立了一个群,供大家一起交流!

 

 

最后

以上就是欣慰小刺猬为你收集整理的LK32T102学习3-ADC基本特征 的全部内容,希望文章能够帮你解决LK32T102学习3-ADC基本特征 所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(62)

评论列表共有 0 条评论

立即
投稿
返回
顶部