我试图通过I2C协议控制BMP180。问题是Pic总是重置。我改变了Pic,它是一样的。
配置代码是下一个:
#include <xc.h>
// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.
// CONFIG1H
#pragma config OSC = INTIO7 // Oscillator Selection bits (Internal oscillator block, CLKO function on RA6, port function on RA7)
#pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enable bit (Fail-Safe Clock Monitor disabled)
#pragma config IESO = OFF // Internal/External Oscillator Switchover bit (Oscillator Switchover mode disabled)
// CONFIG2L
#pragma config PWRT = OFF // Power-up Timer Enable bit (PWRT disabled)
#pragma config BOREN = SBORDIS // Brown-out Reset Enable bits (Brown-out Reset enabled in hardware only (SBOREN is disabled))
#pragma config BORV = 3 // Brown Out Reset Voltage bits (Minimum setting)
// CONFIG2H
#pragma config WDT = OFF // Watchdog Timer Enable bit (WDT disabled)
#pragma config WDTPS = 32768 // Watchdog Timer Postscale Select bits (1:32768)
// CONFIG3H
#pragma config CCP2MX = PORTC // CCP2 MUX bit (CCP2 input/output is multiplexed with RC1)
#pragma config PBADEN = ON // PORTB A/D Enable bit (PORTB<4:0> pins are configured as analog input channels on Reset)
#pragma config LPT1OSC = OFF // Low-Power Timer1 Oscillator Enable bit (Timer1 configured for higher power operation)
#pragma config MCLRE = ON // MCLR Pin Enable bit (MCLR pin enabled; RE3 input pin disabled)
// CONFIG4L
#pragma config STVREN = ON // Stack Full/Underflow Reset Enable bit (Stack full/underflow will cause Reset)
#pragma config LVP = ON // Single-Supply ICSP Enable bit (Single-Supply ICSP enabled)
#pragma config XINST = OFF // Extended Instruction Set Enable bit (Instruction set extension and Indexed Addressing mode disabled (Legacy mode))
// CONFIG5L
#pragma config CP0 = OFF // Code Protection bit (Block 0 (000800-001FFFh) not code-protected)
#pragma config CP1 = OFF // Code Protection bit (Block 1 (002000-003FFFh) not code-protected)
#pragma config CP2 = OFF // Code Protection bit (Block 2 (004000-005FFFh) not code-protected)
#pragma config CP3 = OFF // Code Protection bit (Block 3 (006000-007FFFh) not code-protected)
// CONFIG5H
#pragma config CPB = OFF // Boot Block Code Protection bit (Boot block (000000-0007FFh) not code-protected)
#pragma config CPD = OFF // Data EEPROM Code Protection bit (Data EEPROM not code-protected)
// CONFIG6L
#pragma config WRT0 = OFF // Write Protection bit (Block 0 (000800-001FFFh) not write-protected)
#pragma config WRT1 = OFF // Write Protection bit (Block 1 (002000-003FFFh) not write-protected)
#pragma config WRT2 = OFF // Write Protection bit (Block 2 (004000-005FFFh) not write-protected)
#pragma config WRT3 = OFF // Write Protection bit (Block 3 (006000-007FFFh) not write-protected)
// CONFIG6H
#pragma config WRTC = OFF // Configuration Register Write Protection bit (Configuration registers (300000-3000FFh) not write-protected)
#pragma config WRTB = OFF // Boot Block Write Protection bit (Boot block (000000-0007FFh) not write-protected)
#pragma config WRTD = OFF // Data EEPROM Write Protection bit (Data EEPROM not write-protected)
// CONFIG7L
#pragma config EBTR0 = OFF // Table Read Protection bit (Block 0 (000800-001FFFh) not protected from table reads executed in other blocks)
#pragma config EBTR1 = OFF // Table Read Protection bit (Block 1 (002000-003FFFh) not protected from table reads executed in other blocks)
#pragma config EBTR2 = OFF // Table Read Protection bit (Block 2 (004000-005FFFh) not protected from table reads executed in other blocks)
#pragma config EBTR3 = OFF // Table Read Protection bit (Block 3 (006000-007FFFh) not protected from table reads executed in other blocks)
// CONFIG7H
#pragma config EBTRB = OFF // Boot Block Table Read Protection bit (Boot block (000000-0007FFh) not protected from table reads executed in other blocks)
和主代码:
#include <xc.h>
#include <stdint.h>
#define EAUSART_V4
#include <plib/usart.h>
#include "i2c.h"
#define OSCCON_Init 0b11111111
#define BMP180_W 0xEE
#define BMP180_R 0xEF
#define I2C_master_ACK 1
#define I2C_master_NOACK 0
#define I2C_WRITE_CMD 0
#define I2C_READ_CMD 1
#define I2C_START_CMD 0
#define I2C_REP_START_CMD 1
#define I2C_REQ_ACK 0
#define I2C_REQ_NOACK 0
#define SDA_TRIS TRISCbits.RC4
#define SCL_TRIS TRISCbits.RC3
char CaracterRx;
int nummer = 0;
uint8_t data;
uint16_t temperature;
uint8_t BMP180_present(void);
void i2c_master_ack(unsigned char);
uint16_t BMP180_Temperature_Lecture(void);
void main(void) {
char hello[] ={"hello therern "};
SSPSTATbits.CKE = 1;
SDA_TRIS = 1;
SCL_TRIS = 1;
OSCCON = OSCCON_Init;
OpenUSART(USART_TX_INT_ON &
USART_RX_INT_ON &
USART_ASYNCH_MODE &
USART_EIGHT_BIT &
USART_CONT_RX &
USART_BRGH_HIGH, 51);
putsUSART("2");
for(int i=0; i<10 ; i++)
__delay_ms(50);
SSPADD=19;
OpenI2C(MASTER,SLEW_OFF);
putsUSART(&hello);
for(int i=0; i<10 ; i++)
__delay_ms(50);
while(1)
{
data = BMP180_present();
temperature = BMP180_Temperature_Lecture();
nummer = data;
putsUSART(nummer);
for(int i=0; i<50; i++)
__delay_ms(50);
}
}
uint8_t BMP180_present(void)
{//returns true if a bmp is detected.
//Detection achieved by looking at the device ID, which is fixed at 0x55.
uint8_t Id;
StartI2C();
WriteI2C(BMP180_W);
WriteI2C(0xD0);
RestartI2C();
WriteI2C(BMP180_R);
Id=ReadI2C();
StopI2C();
return Id;
}
uint16_t BMP180_Temperature_Lecture(void)
{
uint16_t value;
uint8_t prueba1, prueba2;
StartI2C();
WriteI2C(BMP180_W);
WriteI2C(0xF4);
WriteI2C(0x2E);
StopI2C();
__delay_ms(5);
WriteI2C(BMP180_W);
WriteI2C(0xF6);
RestartI2C();
WriteI2C(BMP180_R);
prueba1=ReadI2C();//Value in F6
i2c_master_ack(I2C_master_ACK);
prueba2=ReadI2C();//Value in F7
i2c_master_ack(I2C_master_NOACK);
StopI2C();
value = prueba1<<8 | prueba2;
return value;
}
void i2c_master_ack(unsigned char ack_type)
{
SSPCON2bits.ACKDT = ack_type; // 1 = Not Acknowledge, 0 = Acknowledge
SSPCON2bits.ACKEN = 1; // Enable Acknowledge
while (SSPCON2bits.ACKEN == 1);
}
我将数据通过串行发送到Arduino,并将其打印到计算机上。当我试图打印它时,它几乎总是只打印"2",有时,他写句子并打印包含BMP180的模块的数据。但大多数时候,Arduino显示的是:22222222…我已经测试了设置MCLR = OFF,但它仍然是相同的。
SDA和SCL通道的电阻为4.7k至3.5V。模块供电3.5V,但pic供电5V。我不认为这个模块的问题是强度太高。我是不是忘了什么?
奇怪的是,当我触摸pic时(当我试图改变一些电线或其他东西时),它会自动复位。
非常感谢。
Manuel。听起来你有一些严重的噪音问题。乍一看,你的代码似乎没有什么问题。当一个未使用的引脚浮在水面上时,它就像一个高阻抗天线,基本上可以接收附近的任何和所有信号,不管它们是什么。在这种情况下,电力消耗也会急剧上升。这也许可以解释为什么每次触摸PIC都会重置。根据个人经验,我建议你做以下部分或全部:
-
设置所有未使用的引脚作为数字输出,并使用LAT寄存器将它们拉到地。例如,如果您不使用RA2引脚,请将此置于主函数的开头:
TRISAbits。
LATAbits。
为所有未使用的引脚执行此操作。这将大大降低你的功耗。
- 确保在5V(在您的情况下)和复位引脚之间连接了正确的电阻值。如果该值高于或低于数据表中的建议值,有时会出现问题。
- 测量对应引脚上的PIC电源电压。你可以用万用表,但我建议你使用示波器,如果你有机会。将其连接到PIC的电源引脚,并在通过I2C发送数据时测量值。电源电压可能会下降,导致断电复位,即在您的情况下电压降至3V以下,控制器复位。如果是这样的话,清除BOREN位将是一个可能的解决方案,然而,这样的功率下降表明你的电路有更大的问题,所以我建议你再研究一下。