现在的智能手机其实都带光强传感器,大体是这样的,在光照强的地方,屏幕也亮,因此有利于看清楚屏幕上的字,之前发过呼吸灯的例子,这里我再加上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 --\r\n" \
- "-- "BOARD_NAME" --\r\n" \
- "-- 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)
- {}
- }
-
本帖最后由 梭罗瓦尔登 于 2015-2-28 13:40 编辑