了解ADC DMA的五路模拟量灰度传感器

我使用的是五路模拟量灰度传感器,单片机是stm32f103c8t6.要注意灰度电源端最好接5v。其余A0、A1、A2、A3、A4我接的是单片机ADC1的PA0、PA1、PA2、PA3、PA5,(为什么不接PA4呢,那是由于PA4被占用了,那如何判断IO口是否被占用,我们可以不给灰度传感器供电,其他IO口都接上,然后与电脑通信,查看那个口有数据就说明他被占用了)还要注意,ADC1只能用DMA1进行搬运。

灰度传感器原理:每一组传感器均由一只发光二极管和一只灰度接收管组成;两个探 头安装在电路板同一面上,发光管发射的光会被检测面反射后由灰度 接收管进行回收。由于光线照射到不同颜色后一部分光被颜色吸收, 一部分则被反射出去,会得到不同颜色光反射强度的变化,灰度接收 管对被探测面颜色光反射的强弱不同进行采集回收,然后输出对应的 电压值信号(也叫做模拟信号);得到此种信号,我们就可配合单片 机编程控制,用于颜色识别、巡线智能小车机器人等领域。模拟量灰度传感器可对被探测面的多种任意颜色进行识别,在探测到 不同颜色时,输出不同的电压信号(俗称为一种状态值);输出的电 压值是随被探测面的颜色变化而变化的,所以也就可以识别出任意颜 色。使用时需要注意的是由于它的值是受到探头离地高度不同和被探 测面颜色变化而产生变化,所以在编程时需预先固定好传感器高度后 再对各种颜色进行取值,然后将对应的值作为条件判断进行识别控制 (一般取一定范围的值,防止环境光干扰产生波动。

我们需要注意,我们要先安装好灰度传感器再去进行采取参数。安装高度一般是5~20mm,个人建议最后15mm左右。

我们可以通过RCC_ADCCLKConfig(RCC_PCLK2_Div6);//对应APB272MHZ6分频与ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_13Cycles5);来配置ADC采样时间。(ADC_RegularChannelConfig是规则组通道配置,第三个参数是配置序列位置,相当于是第几个传输出去)

要注意使用连续转换与连续扫描模式,这样可以不断进行采样(转换:就是指你需要将你采集的数据转换几次。扫描就是指你要接着转换下去吗。)

配置ADC:

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
	
	RCC_ADCCLKConfig(RCC_PCLK2_Div6);//对应APB272MHZ6分频
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_5;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_13Cycles5);
	ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 2, ADC_SampleTime_13Cycles5);
	ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 3, ADC_SampleTime_13Cycles5);
	ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 4, ADC_SampleTime_13Cycles5);
	ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 5, ADC_SampleTime_13Cycles5);	
	
	
	ADC_InitTypeDef ADC_InitStructure;
	ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;//独立模式,ADC1和ADC2各自转换各自的
	ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//数据右对齐
	ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//选用触发源(这里使用内部软件触发)
	ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;//选择连续转换模式
	ADC_InitStructure.ADC_ScanConvMode = ENABLE;//选用扫描模式
	ADC_InitStructure.ADC_NbrOfChannel = 5;//选择通道数目
	ADC_Init(ADC1, &ADC_InitStructure);

这里由于ADC寻址空间是32位的但是数据寄存器是16位的,而我们需要将他转成32位但是址需要他的低16位,采用半字(16位)进行传输就可以。

 配置DMA:

	DMA_InitTypeDef DMA_InitStructure;
	DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR;//外设站点起始地址
	DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;//外设数据宽度
	DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//地址是否自增,不用因为ADC地址一定
	DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)AD_Value;//存储器基地址
	DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;//存储器数据宽度
	DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//存储器地址是否自增
	DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;//指定外设站点是源端还是目的地
	DMA_InitStructure.DMA_BufferSize = 5;//传输几次
	DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;//是否自动重装
	DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;//是否用软件触发
	DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;//指定通道优先级
	DMA_Init(DMA1_Channel1, &DMA_InitStructure);
	
	DMA_Cmd(DMA1_Channel1, ENABLE);
	ADC_DMACmd(ADC1, ENABLE);
	ADC_Cmd(ADC1, ENABLE);
	
	ADC_ResetCalibration(ADC1);//重置指定的ADC的校准寄存器
	while (ADC_GetResetCalibrationStatus(ADC1) == SET);
	ADC_StartCalibration(ADC1); //开始指定ADC的校准状态 
	while (ADC_GetCalibrationStatus(ADC1) == SET);
	ADC_SoftwareStartConvCmd(ADC1, ENABLE);//软件触发ADC转换

IO口被占用现象:

链接:https://pan.baidu.com/s/123lAQETFVWAsMdA9Hp8VoA?pwd=yayl 
提取码:yayl

物联沃分享整理
物联沃-IOTWORD物联网 » 了解ADC DMA的五路模拟量灰度传感器

发表评论