光敏傳感器的主要是光敏二極管,核心是PN結(jié),利用了光電效應(yīng),對(duì)光強(qiáng)很敏感,有單向?qū)щ娦裕ぷ鲿r(shí)需要加反向電壓。光照越強(qiáng),等效電阻越小。
實(shí)驗(yàn)要求通過ADC3通道6(PF8)采集光敏二極管的電壓,然后轉(zhuǎn)換為0~100的光纖強(qiáng)度值并顯示在液晶屏上。
由下圖可知對(duì)于的通道是PF8
??首先確定我們的最小刻度,Vref = 3.3V,所以0V <= Vin <= 3.3V,所以最小刻度是3.3V / 4096(2^12)。
接下來確定轉(zhuǎn)換時(shí)間。采樣時(shí)間239.5個(gè)ADC時(shí)鐘周期為例,可以得到轉(zhuǎn)換時(shí)間為21us。
時(shí)間轉(zhuǎn)換公式參考如下公式:Tcvtmin=(12.5+X)周期=(12.5 + X)/(12MHz)=21us。
因?yàn)槭褂玫氖菃瓮ǖ?,所以不使用掃描模式。因?yàn)槲词褂玫紻MA,所以使用單次掃描模式。
由于光敏二極管是光照越強(qiáng),阻值越小,獲取的電壓值與光強(qiáng)關(guān)系成負(fù)相關(guān),所以在處理數(shù)據(jù)的時(shí)候需要在取互補(bǔ)的部分。
?
接下來編寫我們的函數(shù)代碼:
接下來編寫函數(shù)文件代碼adc_l.c:
#include "./BSP/ADC/adc_l.h"
ADC_HandleTypeDef g_adc_handle;
void adc_init(void){
ADC_ChannelConfTypeDef adc_ch_conf;
g_adc_handle.Instance = ADC3;
g_adc_handle.Init.DataAlign = ADC_DATAALIGN_RIGHT; //右對(duì)齊
g_adc_handle.Init.ScanConvMode = ADC_SCAN_DISABLE; //不掃描
g_adc_handle.Init.ContinuousConvMode = DISABLE; //單次模式
g_adc_handle.Init.NbrOfConversion = 1; //轉(zhuǎn)換通道數(shù)為1,單通道
g_adc_handle.Init.DiscontinuousConvMode = DISABLE; //不用間斷模式
g_adc_handle.Init.NbrOfDiscConversion = 0; //無間斷模式則無間斷通道
g_adc_handle.Init.ExternalTrigConv = ADC_SOFTWARE_START; //外部軟件觸發(fā)
HAL_ADC_Init(&g_adc_handle);
HAL_ADCEx_Calibration_Start(&g_adc_handle);
adc_ch_conf.Channel = ADC_CHANNEL_1;
adc_ch_conf.Rank = ADC_REGULAR_RANK_1; //轉(zhuǎn)換順序
adc_ch_conf.SamplingTime = ADC_SMAPLINGTIME_239CYCLES_5; //設(shè)置為最大值
HAL_ADC_ConfigChannel(&g_adc_handle, &adc_ch_conf);
}
void HAL_ADC_MspInit(ADC_HandleTypeDef *hadc){
if(hadc->Instance == ADC3){
GPIO_InitTypeDef gpio_init_struct;
RCC_PeriphCLKInitTypeDef adc_clk_init = {0};
__HAL_RCC_GPIOF_CLK_ENABLE(); //使能ADC時(shí)鐘
__HAL_RCC_ADC3_CLK_ENABLE(); //使能GPIO時(shí)鐘
gpio_init_struct.Pin = GPIO_PIN_8;
gpio_init_struct.Mode = GPIO_MODE_ANALOG; //模擬模式
HAL_GPIO_Init(GPIOF, &gpio_init_struct);
adc_clk_init.PeriphClockSelection = RCC_PERIPHCLK_ADC; //選擇ADC外設(shè)時(shí)鐘設(shè)置
adc_clk_init.AdcClockSelection = RCC_ADCPCLK2_DIV6; //選擇6分頻,72/6=12MHz
HAL_RCCEx_PeriphCLKConfig(&adc_clk_init, &g_adc_handle);
}
}
uint32_t adc_get_result(void){
HAL_ADC_Start(&g_adc_handle);
HAL_ADC_PollForConversion(&g_adc_handle, 10); //第二個(gè)參數(shù)比1大就行
return (uint16_t)HAL_ADC_GetValue(&g_adc_handle);
}
uint32_t adc_get_result_average(uint32_t ch, uint8_t times){
uint32_t temp_val = 0;
uint8_t t;
for(t = 0; t < times; t++){
temp_val += adc_get_result();
delay_ms(5);
}
return temp_val / times;
}
uint8_t lsens_get_val(void){
uint32_t temp_val;
temp_val = adc_get_result();
temp_val /= 40;
if(temp_val > 100) temp_val = 100;
return (uint8_t)(100 - temp_val);
}
再編寫函數(shù)頭文件adc_l.h:
#ifndef __ADC_L_H
#define __ADC_L_H
extern ADC_HandleTypeDef g_adc_handle;
void adc_init(void);
void HAL_ADC_MspInit(ADC_HandleTypeDef *hadc);
uint32_t adc_get_result(void);
uint32_t adc_get_result_average(uint32_t ch, uint8_t times);
#endif
最后編寫我們的主函數(shù)代碼main.c:文章來源:http://www.zghlxwxcb.cn/news/detail-448078.html
#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/usart/usart.h"
#include "./SYSTEM/delay/delay.h"
#include "./USMART/usmart.h"
#include "./BSP/LED/led.h"
#include "./BSP/LCD/lcd.h"
#include "./BSP/LSENS/lsens.h"
int main(void)
{
short adcx;
HAL_Init(); /* 初始化HAL庫 */
sys_stm32_clock_init(RCC_PLL_MUL9); /* 設(shè)置時(shí)鐘, 72Mhz */
delay_init(72); /* 延時(shí)初始化 */
usart_init(115200); /* 串口初始化為115200 */
led_init(); /* 初始化LED */
lcd_init(); /* 初始化LCD */
lsens_init(); /* 初始化光敏傳感器 */
lcd_show_string(30, 50, 200, 16, 16, "STM32", RED);
lcd_show_string(30, 70, 200, 16, 16, "LSENS TEST", RED);
lcd_show_string(30, 90, 200, 16, 16, "ATOM@ALIENTEK", RED);
lcd_show_string(30, 110, 200, 16, 16, "LSENS_VAL:", BLUE);
while (1)
{
adcx = lsens_get_val();
lcd_show_xnum(30 + 10 * 8, 110, adcx, 3, 16, 0, BLUE); /* 顯示ADC的值 */
LED0_TOGGLE(); /* LED0閃爍,提示程序運(yùn)行 */
delay_ms(250);
}
}
到這里我們的函數(shù)代碼便編寫完成了文章來源地址http://www.zghlxwxcb.cn/news/detail-448078.html
到了這里,關(guān)于STM32-光敏傳感器實(shí)驗(yàn)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!