0

I2C プロトコルを介して BMP180 を制御しようとしています。問題は、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 there\r\n\0"};

 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 で給電されますが、写真は 5V です。このモジュールでは問題が高すぎるとは思いません。私は何かを忘れているのでしょうか?

写真に触れると(ワイヤーなどを交換しようとすると)、自動的にリセットされるのは不思議です。

どうもありがとうございました。

マヌエル。

4

1 に答える 1

0

深刻な騒音問題を抱えているようですね。一見したところ、コードに問題はないようです。未使用のピンをフローティングのままにしておくと、高インピーダンス アンテナのように機能し、基本的に、近くにあるすべての信号を拾います。この場合、消費電力も大幅に増加します。これは、PIC に触れるたびに PIC がリセットされる理由を説明している可能性があります。個人的な経験に基づいて、次のいくつかまたはすべてを実行することをお勧めします。

  1. 未使用のすべてのピンをデジタル出力として設定し、LAT レジスタを使用してそれらを GND にプルダウンします。たとえば、RA2 ピンを使用していない場合は、これをメイン関数の先頭に置きます。

    TRISAbits.RA2 = 0;

    LATAbits.LATA2 = 0;

未使用のすべてのピンに対してこれを行います。これにより、消費電力が大幅に削減されます。

  1. 5V(あなたの場合)とリセットピンの間に正しい抵抗値を接続したことを確認してください。値がデータシートで推奨されている値よりも高いか低い場合、問題が発生することがあります。
  2. 対応するピンの PIC 電源電圧を測定します。これはマルチメーターで行うこともできますが、オシロスコープを使用できる場合は使用することをお勧めします。PIC の電源ピンに接続し、I2C 経由でデータを送信している間に値を測定します。電源電圧が低下し、ブラウンアウト リセットが発生する可能性があります。つまり、電圧が 3V を下回り、コントローラがリセットされます。その場合、BOREN ビットをクリアすることで解決できる可能性がありますが、このような電力低下は回路に大きな問題があることを示しているため、さらに調査することをお勧めします。
于 2015-10-12T21:53:56.693 に答える