2016-04-13 51 views
0

Bir sensör cihazı tarafından döndürülen bazı değerleri okumaya çalışıyorum. Her şey iyi durumda, ama sensörden verileri doğru şekilde almak için uğraşıyorum.Veri talebi sadece adres değeri (I2C) döndürüyor

datasheet'da, sıralama, durum, direnç, tvoc: sırayla bayt almam gerektiğini söylüyor.

Benim terminali aynı değeri 23.130 (0x5a5a)

Bu düzgün benim i2c_start() demiyorum o beni inandıramaz saçıyor tutar. In the protocol readmeI2C_start(SLAVE_READ_ADDRESS);' ile okunan adresi 0xB5 olarak bilinen başlangıç ​​noktası ile değiştirmeyi denedim, ancak bu hatamı döndürür.

/* Name: main.c 
* Author: <insert your name here> 
* Copyright: <insert your copyright message here> 
* License: <insert your license reference here> 
*/ 

#include <avr/io.h> 
#include <util/delay.h> 
#include <stdlib.h> 
#include <uart.h> 
#include <i2c_master.h> 

#define LED PB5 

#define I2C_READ 0x5A 

char buffer[10]; 

uint16_t val = 0; 
uint16_t pred = 0; 
uint8_t status = 0; 
uint8_t resistance = 0; 
uint8_t tvoc = 0; 


void getVal() 
{ 
    if(i2c_start(I2C_READ)) 
    { 
     //uart_puts("Start "); 

     val = ((uint8_t)i2c_read_ack())<<8; 
     val |= i2c_read_ack(); 

     pred = ((uint16_t)i2c_read_ack())<<8; 
     pred |= i2c_read_ack(); 

     // status = ((uint8_t)i2c_read_ack())<<8; 
     // status |= i2c_read_ack(); 

     // resistance = ((uint8_t)i2c_read_ack())<<8; 
     // resistance |= i2c_read_ack(); 

     // tvoc = ((uint8_t)i2c_read_ack())<<8; 
     // tvoc |= i2c_read_nack(); 

     i2c_stop(); 

    } else 
    { 
     uart_puts("Error"); 

     i2c_stop(); 
    } 
} 

int main(void) 
{ 
    init_uart(57600); 
    i2c_init(); 

    DDRB = _BV(5); 

    for(;;) 
    { 

     getVal(); 

     itoa(val, buffer, 10); //convert decimal to string base 10 
     uart_puts(buffer); 
     uart_puts(" "); 

      itoa(pred, buffer, 10); //convert decimal to string base 10 
     uart_puts(buffer); 
     uart_puts(" "); 

     itoa(status, buffer, 10); //convert decimal to string base 10 
     uart_puts(buffer); 
     uart_puts(" "); 

     itoa(resistance, buffer, 10); //convert decimal to string base 10 
     uart_puts(buffer); 
     uart_puts(" "); 

     itoa(tvoc, buffer, 10); //convert decimal to string base 10 
     uart_puts(buffer); 
     uart_puts(" "); 

     PORTB = 0xFF; 
     _delay_ms(500); 
     PORTB = 0x00; 
     _delay_ms(500); 
    } 
    return 0; /* never reached */ 
} 
+0

8 bit ve OR öğelerini değiştirdiğiniz değişkenlerin çoğu "uint8_t" türündendir. Yani bu işe yaramayacak. –

+0

Tamam, arabellek boyutunu artıracağım! Başka ne yanlış yapıyorum? – SensationSama

+0

Ooops Son yorumu yazdığımda yanlış okumuş. char buffer [4]; 'yalnızca 3 hanelik ondalık sayı için yeterince büyük olacaktır. –

cevap

1

Veri sayfası çok belirsizdir ve adresleme söz konusu olduğunda bir hata içermektedir. WRITING adresi 0xB4 ve READING adresi 0xB5'tir.

veri sayfası adresidir söyler: 0xB4 veya 0xB5 R/W bitine bağlı olarak karşılık gelen

BIT 7 6 5 4 3 2 1 0 
DATA 1 0 1 1 0 1 0 R/W 

ayarlamak veya beeing. Metinde yaptıkları hata, (0) 1011010'un 0x5A olmasıdır, ancak R/W biti en anlamlı bit değil, en az anlamlı bittir.

+0

Neyi kastettiğimi anlıyorum, ancak i2c_start (0xB4) çağrısı, – SensationSama

+0

hatasını atar. 0xB5'e ihtiyacınız var ... Çünkü aygıttan veri okuyorsunuz. – Unimportant

+0

Maalesef, 0xB5 bu hatayı atar. Aslında her ikisini de test ettim. – SensationSama

0

i2cmaster kütüphane getiri 1'de i2c_start işlevi Yapamam, sen Ayrıca

void getVal() 
{ 
    if(i2c_start(I2C_READ) == 0) // 0 indicates success 
    { 

sahip olmalıdır, bir hata değil, sizin getVal işlevinde Yani sıfır

uint8_t i2c_start(uint8_t address) 
{ 
    // ... snip ... 

    // check if the device has acknowledged the READ/WRITE mode 
    uint8_t twst = TW_STATUS & 0xF8; 
    if ((twst != TW_MT_SLA_ACK) && (twst != TW_MR_SLA_ACK)) return 1; 

    return 0; 
} 

belirtmek için Algılayıcınızdan neden iki 16 bitlik değerlerini val ve pred okuduğunuzu görün. Veri sayfası, pred'un döndürülen ilk değer olduğunu gösterir. Okunan verilerin geçerli olup olmadığını kontrol etmek için 8 bit status değerini de okumalısınız.