我试图将LPS331AP压力传感器连接到我的ATtiny85,以从中读取压力。我的代码在Arduino Uno上可以完美运行,但是在多个论坛上进行建议的相关更改时,我遇到了一些我不知道如何解决的错误。我正在使用Wire.h,twi.h,TinyWire.h和LPS.h库,但无济于事。
我尝试过编辑库以符合不同的功能错误,并声明了引脚,但是我无法使其正常工作。我已重置所有内容,使用的代码和库如下所示:
我尝试执行的代码如下所示:
#include <TinyWire.h>
#include "USI_TWI_Master.h"
#include <LPS.h>
LPS ps;
void setup()
{
TinyWire.begin();
ps.enableDefault();
}
void loop()
{
float pressure = ps.readPressureMillibars();
float altitude = ps.pressureToAltitudeMeters(pressure);
float temperature = ps.readTemperatureC();
delay(100);
}
我希望代码能够正确上传,然后就可以开始编写代码来处理数据并进行计算了。目前,我收到以下错误:
Arduino: 1.8.9 (Windows 7), Board: "ATtiny25/45/85, ATtiny85, Internal 8 MHz"
Build options changed, rebuilding all
C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\Wire\src\utility\twi.c: In function 'twi_init':
C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\Wire\src\utility\twi.c:76:16: error: 'SDA' undeclared (first use in this function)
digitalWrite(SDA, 1);
^
C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\Wire\src\utility\twi.c:76:16: note: each undeclared identifier is reported only once for each function it appears in
C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\Wire\src\utility\twi.c:77:16: error: 'SCL' undeclared (first use in this function)
digitalWrite(SCL, 1);
^
In file included from c:\program files (x86)\arduino\hardware\tools\avr\avr\include\avr\io.h:99:0,
from C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\Wire\src\utility\twi.c:25:
C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\Wire\src\utility\twi.c:80:7: error: 'TWSR' undeclared (first use in this function)
cbi(TWSR, TWPS0);
^
C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\Wire\src\utility\twi.c:80:3: note: in expansion of macro 'cbi'
cbi(TWSR, TWPS0);
^
C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\Wire\src\utility\twi.c:80:13: error: 'TWPS0' undeclared (first use in this function)
cbi(TWSR, TWPS0);
^
C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\Wire\src\utility\twi.c:80:3: note: in expansion of macro 'cbi'
cbi(TWSR, TWPS0);
^
C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\Wire\src\utility\twi.c:81:13: error: 'TWPS1' undeclared (first use in this function)
cbi(TWSR, TWPS1);
^
C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\Wire\src\utility\twi.c:81:3: note: in expansion of macro 'cbi'
cbi(TWSR, TWPS1);
^
C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\Wire\src\utility\twi.c:82:3: error: 'TWBR' undeclared (first use in this function)
TWBR = ((F_CPU / TWI_FREQ) - 16) / 2;
^
In file included from c:\program files (x86)\arduino\hardware\tools\avr\avr\include\avr\io.h:99:0,
from C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\Wire\src\utility\twi.c:25:
C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\Wire\src\utility\twi.c:393:14: error: 'TWEN' undeclared (first use in this function)
TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT);
^
C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\Wire\src\utility\twi.c:393:26: error: 'TWIE' undeclared (first use in this function)
TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT);
^
C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\Wire\src\utility\twi.c:393:38: error: 'TWEA' undeclared (first use in this function)
TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT);
^
C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\Wire\src\utility\twi.c:393:50: error: 'TWINT' undeclared (first use in this function)
TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT);
^
In file included from c:\program files (x86)\arduino\hardware\tools\avr\avr\include\compat\twi.h:36:0,
from C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\Wire\src\utility\twi.c:27:
C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\Wire\src\utility\twi.c: In function 'TWI_vect':
C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\Wire\src\utility\twi.c:401:10: error: 'TWSR' undeclared (first use in this function)
switch(TW_STATUS){
^
In file included from c:\program files (x86)\arduino\hardware\tools\avr\avr\include\avr\io.h:99:0,
from C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\Wire\src\utility\twi.c:25:
C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\Wire\src\utility\twi.c:401:10: error: 'TWS7' undeclared (first use in this function)
switch(TW_STATUS){
^
C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\Wire\src\utility\twi.c:401:10: error: 'TWS6' undeclared (first use in this function)
switch(TW_STATUS){
^
C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\Wire\src\utility\twi.c:401:10: error: 'TWS5' undeclared (first use in this function)
switch(TW_STATUS){
^
C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\Wire\src\utility\twi.c:401:10: error: 'TWS4' undeclared (first use in this function)
switch(TW_STATUS){
^
C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\Wire\src\utility\twi.c:401:10: error: 'TWS3' undeclared (first use in this function)
switch(TW_STATUS){
^
C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\Wire\src\utility\twi.c:406:7: error: 'TWDR' undeclared (first use in this function)
TWDR = twi_slarw;
^
C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\Wire\src\utility\twi.c:426:4: error: 'TWCR' undeclared (first use in this function)
TWCR = _BV(TWINT) | _BV(TWSTA)| _BV(TWEN) ;
^
In file included from c:\program files (x86)\arduino\hardware\tools\avr\avr\include\avr\io.h:99:0,
from C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\Wire\src\utility\twi.c:25:
C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\Wire\src\utility\twi.c:426:15: error: 'TWINT' undeclared (first use in this function)
TWCR = _BV(TWINT) | _BV(TWSTA)| _BV(TWEN) ;
^
C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\Wire\src\utility\twi.c:426:28: error: 'TWSTA' undeclared (first use in this function)
TWCR = _BV(TWINT) | _BV(TWSTA)| _BV(TWEN) ;
^
C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\Wire\src\utility\twi.c:426:40: error: 'TWEN' undeclared (first use in this function)
TWCR = _BV(TWINT) | _BV(TWSTA)| _BV(TWEN) ;
^
exit status 1
Error compiling for board ATtiny25/45/85.
This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.
我使用的库如下所示。 .h和.c库位于我的本地项目文件夹中:
TinyWire.h:
/*****************************************************************************
*
*
* File TinyWire.h
* Date Saturday, 10/29/17
* Composed by lucullus
*********************************************************************************/
#ifndef tiny_twi_h
#define tiny_twi_h
#include <inttypes.h>
//********** Master Error Codes **********//
// Note these have been renumbered from the Atmel Apps Note. Most likely errors are now
// lowest numbers so they're easily recognized as LED flashes.
#define USI_TWI_NO_DATA 0x08 // Transmission buffer is empty
#define USI_TWI_DATA_OUT_OF_BOUND 0x09 // Transmission buffer is outside SRAM space
#define USI_TWI_UE_START_CON 0x07 // Unexpected Start Condition
#define USI_TWI_UE_STOP_CON 0x06 // Unexpected Stop Condition
#define USI_TWI_UE_DATA_COL 0x05 // Unexpected Data Collision (arbitration)
#define USI_TWI_NO_ACK_ON_DATA 0x02 // The slave did not acknowledge all data
#define USI_TWI_NO_ACK_ON_ADDRESS 0x01 // The slave did not acknowledge the address
#define USI_TWI_MISSING_START_CON 0x03 // Generated Start Condition not detected on bus
#define USI_TWI_MISSING_STOP_CON 0x04 // Generated Stop Condition not detected on bus
#define USI_TWI_BAD_MEM_READ 0x0A // Error during external memory read
#define USI_TWI_BUS_BUSY 0x0B // Another Master is using the bus
#define USI_TWI_ARBITRATION_LOST 0x0C // The master lost the arbitration due to the transmission of another master
//********** Class Definition **********//
class TinyTwi
{
private:
bool master_mode=false;
bool temp_master_mode=false;
uint8_t slave_addr=0;
static void (*user_onRequest)(void);
static void (*user_onReceive)(int);
static void onRequestService(void);
static void onReceiveService(int numBytes);
public:
TinyTwi();
void begin();
void begin(uint8_t I2C_SLAVE_ADDR);
uint8_t read();
uint8_t receive();
uint8_t available();
uint8_t send(uint8_t data);
uint8_t write(uint8_t data);
void beginTransmission(uint8_t slaveAddr);
uint8_t endTransmission();
uint8_t requestFrom(uint8_t slaveAddr, uint8_t numBytes);
void end();
void onReceive( void (*)(int) );
void onRequest( void (*)(void) );
};
extern TinyTwi TinyWire;
#endif
LPS.h:
#ifndef LPS_h
#define LPS_h
#include <Arduino.h> // for byte data type
class LPS
{
public:
enum deviceType { device_331AP, device_25H, device_auto };
enum sa0State { sa0_low, sa0_high, sa0_auto };
// register addresses
// Note: where register names differ between the register mapping table and
// the register descriptions in the datasheets, the names from the register
// descriptions are used here.
enum regAddr
{
REF_P_XL = 0x08,
REF_P_L = 0x09,
REF_P_H = 0x0A,
WHO_AM_I = 0x0F,
RES_CONF = 0x10,
CTRL_REG1 = 0x20,
CTRL_REG2 = 0x21,
CTRL_REG3 = 0x22,
CTRL_REG4 = 0x23, // 25H
STATUS_REG = 0x27,
PRESS_OUT_XL = 0x28,
PRESS_OUT_L = 0x29,
PRESS_OUT_H = 0x2A,
TEMP_OUT_L = 0x2B,
TEMP_OUT_H = 0x2C,
FIFO_CTRL = 0x2E, // 25H
FIFO_STATUS = 0x2F, // 25H
AMP_CTRL = 0x30, // 331AP
RPDS_L = 0x39, // 25H
RPDS_H = 0x3A, // 25H
DELTA_PRESS_XL = 0x3C, // 331AP
DELTA_PRESS_L = 0x3D, // 331AP
DELTA_PRESS_H = 0x3E, // 331AP
// dummy addresses for registers in different locations on different devices;
// the library translates these based on device type
// value with sign flipped is used as index into translated_regs array
INTERRUPT_CFG = -1,
INT_SOURCE = -2,
THS_P_L = -3,
THS_P_H = -4,
// update dummy_reg_count if registers are added here!
// device-specific register addresses
LPS331AP_INTERRUPT_CFG = 0x23,
LPS331AP_INT_SOURCE = 0x24,
LPS331AP_THS_P_L = 0x25,
LPS331AP_THS_P_H = 0x26,
LPS25H_INTERRUPT_CFG = 0x24,
LPS25H_INT_SOURCE = 0x25,
LPS25H_THS_P_L = 0x30,
LPS25H_THS_P_H = 0x31,
};
LPS(void);
bool init(deviceType device = device_auto, byte sa0 = sa0_auto);
deviceType getDeviceType(void) { return _device; }
byte getAddress(void) { return address; }
void enableDefault(void);
void writeReg(int reg, byte value);
byte readReg(int reg);
float readPressureMillibars(void);
float readPressureInchesHg(void);
int32_t readPressureRaw(void);
float readTemperatureC(void);
float readTemperatureF(void);
int16_t readTemperatureRaw(void);
static float pressureToAltitudeMeters(float pressure_mbar, float altimeter_setting_mbar = 1013.25);
static float pressureToAltitudeFeet(float pressure_inHg, float altimeter_setting_inHg = 29.9213);
private:
deviceType _device; // chip type (331AP or 25H)
byte address;
static const int dummy_reg_count = 4;
regAddr translated_regs[dummy_reg_count + 1]; // index 0 not used
bool detectDeviceAndAddress(deviceType device, sa0State sa0);
bool detectDevice(deviceType device);
int testWhoAmI(byte address);
};
#endif
USI_TWI_Master.h:
/*****************************************************************************
*
* Atmel Corporation
*
* File : USI_TWI_Master.h
* Compiler : AVRGCC Toolchain version 3.4.2
* Revision : $Revision: 992 $
* Date : $Date: 2013-11-07 $
* Updated by : $Author: Atmel $
*
* Support mail : [email protected]
*
* Supported devices : All device with USI module can be used.
* The example is written for the ATmega169, ATtiny26 and ATtiny2313
*
* AppNote : AVR310 - Using the USI module as a TWI Master
*
* Description : This is an implementation of an TWI master using
* the USI module as basis. The implementation assumes the AVR to
* be the only TWI master in the system and can therefore not be
* used in a multi-master system.
* Usage : Initialize the USI module by calling the USI_TWI_Master_Initialise()
* function. Hence messages/data are transceived on the bus using
* the USI_TWI_Start_Transceiver_With_Data() function. If the transceiver
* returns with a fail, then use USI_TWI_Get_Status_Info to evaluate the
* couse of the failure.
*
****************************************************************************/
#include<avr/io.h>
//********** Defines **********//
// Defines controlling timing limits
#define TWI_FAST_MODE
#define SYS_CLK 4000.0 // [kHz]
#ifdef TWI_FAST_MODE // TWI FAST mode timing limits. SCL = 100-400kHz
#define T2_TWI ((SYS_CLK *1300) /1000000) +1 // >1,3us
#define T4_TWI ((SYS_CLK * 600) /1000000) +1 // >0,6us
#else // TWI STANDARD mode timing limits. SCL <= 100kHz
#define T2_TWI ((SYS_CLK *4700) /1000000) +1 // >4,7us
#define T4_TWI ((SYS_CLK *4000) /1000000) +1 // >4,0us
#endif
// Defines controling code generating
//#define PARAM_VERIFICATION
//#define NOISE_TESTING
//#define SIGNAL_VERIFY
//USI_TWI messages and flags and bit masks
//#define SUCCESS 7
//#define MSG 0
/****************************************************************************
Bit and byte definitions
****************************************************************************/
#define TWI_READ_BIT 0 // Bit position for R/W bit in "address byte".
#define TWI_ADR_BITS 1 // Bit position for LSB of the slave address bits in the init byte.
#define TWI_NACK_BIT 0 // Bit position for (N)ACK bit.
#define USI_TWI_NO_DATA 0x00 // Transmission buffer is empty
#define USI_TWI_DATA_OUT_OF_BOUND 0x01 // Transmission buffer is outside SRAM space
#define USI_TWI_UE_START_CON 0x02 // Unexpected Start Condition
#define USI_TWI_UE_STOP_CON 0x03 // Unexpected Stop Condition
#define USI_TWI_UE_DATA_COL 0x04 // Unexpected Data Collision (arbitration)
#define USI_TWI_NO_ACK_ON_DATA 0x05 // The slave did not acknowledge all data
#define USI_TWI_NO_ACK_ON_ADDRESS 0x06 // The slave did not acknowledge the address
#define USI_TWI_MISSING_START_CON 0x07 // Generated Start Condition not detected on bus
#define USI_TWI_MISSING_STOP_CON 0x08 // Generated Stop Condition not detected on bus
// Device dependant defines
#if defined(__AVR_AT90Mega169__) | defined(__AVR_ATmega169PA__) | \
defined(__AVR_AT90Mega165__) | defined(__AVR_ATmega165__) | \
defined(__AVR_ATmega325__) | defined(__AVR_ATmega3250__) | \
defined(__AVR_ATmega645__) | defined(__AVR_ATmega6450__) | \
defined(__AVR_ATmega329__) | defined(__AVR_ATmega3290__) | \
defined(__AVR_ATmega649__) | defined(__AVR_ATmega6490__)
#define DDR_USI DDRE
#define PORT_USI PORTE
#define PIN_USI PINE
#define PORT_USI_SDA PORTE5
#define PORT_USI_SCL PORTE4
#define PIN_USI_SDA PINE5
#define PIN_USI_SCL PINE4
#endif
#if defined(__AVR_ATtiny25__) | defined(__AVR_ATtiny45__) | defined(__AVR_ATtiny85__) | \
defined(__AVR_AT90Tiny26__) | defined(__AVR_ATtiny26__)
#define DDR_USI DDRB
#define PORT_USI PORTB
#define PIN_USI PINB
#define PORT_USI_SDA PORTB0
#define PORT_USI_SCL PORTB2
#define PIN_USI_SDA PINB0
#define PIN_USI_SCL PINB2
#endif
#if defined(__AVR_AT90Tiny2313__) | defined(__AVR_ATtiny2313__)
#define DDR_USI DDRB
#define PORT_USI PORTB
#define PIN_USI PINB
#define PORT_USI_SDA PORTB5
#define PORT_USI_SCL PORTB7
#define PIN_USI_SDA PINB5
#define PIN_USI_SCL PINB7
#endif
// General defines
#define TRUE 1
#define FALSE 0
//********** Prototypes **********//
void USI_TWI_Master_Initialise( void );
unsigned char USI_TWI_Start_Transceiver_With_Data( unsigned char * , unsigned char );
unsigned char USI_TWI_Get_State_Info( void );
有关修复的任何建议将不胜感激。
最佳答案
ATtiny85没有TWI。它拥有USI来实现TWI。 USI上的操作不同于TWI上的操作,寄存器也不同。要修改库,请引用AVR310和AVR312,它们介绍了如何在TWI模式下使用USI。