Еще кусок: DS75 термометр
Вчера я с ним промудохался :( - работал на макетке в тесовом проекте специально для чтения температуры, воткнул вчера в макетку с часами - а хрен вам
В общем, бубном тарахтел-тарахтел вокруг него, потом зачем-то прошил фьюзы, чтобы контроллер тактовался не от внешнего кварца (14 МГц с копейками, просто какой был в небольшом корпусе), а от внутреннего генератора 8 МГц - и все заработало.. Может кварц плохой или быстрый слишком, хз; поменяю да и все
В общем вот так он (термометр) подключается:
Уж проще некуда - питание, А0-А2 задают адрес, у меня тупо 0х00; линии SDA/SCL подтянуты к Vcc через 5 кОм резисторы. Кода немного:
unsigned char i2c_start(void) { TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN); //Send START condition while (!(TWCR & (1<<TWINT))); if ((TWSR & 0xF8) == TW_START) //Check value of TWI Status Register return(0); else return(1); } unsigned char i2c_sendAddress(unsigned char address) { unsigned char STATUS; if((address & 0x01) == 0) STATUS = TW_MT_SLA_ACK; else STATUS = TW_MR_SLA_ACK; TWDR = address; TWCR = (1<<TWINT)|(1<<TWEN); while (!(TWCR & (1<<TWINT))); if ((TWSR & 0xF8) == TW_STATUS) return(0); else return(1); } unsigned char i2c_sendData(unsigned char data) { TWDR = data; TWCR = (1<<TWINT) |(1<<TWEN); while (!(TWCR & (1<<TWINT))); if ((TWSR & 0xF8) != TW_MT_DATA_ACK) return(1); else return(0); } unsigned char i2c_receiveData_ACK(void) { unsigned char data; TWCR = (1<<TWEA)|(1<<TWINT)|(1<<TWEN); while (!(TWCR & (1<<TWINT))); if ((TWSR & 0xF8) != TW_MR_DATA_ACK) return(TW_BUS_ERROR); data = TWDR; return(data); } unsigned char i2c_receiveData_NACK(void) { unsigned char data; TWCR = (1<<TWINT)|(1<<TWEN); while (!(TWCR & (1<<TWINT))); if ((TWSR & 0xF8) != TW_MR_DATA_NACK) return(TW_BUS_ERROR); data = TWDR; return(data); } void i2c_stop(void) { TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO); //Transmit STOP condition }
В конце даташита на DS75 есть последовательности - "что надо сделать, чтобы.." В след. процедуре сначала задается адрес термометра (0х00), а потом читаются данные из него
#include "twi.h" ... u08 measureTemp () { i2c_start(); i2c_sendAddress(0x90); i2c_sendData(0); i2c_sendData(0); i2c_stop(); i2c_start(); i2c_sendAddress(0x91); u08 ms = i2c_receiveData_ACK(); i2c_receiveData_NACK(); i2c_stop(); return ms; }
Так не совсем правильно конечно, но в моем конкретном случае сойдет: я использую 9-битную точность (если так можно выражаться), если я правильно все понял, то это означает, что под знак отводится бит, под целые градусы - 7 бит и под десятые доли - 1 бит, т.е. точность в пол-градуса; в младшем байте эти пол-градуса и храняться, а в старшем - или просто положительное значение, или отрицательное, если старший бит установлен в "1"; поск. я не собираюсь (пока) измерять температуру зимой на улице, то значение старшего байта == температуре
Комментариев нет:
Отправить комментарий