faruk97
Üye
- Katılım
- 1 Haz 2020
- Mesajlar
- 38
- Puanları
- 1
- Yaş
- 27
Merhaba arkadaşlar şu an uğraşmış olduğum yeni bir proje var. PIC16F1509 mikrodenetleyicisi kullanarak BMP180'den basınç ve sıcaklık değerlerini okumaya çalışıyorum. Ama bazı yerlerde hatam var. Çok uğraşmama rağmen bulamadım. Ve yardımlarınızı bekliyorum.Kodları internetten bir forumdan buldum MikroC için yazılmış ben XC8 derleyicisine uyarlamaya çalıştım. Ama bir sonuç tam olarak alamadım.
Devrenin kodları:
main.c
"BMP180.c" dosyası;
Akış Şeması
Devrenin kodları:
main.c
Kod:
// PIC16F1509 Configuration Bit Settings
// 'C' source line config statements
// CONFIG1
#pragma config FOSC = HS // Oscillator Selection Bits (HS Oscillator, High-speed crystal/resonator connected between OSC1 and OSC2 pins)
#pragma config WDTE = OFF // Watchdog Timer Enable (WDT disabled)
#pragma config PWRTE = ON // Power-up Timer Enable (PWRT enabled)
#pragma config MCLRE = ON // MCLR Pin Function Select (MCLR/VPP pin function is MCLR)
#pragma config CP = OFF // Flash Program Memory Code Protection (Program memory code protection is disabled)
#pragma config BOREN = OFF // Brown-out Reset Enable (Brown-out Reset enabled)
#pragma config CLKOUTEN = OFF // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin)
#pragma config IESO = OFF // Internal/External Switchover Mode (Internal/External Switchover Mode is disabled)
#pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is disabled)
// CONFIG2
#pragma config WRT = OFF // Flash Memory Self-Write Protection (Write protection off)
#pragma config STVREN = OFF // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will not cause a Reset)
#pragma config BORV = LO // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.)
#pragma config LPBOR = OFF // Low-Power Brown Out Reset (Low-Power BOR is disabled)
#pragma config LVP = OFF // Low-Voltage Programming Enable (High-voltage on MCLR/VPP must be used for programming)
// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.
#include <xc.h>
#include "BMP180.h"
#include "I2C.h"
#include "lcd.h"
#include <stdio.h>
#define _XTAL_FREQ 8000000
void main(void) {
CM1CON0bits.C1ON=0;
CM2CON0bits.C2ON=0;
ANSELB=0;
ANSELC=0;
TRISC=0;
i2c_kur();
lcd_baslat();
lcd_mesajyaz(1,1,"bmp180");
lcd_mesajyaz(2,1,"Genc Mucitler");
__delay_ms(1000);
lcd_sil();
BMP_Init();
while(1){
BMP_Read( 0 );
lcd_git(1,1);
//sonuc=50;
printf("%d",UT);
lcd_git(2,8);
printf("%d",TrueT);
//lcd_mesajyaz(1,1,'res');
lcd_mesajyaz(2,1,"sonuc");
}
//return;
}
"BMP180.c" dosyası;
Kod:
#include <xc.h>
#include "I2C.h"
// Note: #include "BMP180.h" in main module
#define CAL_DATA_ADDR 0xAA // start address of calibration data
#define BMP_CONTROL 0xF4 // see Figure 6 in datasheet, ctrl_meas F4h (oss, sco, meas)
#define BMP_OUT_MSB 0xF6 // see Figure 6 in datasheet, out_msb
#define BMP_READTEMPCMD 0x2E
#define BMP_READPRESSURECMD 0x34
#define _XTAL_FREQ 8000000
// Calibration data in E2PROM (named as in datasheet but with c suffix on B1 & B2 or redifined)
int AC1, AC2, AC3 ;
unsigned int AC4, AC5, AC6 ;
int B1c, B2c, MB, MC, MD ; // c suffix added to B1 & B2
// Global variables for display in main function
int TrueT ; // temperature in 0.1 degrees (named T in datasheet) so 20deg = 200
long TrueP ; // pressure in Pa (named P in datasheet) so 1013 hPa = 101300
// Global for debug purposes
int UT ; // uncompensated value of temperature
long UP ; // uncompensated value of pressure
char i2c_r;
// Internal functions
void delayOss (char oss)
{ // delay depending on oversampling oss 0 to 3, approximates to 2x^2 + x + 5
char i, do1mS ;
do1mS = 2*oss*oss + oss + 5 ; // (0, 1, 2, or 3 gives 5, 8, 15, or 26)
for (i = 0 ; i < do1mS ; i++)
__delay_ms(1) ;
}
int BMP_I2C_Rd16b (char ackm)
{ // return MSB<<8 + LSB, send ACKM if parameter ackm is 1, NACKM if ackm 0
i2c_r=i2c_oku();
return ( (i2c_r << 8) + i2c_r ) ;
}
void BMP_I2C_SetU( char reg )
{ // setup for read of UT or UP, do delay on return
BMP_I2C_Start();
BMP_I2C_Wr( I2C_ADDR_WR );
BMP_I2C_Wr( BMP_CONTROL ); // 0xF4
BMP_I2C_Wr( reg ); // write 0x2E or 0x34 into reg 0xF4
BMP_I2C_Stop();
}
void BMP_I2C_SetReg( char reg )
{ // setup for read of calibration data 0xAA, or UT/UP data 0xF6
BMP_I2C_Start(); // start condition
BMP_I2C_Wr( I2C_ADDR_WR ); // module address write command 0xEE
BMP_I2C_Wr( reg ); // select read register (calibration data 0xAA, UT/UP data 0xF6)
BMP_I2C_Start(); // restart condition
BMP_I2C_Wr( I2C_ADDR_RD ); // module address read command 0xEF
}
// Global functions
void BMP_Read( char oss )
{// read uncompensated values UT & UP, convert to true, save in global variables: TrueT & TrueP
long B3, B5, B6, X1, X2, X3, pp ;
unsigned long B4, B7;
// read uncompensated value UT
BMP_I2C_SetU( BMP_READTEMPCMD ) ; // write 0x2E into reg 0xF4: setup for UT
__delay_ms( 5 ) ; // delay 4.5mS minimum
BMP_I2C_SetReg ( BMP_OUT_MSB ) ; // select read register start 0xF6
UT = BMP_I2C_Rd16b(0) ; // read 16 bits into UT, send NACKM
BMP_I2C_Stop() ; // stop
// DEBUG Example from Bosch datasheet (TrueT should be 150, TrueP should be 69964).
// UT = 27898 ;
// read uncompensated value UP
BMP_I2C_SetU( BMP_READPRESSURECMD | (oss << 6) ) ; // write 0x34 into reg 0xF4: setup for UP
delayOss( oss ) ; // delay depends on oss
BMP_I2C_SetReg( BMP_OUT_MSB ) ; // select read register start 0xF6
UP = BMP_I2C_Rd16b(1) ; // read MSB + LSB into UP, send ACKM
UP = UP<<8 | BMP_I2C_Rd(0) ; // read XLSB into UP, send NACKM
UP = UP>>(8-oss) ; // adjust for oss
BMP_I2C_Stop() ; // stop
// DEBUG Example from Bosch datasheet
// UP = 23843;
//Calculate True Temperature
X1 = (( (long)UT - (long)AC6)*(long)AC5) >> 15 ;
X2 = ( (long)MC << 11)/(X1 + MD) ;
B5 = X1 + X2 ; // long B5 used in calculation of True Pressure
TrueT = ( (B5 + 8) >> 4 ) ; // TrueT is temperature in 0.1 degrees
//Calculate True Pressure
// Calculate B6
B6 = B5 - 4000 ;
// Calculate B3
X1 = ((long)B2c * (long)(B6*B6)>>12) >>11 ;
X2 = ((long)AC2 * (long)B6) >>11 ;
X3 = X1 + X2 ;
B3 = ((( (long)AC1*4 + X3) <<oss) + 2) >>2 ;
// Calculate B4
X1 = (AC3 * B6) >>13 ;
X2 = (B1c * ((B6 * B6)>>12)) >>16 ;
X3 = ((X1 + X2) + 2 ) >>2 ;
B4 = (AC4 * (unsigned long)(X3 + 32768)) >>15 ;
B7 = ((unsigned long)(UP - B3) * (unsigned long)(50000 >>oss)) ;
if( B7 < 0x80000000 )
{ pp = ((B7 <<1) / B4) ; }
else
{ pp = ((B7 / B4) <<1) ; }
X1 = (pp >>8)*(pp >>8) ;
X1 = (X1 * 3038) >>16; // original says * 1519; ???
X2 = (-7357 * pp) >>16;
TrueP = pp + ((X1 + X2 + 3791) >>4) ; // pressure in Pa 101300
}
void BMP_Init()
{
BMP_I2C_SetReg ( CAL_DATA_ADDR ) ; // select read register at start of calibration data 0xAA
// load up calibration data
AC1 = (int)BMP_I2C_Rd16b(1) ;
AC2 = (int)BMP_I2C_Rd16b(1) ;
AC3 = (int)BMP_I2C_Rd16b(1) ;
AC4 = (unsigned int)BMP_I2C_Rd16b(1) ;
AC5 = (unsigned int)BMP_I2C_Rd16b(1) ;
AC6 = (unsigned int)BMP_I2C_Rd16b(1) ;
B1c = (int)BMP_I2C_Rd16b(1) ;
B2c = (int)BMP_I2C_Rd16b(1) ;
MB = (int)BMP_I2C_Rd16b(1) ;
MC = (int)BMP_I2C_Rd16b(1) ;
MD = (int)BMP_I2C_Rd16b(0) ; // send NACKM before stop
BMP_I2C_Stop();
// DEBUG Example from Bosch datasheet
// AC1 = 408; AC2 = -72; AC3 = -14383; AC4 = 32741; AC5 = 32757; AC6 = 23153;
// B1c = 6190; B2c = 4; MB = -32768; MC = -8711; MD = 2868;
}
Akış Şeması