首页 > 分享 > SAM4E LED0亮度随光照自动调节(TWI读bh1750)

SAM4E LED0亮度随光照自动调节(TWI读bh1750)

本帖最后由 梭罗瓦尔登 于 2015-2-28 13:40 编辑 现在的智能手机其实都带光强传感器,大体是这样的,在光照强的地方,屏幕也亮,因此有利于看清楚屏幕上的字,之前发过呼吸灯的例子,这里我再加上BH1750来模拟智能手机的这项功能,只是做个小demo,也有很多不好的地方,大哥们就多指正 ,我利用ASF里的TWI例程加以修改,使之能够读出BH1750传感器的数据并转换成光强强度,然后根据光强设置PWM的占空比,来设置一下亮度,原理就是这样。 贴一下代码,注释都在代码里,有问题及时回帖交流,不完善的及时指正。

THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED

* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * */ #include //******************************************** 20150127修改*********************************************// #include #include "conf_board.h" //**************************************** uint32_t light=0; #define PERIOD_VALUE 547 #define BREATH_INTERVAL_PERIOD 100 /*LED暗下来一段时间*/ #define STRING_EOL "r" #define STRING_HEADER "-- EDBG TWI Information Interface Example --rn" "-- "BOARD_NAME" --rn" "-- Compiled: "__DATE__" "__TIME__" --"STRING_EOL /** TWI Bus Clock 400kHz */ #define TWI_CLK 400000 /** EDBG TWI interface address */ #define EDBG_ADDRESS 0xD1; /** Request token of EDBG TWI information interface */ #define EDBG_EXTEN_BOARDS_TOKEN 0x75; #define EDBG_KIT_DATA_TOKEN 0xD2; #define BH1750 0x5C /** I2C related structure */ twi_options_t opt; twi_packet_t packet_rx; twi_packet_t packet_tx; /* Number of times to try to send packet if failed. */ #define TIMEOUT 10 /** Read buffer */ uint8_t read_buffer[1]; /** Extension board info structure*/ uint8_t extension_map[2]; uint8_t extension_info[64]; uint16_t minimum_voltage; uint16_t maximum_voltage; uint16_t minimum_current; #ifdef CONF_KIT_DATA_EXIST /** Kit data structure*/ uint8_t kit_data[256]; #endif /** * brief Function for show the extension boards information * */ /*[中断处理程序]*/ void PWM_Handler(void) { static uint32_t ul_duty = 0; /* PWM 占空比*/ static uint8_t fade_in = 1; /* LED 淡入标志 */ static uint8_t dark_period = 0; /* LED 完全暗下来时间 */ /* 读取PWM_ISR1寄存器,同时可以拉低中断 */ uint32_t events = PWM->PWM_ISR1; /* 先确定是否是指定的中断,PWM_ISR1_CHID2表示PWM_ISR1寄存器的CHID0位*/ if ((events & PWM_ISR1_CHID2) != 0) { if (dark_period != 0) { dark_period--; return; } /* 设置新的占空比 */ PWM->PWM_CH_NUM[2].PWM_CDTYUPD = PWM_CDTY_CDTY(light/100); } } void ConfigPIO(void) { /* 引脚由外设控制 */ PIOD->PIO_PDR = PIO_PD22; /* 选择外设 */ /* PIOD选择外设D(将影响PD所有引脚) */ PIOD->PIO_ABCDSR[0] = 0; PIOD->PIO_ABCDSR[1] = 0; } /*配置PWM*/ void ConfigPWM(void) { /* 外设时钟启用,PWM的ID大于31,需要在PMC_PCER1中启用*/ PMC->PMC_PCER1 = 1 << (ID_PWM - 32); /* 禁用通道2,以进行配置 */ PWM->PWM_DIS = PWM_DIS_CHID2; /* 配置通道2,计数器时钟选择为32分频,周期左对齐,先输出低电平,不使用死区发生器。 这里需要用到较高频率的时钟,所以选择使用主时钟经32分频后的时钟(12.5 kHz)。计数器周期为400,即输出脉冲频率为125000/400 = 312.5 Hz。*/ PWM->PWM_CH_NUM[2].PWM_CMR =PWM_CMR_CPRE_MCK_DIV_32; /* 启用中断 */ PWM->PWM_IER1 = PWM_IER1_CHID2; PWM->PWM_CH_NUM[2].PWM_CPRD = PWM_CPRD_CPRD(PERIOD_VALUE); /* 设置周期 */ PWM->PWM_CH_NUM[2].PWM_CDTY = PWM_CDTY_CDTY(0); /* 设置占空比*/ /* 使能中断 */ NVIC_ClearPendingIRQ(PWM_IRQn); NVIC_SetPriority(PWM_IRQn, 0); NVIC_EnableIRQ(PWM_IRQn); /* 使能 PWM */ PWM->PWM_ENA = PWM_ENA_CHID2; } static void show_extension_boards_information(void) { //uint8_t request_token = EDBG_EXTEN_BOARDS_TOKEN; uint32_t timeout = 0; uint8_t board_num = 0; uint8_t i; uint8_t request_token[5] ={0x01,0x10,0,0,0};//地址意义看上面的宏定义 uint8_t dat[2]={0x01,0x10}; //初始值 for(i=0;i<2;i++) { packet_tx.chip = BH1750; packet_tx.addr_length = 1; packet_tx.addr[0] = request_token[i]; packet_tx.buffer = dat+i; packet_tx.length = 1; while (twi_master_write(EDBG_I2C_MODULE, &packet_tx) != TWI_SUCCESS) { /* Increment timeout counter and check if timed out. */ if (timeout++ == TIMEOUT) { puts("timeout!n"); return; } } } return; } #ifdef CONF_KIT_DATA_EXIST /* uint32_t GetData(uint8_t* REG_Address) { uint8_t H,L; H=*REG_Address; L=*(REG_Address+1); return (H<<8)+L; //合成数据 } */ static void bh1750_init(void) { uint8_t dat[2]={0x01,0x11}; //command 0x01 power on 0x10 start converting uint8_t timeout=0; uint8_t send_count; for(send_count=0;send_count<=1;send_count++)//这里要看BH1750的数据手册,它把第二个字节的数据当命令,所以我们先发俩字节来初始化它 { packet_tx.chip = BH1750; packet_tx.buffer = dat+send_count; packet_tx.length = 1; while (twi_master_write(EDBG_I2C_MODULE, &packet_tx) != TWI_SUCCESS) { // Increment timeout counter and check if timed out. if (timeout++ == TIMEOUT) { puts("timeout!!!!!!!!!!!n"); return; } } delay_ms(10); } } static void show_light_data(uint32_t *light) { uint8_t g_data[6]={0x00,0x00}; uint8_t timeout=0; uint32_t g_data_32[3]={0x00,0x00}; float lux; packet_rx.chip = BH1750; packet_rx.addr_length = 1; packet_rx.addr[0] = 0x23;//数据从0x23读出 packet_rx.buffer =g_data; packet_rx.length = 2;//要读两个字节 while (twi_master_read(EDBG_I2C_MODULE, &packet_rx) != TWI_SUCCESS) { /* Increment timeout counter and check if timed out. */ if (timeout++ == TIMEOUT) { printf("read error n"); return; } } g_data_32[0]=(g_data[0]<<8)+g_data[1];//data processing lux=(float)g_data_32[0]/1.2; /** show kit data */ printf("rLIGHT == %d n LUX == %d n",g_data_32[0],(uint)lux);//串口打印光强数据 *light=(uint32_t)lux;//数据传出去,来调节PWM从而控制led0的亮度 } #endif /** * brief Function for configuring I2C master module * * This function will configure the I2C master module with * the SERCOM module to be used and pinmux settings */ static void configure_i2c_master(void) { /* Enable the peripheral clock for TWI */ pmc_enable_periph_clk(EDBG_I2C_MODULE_ID); /* Configure the options of TWI driver */ opt.master_clk = sysclk_get_cpu_hz(); opt.speed = TWI_CLK; if (twi_master_init(EDBG_I2C_MODULE, &opt) != TWI_SUCCESS) { puts("-E-tTWI master initialization failed.r"); while (1) { /* Capture error */ } } } static void configure_console(void) { const usart_serial_options_t uart_serial_options = { .baudrate = CONF_UART_BAUDRATE, .paritytype = CONF_UART_PARITY }; /* Configure console UART. */ sysclk_enable_peripheral_clock(CONSOLE_UART_ID); stdio_serial_init(CONF_UART, &uart_serial_options); } /** * brief Main application */ int main(void) { /* Initialize the SAM system */ sysclk_init(); /* Initialize the board */ board_init(); /*Configure UART console.*/ configure_console(); /* Configure the I2C master module */ configure_i2c_master(); /* Output example information */ puts(STRING_HEADER); /* Show the extension boards information */ WDT->WDT_MR = WDT_MR_WDDIS; ConfigPWM(); ConfigPIO(); //while (1); while(1) { #ifdef CONF_KIT_DATA_EXIST bh1750_init();//初始化之后一定要等120ms delay_ms(120); show_light_data(&light); #endif } while (1) {} }

复制代码

相关知识

后期制作时,“曝光补偿”与“调节亮度”的区别
机器人制作开源方案
光照调控在景观中的应用.docx
龙鱼饲养方法之温度控制和光照调节
如何调节花卉光照?
养花中如何调节光照 ...
家庭养花怎样调节光照?
家庭养花怎样调节光照
养花中调节不好光照该...
温室光照调节和控制

网址: SAM4E LED0亮度随光照自动调节(TWI读bh1750) https://m.huajiangbk.com/newsview366611.html

所属分类:花卉
上一篇: 一种绿茶种植用光照强度可调节装置
下一篇: 23不同光照调节好望角茅膏菜分泌