查看: 3599|回复: 0

【朋仔】SAM4E TWI读BH1750自动调节LED0亮度

[复制链接]
  • TA的每日心情

    2016-1-22 11:18
  • 签到天数: 159 天

    连续签到: 1 天

    [LV.7]常住居民III

    发表于 2015-2-28 13:01:40 | 显示全部楼层 |阅读模式
    分享到:


    现在的智能手机其实都带光强传感器,大体是这样的,在光照强的地方,屏幕也亮,因此有利于看清楚屏幕上的字,之前发过呼吸灯的例子,这里我再加上BH1750来模拟智能手机的这项功能,只是做个小demo,也有很多不好的地方,大哥们就多指正   ,我利用ASF里的TWI例程加以修改,使之能够读出BH1750传感器的数据并转换成光强强度,然后根据光强设置PWM的占空比,来设置一下亮度,原理就是这样。
    贴一下代码,注释都在代码里,有问题及时回帖交流,不完善的及时指正。
    1. /*
    2. *
    3. * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
    4. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
    5. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
    6. * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
    7. * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
    8. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
    9. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
    10. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
    11. * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
    12. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    13. * POSSIBILITY OF SUCH DAMAGE.
    14. *
    15. *
    16. */

    17. #include <asf.h>//********************************************与非朋 20150127修改*********************************************//
    18. #include <string.h>
    19. #include "conf_board.h"
    20. //****************************************

    21. uint32_t light=0;

    22. #define PERIOD_VALUE 547
    23. #define BREATH_INTERVAL_PERIOD 100 /*LED暗下来一段时间*/


    24. #define STRING_EOL "\r"
    25. #define STRING_HEADER "-- EDBG TWI Information Interface Example --\r\n" \
    26. "-- "BOARD_NAME" --\r\n" \
    27. "-- Compiled: "__DATE__" "__TIME__" --"STRING_EOL
    28. /** TWI Bus Clock 400kHz */
    29. #define TWI_CLK 400000
    30. /** EDBG TWI interface address */
    31. #define EDBG_ADDRESS 0xD1;
    32. /** Request token of EDBG TWI information interface */
    33. #define EDBG_EXTEN_BOARDS_TOKEN 0x75;
    34. #define EDBG_KIT_DATA_TOKEN 0xD2;

    35. #define BH1750 0x5C
    36. /** I2C related structure */
    37. twi_options_t opt;
    38. twi_packet_t packet_rx;
    39. twi_packet_t packet_tx;
    40. /* Number of times to try to send packet if failed. */
    41. #define TIMEOUT 10
    42. /** Read buffer */
    43. uint8_t read_buffer[1];
    44. /** Extension board info structure*/
    45. uint8_t extension_map[2];
    46. uint8_t extension_info[64];
    47. uint16_t minimum_voltage;
    48. uint16_t maximum_voltage;
    49. uint16_t minimum_current;

    50. #ifdef CONF_KIT_DATA_EXIST
    51. /** Kit data structure*/
    52. uint8_t kit_data[256];
    53. #endif
    54. /**
    55. * \brief Function for show the extension boards information
    56. *
    57. */
    58. /*[中断处理程序]*/
    59. void PWM_Handler(void)
    60. {
    61. static uint32_t ul_duty = 0; /* PWM 占空比*/
    62. static uint8_t fade_in = 1; /* LED 淡入标志 */
    63. static uint8_t dark_period = 0; /* LED 完全暗下来时间 */

    64. /* 读取PWM_ISR1寄存器,同时可以拉低中断 */
    65. uint32_t events = PWM->PWM_ISR1;
    66. /* 先确定是否是指定的中断,PWM_ISR1_CHID2表示PWM_ISR1寄存器的CHID0位*/
    67. if ((events & PWM_ISR1_CHID2) != 0)
    68. {
    69. if (dark_period != 0)
    70. {
    71. dark_period--;
    72. return;
    73. }


    74. /* 设置新的占空比 */
    75. PWM->PWM_CH_NUM[2].PWM_CDTYUPD = PWM_CDTY_CDTY(light/100);
    76. }
    77. }

    78. void ConfigPIO(void)
    79. {
    80. /* 引脚由外设控制 */
    81. PIOD->PIO_PDR = PIO_PD22;
    82. /* 选择外设 */
    83. /* PIOD选择外设D(将影响PD所有引脚) */
    84. PIOD->PIO_ABCDSR[0] = 0;
    85. PIOD->PIO_ABCDSR[1] = 0;
    86. }
    87. /*配置PWM*/
    88. void ConfigPWM(void)
    89. {
    90. /* 外设时钟启用,PWM的ID大于31,需要在PMC_PCER1中启用*/
    91. PMC->PMC_PCER1 = 1 << (ID_PWM - 32);
    92. /* 禁用通道2,以进行配置 */
    93. PWM->PWM_DIS = PWM_DIS_CHID2;
    94. /* 配置通道2,计数器时钟选择为32分频,周期左对齐,先输出低电平,不使用死区发生器。
    95. 这里需要用到较高频率的时钟,所以选择使用主时钟经32分频后的时钟(12.5 kHz)。计数器周期为400,即输出脉冲频率为125000/400 = 312.5 Hz。*/
    96. PWM->PWM_CH_NUM[2].PWM_CMR =PWM_CMR_CPRE_MCK_DIV_32;
    97. /* 启用中断 */
    98. PWM->PWM_IER1 = PWM_IER1_CHID2;
    99. PWM->PWM_CH_NUM[2].PWM_CPRD = PWM_CPRD_CPRD(PERIOD_VALUE); /* 设置周期 */
    100. PWM->PWM_CH_NUM[2].PWM_CDTY = PWM_CDTY_CDTY(0); /* 设置占空比*/
    101. /* 使能中断 */
    102. NVIC_ClearPendingIRQ(PWM_IRQn);
    103. NVIC_SetPriority(PWM_IRQn, 0);
    104. NVIC_EnableIRQ(PWM_IRQn);
    105. /* 使能 PWM */
    106. PWM->PWM_ENA = PWM_ENA_CHID2;
    107. }



    108. static void show_extension_boards_information(void)
    109. {
    110. //uint8_t request_token = EDBG_EXTEN_BOARDS_TOKEN;
    111. uint32_t timeout = 0;
    112. uint8_t board_num = 0;
    113. uint8_t i;
    114. uint8_t request_token[5] ={0x01,0x10,0,0,0};//地址意义看上面的宏定义
    115. uint8_t dat[2]={0x01,0x10}; //初始值

    116. for(i=0;i<2;i++)
    117. { packet_tx.chip = BH1750;
    118. packet_tx.addr_length = 1;
    119. packet_tx.addr[0] = request_token[i];
    120. packet_tx.buffer = dat+i;
    121. packet_tx.length = 1;

    122. while (twi_master_write(EDBG_I2C_MODULE, &packet_tx) != TWI_SUCCESS) {
    123. /* Increment timeout counter and check if timed out. */
    124. if (timeout++ == TIMEOUT) {
    125. puts("timeout!\n");
    126. return;
    127. }
    128. }
    129. }



    130. return;
    131. }







    132. #ifdef CONF_KIT_DATA_EXIST
    133. /*
    134. uint32_t GetData(uint8_t* REG_Address)
    135. {
    136. uint8_t H,L;

    137. H=*REG_Address;
    138. L=*(REG_Address+1);
    139. return (H<<8)+L; //合成数据
    140. }
    141. */
    142. static void bh1750_init(void)
    143. {
    144. uint8_t dat[2]={0x01,0x11}; //command 0x01 power on 0x10 start converting
    145. uint8_t timeout=0;
    146. uint8_t send_count;

    147. for(send_count=0;send_count<=1;send_count++)//这里要看BH1750的数据手册,它把第二个字节的数据当命令,所以我们先发俩字节来初始化它
    148. {
    149. packet_tx.chip = BH1750;
    150. packet_tx.buffer = dat+send_count;
    151. packet_tx.length = 1;

    152. while (twi_master_write(EDBG_I2C_MODULE, &packet_tx) != TWI_SUCCESS) {
    153. // Increment timeout counter and check if timed out.
    154. if (timeout++ == TIMEOUT) {
    155. puts("timeout!!!!!!!!!!!\n");
    156. return;
    157. }
    158. }
    159. delay_ms(10);
    160. }




    161. }
    162. static void show_light_data(uint32_t *light)
    163. {
    164. uint8_t g_data[6]={0x00,0x00};
    165. uint8_t timeout=0;
    166. uint32_t g_data_32[3]={0x00,0x00};
    167. float lux;

    168. packet_rx.chip = BH1750;
    169. packet_rx.addr_length = 1;
    170. packet_rx.addr[0] = 0x23;//数据从0x23读出
    171. packet_rx.buffer =g_data;
    172. packet_rx.length = 2;//要读两个字节
    173. while (twi_master_read(EDBG_I2C_MODULE, &packet_rx) != TWI_SUCCESS) {
    174. /* Increment timeout counter and check if timed out. */
    175. if (timeout++ == TIMEOUT) {
    176. printf("\read error \n");
    177. return;
    178. }
    179. }


    180. g_data_32[0]=(g_data[0]<<8)+g_data[1];//data processing

    181. lux=(float)g_data_32[0]/1.2;
    182. /** show kit data */
    183. printf("\rLIGHT == %d \n LUX == %d \n",g_data_32[0],(uint)lux);//串口打印光强数据
    184. *light=(uint32_t)lux;//数据传出去,来调节PWM从而控制led0的亮度


    185. }
    186. #endif
    187. /**
    188. * \brief Function for configuring I2C master module
    189. *
    190. * This function will configure the I2C master module with
    191. * the SERCOM module to be used and pinmux settings
    192. */
    193. static void configure_i2c_master(void)
    194. {
    195. /* Enable the peripheral clock for TWI */
    196. pmc_enable_periph_clk(EDBG_I2C_MODULE_ID);

    197. /* Configure the options of TWI driver */
    198. opt.master_clk = sysclk_get_cpu_hz();
    199. opt.speed = TWI_CLK;

    200. if (twi_master_init(EDBG_I2C_MODULE, &opt) != TWI_SUCCESS) {
    201. puts("-E-\tTWI master initialization failed.\r");
    202. while (1) {
    203. /* Capture error */
    204. }
    205. }
    206. }

    207. static void configure_console(void)
    208. {
    209. const usart_serial_options_t uart_serial_options = {
    210. .baudrate = CONF_UART_BAUDRATE,
    211. .paritytype = CONF_UART_PARITY
    212. };
    213. /* Configure console UART. */
    214. sysclk_enable_peripheral_clock(CONSOLE_UART_ID);
    215. stdio_serial_init(CONF_UART, &uart_serial_options);
    216. }
    217. /**
    218. * \brief Main application
    219. */
    220. int main(void)
    221. {


    222. /* Initialize the SAM system */
    223. sysclk_init();
    224. /* Initialize the board */
    225. board_init();
    226. /*Configure UART console.*/
    227. configure_console();
    228. /* Configure the I2C master module */
    229. configure_i2c_master();
    230. /* Output example information */
    231. puts(STRING_HEADER);
    232. /* Show the extension boards information */

    233. WDT->WDT_MR = WDT_MR_WDDIS;
    234. ConfigPWM();
    235. ConfigPIO();
    236. //while (1);

    237. while(1)
    238. {

    239. #ifdef CONF_KIT_DATA_EXIST

    240. bh1750_init();//初始化之后一定要等120ms
    241. delay_ms(120);
    242. show_light_data(&light);

    243. #endif
    244. }
    245. while (1)
    246. {}
    247. }
    复制代码
    addr.png

    这是命令 初始化完要等120ms

    这是命令  初始化完要等120ms

    n81串口打印

    n81串口打印

    led0.zip

    4.21 MB, 阅读权限: 10, 下载次数: 3

    售价: 1 与非币  [记录]

    解压即可食用

    回复

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /5 下一条

    手机版|小黑屋|与非网

    GMT+8, 2024-12-23 06:20 , Processed in 0.122584 second(s), 17 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.