Еще кусок: 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"; поск. я не собираюсь (пока) измерять температуру зимой на улице, то значение старшего байта == температуре
Комментариев нет:
Отправить комментарий