本文介紹兩種使用方法
一、編寫讀取AD值的函數(shù),之后判斷AD值,進行相應(yīng)操作,比如點燈。
二、用ADC讀取光敏傳感器AO口輸出,并配置ADC通道看門狗監(jiān)控這條通道,當(dāng)光線太暗時打開LED燈。
之后會再介紹可編程RGB燈帶WS2812B。
光敏傳感器介紹
光敏傳感器有兩個輸出口,一個是DO(Digital Output),一個是AO(Analog Output),DO是數(shù)字輸出,只會輸出0或1,AO是模擬輸出,可以配合stm32的ADC轉(zhuǎn)換器得到數(shù)值存放在12位的寄存器中,因此AD值的范圍是4095 - 0,即2的12次方-1到2的0次方。
程序代碼
#include "LightAD.h"
#include "stm32f10x.h" // Device header
#include "LED.h"
#define RCC_LightADC RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOA
#define GPIO_LightADC GPIOA
#define PIN_LightADC GPIO_Pin_0
#define Channel_LightADC ADC_Channel_0
unsigned int HighThreshold = 3000;
unsigned int LowThreshold = 0;
//用AD轉(zhuǎn)換配合模擬看門狗 單次轉(zhuǎn)換非掃描
extern char BrightEnough;
先宏定義引腳和通道,定義三個變量,兩個是看門狗監(jiān)控的高低閾值,一個是main.c中定義的標(biāo)志位,判斷當(dāng)前光線是否夠亮。
void Light_GPIOInit()
{
GPIO_InitTypeDef GPIO_AD;
GPIO_AD.GPIO_Mode = GPIO_Mode_AIN;
GPIO_AD.GPIO_Pin = PIN_LightADC;
GPIO_AD.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIO_LightADC,&GPIO_AD);
}
配置GPIO口,注意GPIO模式要選擇模擬輸入。
void WatchDog_ADInit()
{
ADC_AnalogWatchdogSingleChannelConfig(ADC1, Channel_LightADC);
ADC_AnalogWatchdogThresholdsConfig(ADC1,HighThreshold,LowThreshold);
ADC_AnalogWatchdogCmd(ADC1,ADC_AnalogWatchdog_SingleRegEnable);
ADC_ITConfig(ADC1,ADC_IT_AWD,ENABLE);
}
配置看門狗,選擇ADC1或2,選擇對應(yīng)通道,這里只有一個光敏傳感器,一般選擇通道0。
void Light_NVICInit()
{
NVIC_InitTypeDef nvic_struct;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
nvic_struct.NVIC_IRQChannel = ADC1_2_IRQn;
nvic_struct.NVIC_IRQChannelCmd = ENABLE;
nvic_struct.NVIC_IRQChannelPreemptionPriority = 3;
nvic_struct.NVIC_IRQChannelSubPriority = 3;
NVIC_Init(&nvic_struct);
}
開啟NVIC通道,優(yōu)先級隨便填。
void ADC1_2_IRQHandler()
{
if(ADC_GetITStatus(ADC1,ADC_IT_AWD) == 1)
{
BrightEnough = 0;
LEDOn();
ADC_ClearITPendingBit(ADC1,ADC_IT_AWD);
}
}
配置中斷函數(shù),當(dāng)進入中斷,則光線不夠亮,并打開LED燈,最后清除標(biāo)志位,注意中斷標(biāo)志位是ADC_IT_AWD。
void Light_ADInit()
{
//ADC1通道0在PA0
RCC_APB2PeriphClockCmd(RCC_LightADC,ENABLE);
RCC_ADCCLKConfig(RCC_PCLK2_Div6);//最高14Mhz,72 六分頻 12Mhz
Light_GPIOInit();//1
//選擇規(guī)則組的輸入通道
//通道0,序列1,中等采樣時間
ADC_RegularChannelConfig(ADC1, Channel_LightADC, 1, ADC_SampleTime_55Cycles5);
//初始化ADC
ADC_InitTypeDef adc_struct;
adc_struct.ADC_Mode = ADC_Mode_Independent;
adc_struct.ADC_DataAlign = ADC_DataAlign_Right;
adc_struct.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
adc_struct.ADC_NbrOfChannel = 1;
adc_struct.ADC_ContinuousConvMode = DISABLE;
adc_struct.ADC_ScanConvMode = DISABLE;
//單次轉(zhuǎn)換非掃描,只有一個通道
ADC_Init(ADC1,&adc_struct);
//配置看門狗和中斷
WatchDog_ADInit();//2
Light_NVICInit();//3
ADC_Cmd(ADC1,ENABLE);
//先復(fù)位校準(zhǔn)
ADC_ResetCalibration(ADC1);
while(ADC_GetResetCalibrationStatus(ADC1) == 1);
//等待復(fù)位校準(zhǔn)完成,當(dāng)寄存器軟件置1開始校準(zhǔn),校準(zhǔn)完硬件置0
ADC_StartCalibration(ADC1);
while(ADC_GetCalibrationStatus(ADC1) == 1);
}
配置ADC,選擇規(guī)則組的輸入通道,選擇ADC獨立模式,而不是ADC1和ADC2共同工作的合作模式,后者的優(yōu)勢是轉(zhuǎn)換更快,但是沒必要,ADC轉(zhuǎn)換時間是很短的,下面會有計算。設(shè)置數(shù)據(jù)對齊方式是右對齊。一般都是設(shè)置右對齊,左右對齊的知識大家可以自行搜索。選擇不設(shè)置外部觸發(fā)源,選擇單次觸發(fā),非掃描模式。通道數(shù)量設(shè)置為1條。之后記得復(fù)位校準(zhǔn),否則可能造成數(shù)值漂移。
//可以采用單次掃描更改掃描通道的方式來實現(xiàn)多通道采集,注意修改GPIO初始化引腳
unsigned int Light_GetADVal()
{
ADC_SoftwareStartConvCmd(ADC1,ENABLE);
while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC) == 0);
//等待規(guī)則組轉(zhuǎn)換完成
//采樣時間是55.5,轉(zhuǎn)換固定周期是12.5,一共68個周期
//72MHZ6分頻,12Mhz 68個周期,時間大約是1/12M * 68,約5.6us
ADC_SoftwareStartConvCmd(ADC1,DISABLE);
return ADC_GetConversionValue(ADC1);
}
讀取AD值,AD轉(zhuǎn)換周期如程序中注釋所示,得出時間大約為5.6us,時間非常短。同時,如果有多個輸入設(shè)備,可以采用單次非掃描的方式來達到單次連續(xù)掃描的效果,只需要在一個設(shè)備讀取完之后更改下次要讀取的通道,每次讀取完之后更新AD數(shù)值和通道。
方法一只要在主函數(shù)中拿讀取到的AD值判斷后再執(zhí)行功能就行,方法二用上面的看門狗代碼配置后在看門狗中斷中配置函數(shù)即可。文章來源:http://www.zghlxwxcb.cn/news/detail-417017.html
結(jié)語
STM32的ADC功能很多,這里只是簡單介紹基本使用的方法,剩下內(nèi)容留待讀者去探索。文章來源地址http://www.zghlxwxcb.cn/news/detail-417017.html
到了這里,關(guān)于STM32——ADC讀取光敏傳感器控制LED燈,看門狗中斷的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!