Чт ноя 29, 2018 09:01:33
Чт ноя 29, 2018 09:37:05
Чт ноя 29, 2018 09:43:03
Пт ноя 30, 2018 11:27:22
Сб дек 15, 2018 22:32:36
Вс янв 20, 2019 16:21:01
Чт янв 31, 2019 22:02:49
Пн фев 04, 2019 19:39:23
uint8_t BMP280_Status;
uint32_t Pressure_pascale; // Значение давления в паскалях
uint32_t Pressure_mmHg; // Значение давления в мм.рт.с
int32_t Temperature_BMP280; // Значение температуры в градусах цельсия
unsigned char ptd[6];
int32_t t_fine;
uint16_t dig_T1;
int16_t dig_T2;
int16_t dig_T3;
uint16_t dig_P1;
int16_t dig_P2;
int16_t dig_P3;
int16_t dig_P4;
int16_t dig_P5;
int16_t dig_P6;
int16_t dig_P7;
int16_t dig_P8;
int16_t dig_P9;
int32_t bmp280_compensate_T(int32_t adc_T) // расчет температуры
{
int32_t var1;
int32_t var2;
int32_t temperature = 0;
var1 = ((((adc_T >> 3) - ((int32_t) dig_T1 << 1))) * ((int32_t) dig_T2)) >> 11;
var2 = (((((adc_T >> 4) - ((int32_t) dig_T1)) * ((adc_T >> 4) - ((int32_t) dig_T1))) >> 12) * ((int32_t) dig_T3)) >> 14;
t_fine = var1 + var2;
temperature = (t_fine * 5 + 128) >> 8;
return temperature;
}
uint32_t bmp280_compensate_P(int32_t adc_P) // расчет давления
{
int32_t var1;
int32_t var2;
uint32_t pressure = 0;
var1 = (((int32_t) t_fine) >> 1) - (int32_t) 64000;
var2 = (((var1 >> 2) * (var1 >> 2)) >> 11) * ((int32_t) dig_P6);
var2 = var2 + ((var1 * ((int32_t) dig_P5)) << 1);
var2 = (var2 >> 2) + (((int32_t) dig_P4) << 16);
var1 = (((dig_P3 * (((var1 >> 2) * (var1 >> 2)) >> 13)) >> 3) + ((((int32_t) dig_P2) * var1) >> 1)) >> 18;
var1 = ((((32768 + var1)) * ((int32_t) dig_P1)) >> 15);
pressure = (((uint32_t) (((int32_t) 1048576) - adc_P) - (var2 >> 12))) * 3125;
if (var1 != 0)
{
if (pressure < 0x80000000) pressure = (pressure << 1) / ((uint32_t) var1);
else pressure = (pressure / (uint32_t) var1) * 2;
var1 = (((int32_t) dig_P9) * ((int32_t) (((pressure >> 3) * (pressure >> 3)) >> 13))) >> 12;
var2 = (((int32_t) (pressure >> 2)) * ((int32_t) dig_P8)) >> 13;
pressure = (uint32_t) ((int32_t) pressure + ((var1 + var2 + dig_P7) >> 4));
}
else pressure = 0;
return pressure;
}
uint8_t BMP280_Update() //
{
while (BMP280_Status != NOT_BUSY) { _delay_us(10); }
while (!TWI_Read(TWI_Adress, &adr_data, 1, ptd, 6, &BMP280_Status));
do { _delay_us(10); if (BMP280_Status == TWI_SLA_W_NACK || BMP280_Status == TWI_DATA_NACK || BMP280_Status == TWI_SLA_R_NACK) return 0; }
while (BMP280_Status != NOT_BUSY);
// обязательно сначала рассчитываем температуру, а потом давление.
Temperature_BMP280 = bmp280_compensate_T(((int32_t)ptd[3]<<12) | ((int32_t)ptd[4]<<4) | ((int32_t)ptd[5]>>4));
Pressure_pascale = bmp280_compensate_P((((int32_t)ptd[0]<<12) | ((int32_t)ptd[1]<<4) | (int32_t)ptd[2]>>4));
Pressure_mmHg = Pressure_pascale/133.3224;
return 1;
}
void PreesAndTemp()
{
uint16_t t = 0;
uint8_t i = 0;
if (BMP280_Update())
{
i = 10;
i += LCD_AddSimbol(FONT1,ARIAL,(Pressure_mmHg/100)%10,4,i);
i += LCD_AddSimbol(FONT1,ARIAL,(Pressure_mmHg/10)%10,4,i);
i += LCD_AddSimbol(FONT1,ARIAL,Pressure_mmHg%10,4,i);
i += LCD_AddString(" мм рт.ст.",FONT1,ARIAL,LEFT,4,i);
i += 10;
if (Temperature_BMP280 < 0) { t = -Temperature_BMP280; i += LCD_AddSimbol(FONT1, ARIAL, '-', 4, i); }
else t = Temperature_BMP280;
if (t >= 1000) i += LCD_AddSimbol(FONT1,ARIAL,(t/1000)%10,4,i);
i += LCD_AddSimbol(FONT1,ARIAL,(t/100)%10,4,i);
i += LCD_AddSimbol(FONT1,ARIAL,'.',4,i);
i += LCD_AddSimbol(FONT1,ARIAL,(t/10)%10,4,i);
i += LCD_AddSimbol(FONT1,ARIAL,t%10,4,i);
i += LCD_AddString("°C",FONT1,ARIAL,LEFT,4,i);
}
else
{
i = 0;
switch(BMP280_Status)
{
case TWI_SLA_W_NACK: LCD_AddString("ОШИБКА! BMP280 не отвечает", FONT1, ARIAL, CENTR, 4, i); break;
case TWI_SLA_R_NACK: LCD_AddString("ОШИБКА! BMP280 не отвечает", FONT1, ARIAL, CENTR, 4, i); break;
case TWI_DATA_NACK: LCD_AddString("BMP280 ошибка передачи данных", FONT1, ARIAL, CENTR, 4, i); break;
}
}
}
Вт фев 05, 2019 14:57:35
int64_t temper_int; //глобальная переменная
...........................
.............................
float BME280_ReadTemperature(void)
{
float temper_float = 0.0f;
uint32_t temper_raw;
int32_t val1, val2;
BME280_ReadReg_BE_U24(BME280_REGISTER_TEMPDATA,&temper_raw);
temper_raw >>= 4;
val1 = ((((temper_raw>>3) - ((int32_t)CalibData.dig_T1 <<1))) *
((int32_t)CalibData.dig_T2)) >> 11;
val2 = (((((temper_raw>>4) - ((int32_t)CalibData.dig_T1)) *
((temper_raw>>4) - ((int32_t)CalibData.dig_T1))) >> 12) *
((int32_t)CalibData.dig_T3)) >> 14;
temper_int = val1 + val2;
temper_int = ((temper_int * 5 + 128) >> 8);
temper_float = temper_int/100;
if (temper_float >100) // если значение температуры перевалило в отрицательные значения
{
temper_float = 409.6-temper_float;
temper_float = -temper_float;
}
return temper_float;
}
Пт фев 08, 2019 20:20:27
int64_t temper_int; //глобальная переменная
...........................
.............................
float BME280_ReadTemperature(void)
{
float temper_float = 0.0f;
uint32_t temper_raw;
int32_t val1, val2;
BME280_ReadReg_BE_U24(BME280_REGISTER_TEMPDATA,&temper_raw);
temper_raw >>= 4;
val1 = ((((temper_raw>>3) - ((int32_t)CalibData.dig_T1 <<1))) *
((int32_t)CalibData.dig_T2)) >> 11;
val2 = (((((temper_raw>>4) - ((int32_t)CalibData.dig_T1)) *
((temper_raw>>4) - ((int32_t)CalibData.dig_T1))) >> 12) *
((int32_t)CalibData.dig_T3)) >> 14;
temper_int = val1 + val2;
temper_int = ((temper_int * 5 + 128) >> 8);
temper_float = temper_int/100;
if (temper_float >100) // если значение температуры перевалило в отрицательные значения
{
temper_float = 409.6-temper_float;
temper_float = -temper_float;
}
return temper_float;
}
int32_t bmp280_compensate_T(int32_t adc_T)
{
int32_t var1;
int32_t var2;
int32_t temperature = 0;
var1 = ((((adc_T >> 3) - ((int32_t) dig_T1 << 1))) * ((int32_t) dig_T2)) >> 11;
var2 = (((((adc_T >> 4) - ((int32_t) dig_T1)) * ((adc_T >> 4) - ((int32_t) dig_T1))) >> 12) * ((int32_t) dig_T3)) >> 14;
t_fine = var1 + var2;
temperature = (t_fine * 5 + 128) >> 8;
return temperature;
}
Ср мар 06, 2019 12:38:55
temperature = 1.32 C
raw_temperature = 0x0006F840 := 456768
temperature = 1.27 C
raw_temperature = 0x0006F7A0 := 456608
temperature = 1.19 C
raw_temperature = 0x0006F6A0 := 456352
temperature = 1.02 C
raw_temperature = 0x0006F490 := 455824
temperature = 86 C
raw_temperature = 0x0006F280 := 455296
temperature = 85 C
raw_temperature = 0x0006F260 := 455264
temperature = 91 C
raw_temperature = 0x0006F320 := 455456
temperature = 88 C
raw_temperature = 0x0006F2D0 := 455376
temperature = 63 C
raw_temperature = 0x0006EFA0 := 454560
temperature = 58 C
raw_temperature = 0x0006EF20 := 454432
temperature = 65 C
raw_temperature = 0x0006EFE0 := 454624
temperature = 68 C
raw_temperature = 0x0006F040 := 454720
temperature = 3.64 C
raw_temperature = 0x00071500 := 464128
Ср мар 06, 2019 12:45:33
Ср мар 06, 2019 13:19:30
//signed long t_fine;
int32_t t_fine;
//int64_t t_fine;
int32_t _bmp280_temp;
uint32_t _bmp280_pres;
//структура калибров
static union _bmp280_cal_union {
uint8_t bytes[BMP280_CAL_DATA_SIZE];
struct {
uint16_t dig_t1;
int16_t dig_t2;
int16_t dig_t3;
uint16_t dig_p1;
int16_t dig_p2;
int16_t dig_p3;
int16_t dig_p4;
int16_t dig_p5;
int16_t dig_p6;
int16_t dig_p7;
int16_t dig_p8;
int16_t dig_p9;
};
} bmp280_cal;
//...
//измерение
void bmp280_measure(void){
uint8_t data[BMP280_RAWDATA_BYTES];
int32_t temp_raw, pres_raw;
// чтение raw ADC данных из регистров I2C
readmem(BMP280_PRES_REG, data, BMP280_RAWDATA_BYTES);
// форматирую загрузки в 20-битные числа
pres_raw = bmp280_20bit_reg(data[0], data[1], data[2]);
temp_raw = bmp280_20bit_reg(data[3], data[4], data[5]);
//Тест вариантов измерений. Остановился на 32-битном
//64 bits formula:: Flash - 4900 bytes, RAM - 444 Bytes
//_bmp280_temp = compensate_T_int32(temp_raw);
//_bmp280_pres = compensate_P_int64(pres_raw);
//floating point formula:: Flash - 4700 bytes, RAM - 438 Bytes
//_bmp280_temp = compensate_T_double(temp_raw);
//_bmp280_pres = compensate_P_double(pres_raw);
//32 bits formula:: Flash - 3768 bytes, RAM - 438 Bytes
_bmp280_temp = compensate_T_int32(temp_raw);
_bmp280_pres = compensate_P_int32(pres_raw);
}
//Собственно алхимия из даташита
// Returns temperature in DegC, resolution is 0.01 DegC. Output value of “5123” equals 51.23 DegC.
int32_t compensate_T_int32(int32_t adc_T){
int32_t var1, var2, T;
var1 = ((((adc_T >> 3) - ((int32_t)bmp280_cal.dig_t1 << 1))) * ((int32_t)bmp280_cal.dig_t2)) >> 11;
var2 = (((((adc_T >> 4) - ((int32_t)bmp280_cal.dig_t1)) * ((adc_T >> 4) - ((int32_t)bmp280_cal.dig_t1))) >> 12) *
((int32_t)bmp280_cal.dig_t3)) >> 14;
t_fine = var1 + var2;
T = (t_fine * 5 + 128) >> 8;
return T;
}
//Дебаг этого мохера
//
void debugSendTP(void){
uart_puts("temperature = ");
//bin2dec(_bmp280_temp);
num2dec(_bmp280_temp, 2);
uart_puts(" C\r");
uart_puts("pressure = ");
//bin2dec(_bmp280_pres);
num2dec(_bmp280_pres, 0);
uart_puts(" Pa, ");
//bin2dec(Pa2mmHg(_bmp280_pres));
num2dec(Pa2mmHg(_bmp280_pres), 2);
uart_puts(" mmHg\r");
debugRAWData();
}
Ср мар 06, 2019 14:17:32
Ср мар 06, 2019 14:44:27
Вот - да. Я на нее тоже грешу. Она самописная, а так как я не умею толком преобразовывать, вполне вероятна проблема в ней.DESIER писал(а):Что то мне кажется дело в ней.
void num2dec(long arg, int fractionDigits){
unsigned long dec = 1;
int i = 0, index = 0,max = 0;
char arr[16];
memset(arr, 0, 16);
while(dec < arg){
dec *= 10;
max ++;
}
if(max) dec /= 10;
if(fractionDigits && max > fractionDigits) max -= fractionDigits;
while(dec){
i = 0;
if(index == max && fractionDigits) arr[index ++ ] = 0x2E; // Symbol - "."
while(dec <= arg){
arg -= dec;
i++;
}
arr[index++] = i + 48;
dec /= 10;
}
uart_puts(arr);
}
Ср мар 06, 2019 14:57:57
Ср мар 06, 2019 15:27:06
Задумывалась для преобразования любого числа (до 32 бит) в читабельный вид, с фиксированной точкой и отправки его в UART. Если есть какие-то стандартные вещи в си, для этого, не сильно отжирающие ресурсы и память, подскажите пожалуйста.DESIER писал(а):Не могу понять для чего эта функция? Опишите в кратце что она делает.
Ср мар 06, 2019 15:51:07
uint16_t t = temperatureBMP280;
if (t < 0) { t = -t; uart('-'); }
if (t >= 1000) uart(((t/1000)%10)+48);
uart(((t/100)%10)+48);
uart('.');
uart(((t/10)%10)+48);
uart((t%10)+48);
uart('°');
uart('C');
void DesSend(int32_t n)
{
uint16_t temp = 0;
if (n < 0) { temp = -n; UDR = 45; }
else temp = n;
if (t >= 1000) UDR = ((temp/1000)%10)+48;
UDR = ((temp/100)%10)+48;
UDR = 46;
UDR = ((temp/10)%10)+48;
UDR = (temp%10)+48;
UDR = 176;
ADR = 67;
}
Ср мар 06, 2019 16:45:08
/*bcd
@arg - знаковое число
@fractionDigits - количество "дробных, десятичных разрядов", если = 0, точку не рисуем
*/
void num2dec(long arg, int fractionDigits){
unsigned long dec = 1;//десятичный делитель: 1,10, 100...
int i = 0, index = 0, max = 0;
char arr[16];//выходной массив с символами цифр и точки
memset(arr, 0, 16);
//выясним максимально возможный делитель для исходного числа - arg и заодно посчитаем разряды(количество цифр) - max
while(dec < arg){
dec *= 10;
max ++;
}
//если arg!=0, уменьшим dec в 10 раз(подготовим вычитаемое, для старшего десятичного разряда arg)
if(max) dec /= 10;
//если нужна точка(fractionDigits!=0) и количество цифр позволяет ее поставить, переделаем max в указатель места точки в массиве
if(fractionDigits && max > fractionDigits) max -= fractionDigits;
//начинаем посимвольный вывод числа в массив
while(dec){//пока делитель ненулевой
i = 0;//сброс счетчика цифры
//если индекс ячейки массива == месту точки, сунем в эту ячейку точку, а индекс пусть кажет на седующую ячейку
if(index == max && fractionDigits) arr[index ++ ] = 0x2E; // Symbol - "."
//По сути это i = arg / dec, но вроде поменьше места занимает
while(dec <= arg){
arg -= dec;
i++;
}
arr[index++] = i + 48; //кладем в массив код символа найденой цифры
dec /= 10; //следующая цифра
}
uart_puts(arr);//вывод результата
}
Ср мар 06, 2019 17:23:04