如何使用中断从光传感器读取数据结果
How to read data result from light sensor using interrupts
我正在使用 Arduino mega 2560 和光传感器 BH1750FVI。为了显示我正在使用 minicom 的结果,在 Ubuntu 16.04 LTS
上工作
我编写了代码,它可以正常工作,并将从光传感器读取的数据结果发送给我,我只能读取一次信息。我不明白我是如何让它通过中断工作的(TWI_vect)并在每次使用我的 uart 时显示结果。
#include "my_header.h"
#define I2C_STATUS_MASK 0xF8
#define START_COND_TRANSMITTED 0x08
#define REPEATED_START_COND_TRANSMITTED 0x10
#define SLA_W_TRANSMITTED_ACK_RECEIVED 0x18
#define DATA_TRANSMITTED_ACK_RECEIVED 0x28
#define SLA_R_TRANSMITTED_ACK_RECEIVED 0x40
#define DATA_RECEIVED_ACK_RETURNED 0x50
#define DATA_RECEIVED_NACK_RETURNED 0x58
volatile int light_intensity = 0; // var for read data from sensor
ISR(USART0_UDRE_vect) {
if (!bufferIsEmpty(&buffer)) //if we have something to read do it
UDR0 = popFromBuff(&buffer);
else
UCSR0B &= ~_BV(UDRIE0); //disallow interrupts
}
int main(void) {
cli();
init_port(); //initialize my port
init_buffer(&buffer, BUFF_SIZE); //init ring_buffer for uart
init_uart();
TWI_init();
sei();
TWI_start(); //send start
TWI_send_SLA(WRITE); //send SLA+W to light sensor
TWI_sendData(0b00010000); //opecode for Measurement
TWI_stop(); //stop
TWI_start(); //send start
TWI_send_SLA(READ); // send SLA+R to sensor
TWI_readData(); // read data from it light_intensity = TWDR
TWI_stop(); // stop
u_printnumbers(light_intensity); /*my func that send data to ring_buffer and later
*using interrupts send it form buffer to UDR
*/
u_print("\n");
while (1) {
if (!bufferIsEmpty(&buffer)) /*if buffer is not empty allow interrupts for uart*/
UCSR0B |= _BV(UDRIE0);
}
}
所以这段代码有效,我从传感器接收数据,一切正常。但我想将它与中断 (TWI_vect) 一起使用,并一直从传感器接收数据,就像在 while() 中一样。我读了很多信息,但不明白它应该是什么样子。
你能告诉我使用带有中断 (TWI_vect) 的代码的正确方法吗?一些小例子。感谢您的帮助!
要使用中断驱动的 Two-Wirte 接口 (I²C;TWI),您必须在 TWI ISR 中实现某种状态机。
Atmel Application Note AVR135 稍微介绍一下如何做到这一点。您将必须准备好缓冲区并将事务抽象为某种结构。例如,您可以有一个
struct i2c_transfer {
uint8_t i2c_sla; /* slave address */
const uint8_t *txbuf;
size_t txbytes;
uint8_t *rxbuf;
size_t rxbytes;
}
你设置的,然后有一个函数开始传输 I2C 并通过检查 txbytes == 0 && rxbytes == 0
或是否发生错误来检查你是否完成。然后,您的 ISR 需要检查其状态并根据它应该写入和读取的字节数采取适当的行动。
我正在使用 Arduino mega 2560 和光传感器 BH1750FVI。为了显示我正在使用 minicom 的结果,在 Ubuntu 16.04 LTS
上工作我编写了代码,它可以正常工作,并将从光传感器读取的数据结果发送给我,我只能读取一次信息。我不明白我是如何让它通过中断工作的(TWI_vect)并在每次使用我的 uart 时显示结果。
#include "my_header.h"
#define I2C_STATUS_MASK 0xF8
#define START_COND_TRANSMITTED 0x08
#define REPEATED_START_COND_TRANSMITTED 0x10
#define SLA_W_TRANSMITTED_ACK_RECEIVED 0x18
#define DATA_TRANSMITTED_ACK_RECEIVED 0x28
#define SLA_R_TRANSMITTED_ACK_RECEIVED 0x40
#define DATA_RECEIVED_ACK_RETURNED 0x50
#define DATA_RECEIVED_NACK_RETURNED 0x58
volatile int light_intensity = 0; // var for read data from sensor
ISR(USART0_UDRE_vect) {
if (!bufferIsEmpty(&buffer)) //if we have something to read do it
UDR0 = popFromBuff(&buffer);
else
UCSR0B &= ~_BV(UDRIE0); //disallow interrupts
}
int main(void) {
cli();
init_port(); //initialize my port
init_buffer(&buffer, BUFF_SIZE); //init ring_buffer for uart
init_uart();
TWI_init();
sei();
TWI_start(); //send start
TWI_send_SLA(WRITE); //send SLA+W to light sensor
TWI_sendData(0b00010000); //opecode for Measurement
TWI_stop(); //stop
TWI_start(); //send start
TWI_send_SLA(READ); // send SLA+R to sensor
TWI_readData(); // read data from it light_intensity = TWDR
TWI_stop(); // stop
u_printnumbers(light_intensity); /*my func that send data to ring_buffer and later
*using interrupts send it form buffer to UDR
*/
u_print("\n");
while (1) {
if (!bufferIsEmpty(&buffer)) /*if buffer is not empty allow interrupts for uart*/
UCSR0B |= _BV(UDRIE0);
}
}
所以这段代码有效,我从传感器接收数据,一切正常。但我想将它与中断 (TWI_vect) 一起使用,并一直从传感器接收数据,就像在 while() 中一样。我读了很多信息,但不明白它应该是什么样子。 你能告诉我使用带有中断 (TWI_vect) 的代码的正确方法吗?一些小例子。感谢您的帮助!
要使用中断驱动的 Two-Wirte 接口 (I²C;TWI),您必须在 TWI ISR 中实现某种状态机。
Atmel Application Note AVR135 稍微介绍一下如何做到这一点。您将必须准备好缓冲区并将事务抽象为某种结构。例如,您可以有一个
struct i2c_transfer {
uint8_t i2c_sla; /* slave address */
const uint8_t *txbuf;
size_t txbytes;
uint8_t *rxbuf;
size_t rxbytes;
}
你设置的,然后有一个函数开始传输 I2C 并通过检查 txbytes == 0 && rxbytes == 0
或是否发生错误来检查你是否完成。然后,您的 ISR 需要检查其状态并根据它应该写入和读取的字节数采取适当的行动。