Ср май 16, 2012 15:05:33
Ср май 16, 2012 16:56:03
Ср май 16, 2012 17:17:39
Ср май 16, 2012 17:21:13
Ср май 16, 2012 18:07:56
Ср май 16, 2012 18:10:45
Ср май 16, 2012 18:13:29
Ср май 16, 2012 18:31:45
Nusik1975 писал(а):Леонид Иванович, программа не знает, какой датчик внешний, а какой-внутренний.
Nusik1975 писал(а):В МК только одна ножка может быть запрограммирована на прием и передачу данных по интерфейсу 1-Wire.
Nusik1975 писал(а):А защита там и не нужна вовсе. Какая должна быть ее функция? От замыкания? Ну тогда можно предохранитель поставить....Привожу пример из даташита на датчик. Никакой защиты там не нужно.
Ср май 16, 2012 18:34:45
Ср май 16, 2012 18:48:38
Nusik1975 писал(а):В данном проекте не вижу смысла использовать несколько ножек процессора.P.S. Я только начинаю делать первые шаги в программировании МК, поэтому рациональные предложения принимаю!
Ср май 16, 2012 18:50:48
Ср май 16, 2012 19:10:07
Ср май 16, 2012 19:10:49
Чт май 17, 2012 11:47:22
Nusik1975 писал(а):Я же написал, что у меня верхний дисплей дом, нижний-улица. Четкая привязка!
Nusik1975 писал(а):Производитель не указывает, что нужна защита.
//----------
//---------- Цифровые датчики: ----------
//----------
//Используются термометры DS18B20 (S20), которые подключены к портам OWPn.
//Считанное значение температуры заносится в массив Temp[],
//температура представлена в десятых долях градуса.
//Диапазон возможных температур составляет от TEMP_MIN до TEMP_MAX
//градусов. При отсутствии термометра показания равны TEMP_MIN.
//---------- Константы: ----------
#define FCLK 18.432 //тактовая частота, Мгц
#define OWP0 (1 << PC0) //порт цифрового термометра 0
#define OWP1 (1 << PC1) //порт цифрового термометра 1
#define OWP2 (1 << PC2) //порт цифрового термометра 2
#define OWP3 (1 << PC3) //порт цифрового термометра 3
#define OWP4 (1 << PC4) //порт цифрового термометра 4
#define OWP5 (1 << PC5) //порт цифрового термометра 5
//Маски термометров:
const __flash char Masks[CHANNELS] = {OWP0, OWP1, OWP2, OWP3, OWP4, OWP5};
//---------- Макросы: ----------
//Макроопределения для работы с портами:
#define Port_OWP_0(m) (DDRC |= m)
#define Port_OWP_Z(m) (DDRC &= ~m)
#define Pin_OWP(m) (PINC & m)
#define WORD(b1,b0) ((unsigned int)(b1 << 8) | b0)
#define Delay_us(x) __delay_cycles((int)(x * FCLK + 0.5))
//---------- Переменные: ----------
static int Temp[CHANNELS]; //текущая температура
static bool Present[CHANNELS]; //флаги присутствия термометров
//---------- Прототипы функций: ----------
void Start(char n); //старт термометра
void Read(char n); //чтение термометра
void TReset(char n); //генерация импульса сброса
char TByte(char n, char dat); //запись/чтение байта
bool TBit(char n, bool b); //запись/чтение бита
void Do_Crc(char b, char *crc); //вычисление CRC
//---------- Инициализация измерителя температуры: ----------
void Therm_Init(void)
{
for(char i = 0; i < CHANNELS; i++)
{
Temp[i] = TEMP_MIN; //инициализация температуры
Start(i); //старт всех термометров
}
}
//---------- Измерение температуры: ----------
void Therm_Exe(char n) //должна вызываться в основном цикле
//раз в 750 мс с интересующими значениями n
{
Read(n); //чтение термометра - самое первое измерение
Start(n); //старт термометра
}
//---------- Старт термометра: ----------
void Start(char n)
{
TReset(n); //импульс сброса
if(Present[n])
{
TByte(n, 0xCC); //skip ROM
TByte(n, 0x44); //convert T
}
}
//---------- Чтение термометра: ----------
void Read(char n)
{
if(Present[n])
{
TReset(n); //импульс сброса
if(Present[n])
{
TByte(n, 0xCC); //skip ROM
TByte(n, 0xBE); //read scratchpad
char Data[9]; //данные термометра
char Crc = 0; //инициализация CRC
for(char i = 0; i < 9; i++)
{
char b = TByte(n, 0xFF); //чтение данных
Do_Crc(b, &Crc); //обновление CRC
Data[i] = b; //сохранение данных
}
int t = TEMP_MIN;
if(!Crc)
{
#ifdef DS18B20
t = WORD(Data[1], Data[0]); //температура с дискретностью 0.0625°C
t = (t * 10) / 16; //температура с дискретностью 0.1°C
#else
t = WORD(Data[1], Data[0]) / 2;
t = (t * 20 - 5 + (int)(Data[7] - Data[6]) * 20 / Data[7]) / 2;
#endif
}
Temp[n] = t;
return;
}
}
Temp[n] = TEMP_MIN; //термометр отсутствует
return;
}
//---------- Генерация импульса сброса: ----------
void TReset(char n)
{
char m = Masks[n];
char si;
Present[n] = 0; //сброс флага присутствия термометра
Port_OWP_0(m); //OWP <- 0
Delay_us(500); //delay 500 uS
si = __save_interrupt();
__disable_interrupt(); //запрещение прерываний
Port_OWP_Z(m); //OWP <- 1
Delay_us(14); //delay 14 uS
if(Pin_OWP(m)) //если OWP = 0, то ошибка
{
Delay_us(52); //delay 52 uS
if(!Pin_OWP(m)) //если OWP = 1, то ошибка
{
__restore_interrupt(si); //восстанавление прерываний
Delay_us(250); //delay 250 uS
if(Pin_OWP(m)) //если OWP = 0, то ошибка
{
Present[n] = 1; //если ошибок нет, термометр присутствует
}
}
}
__restore_interrupt(si); //восстанавление прерываний в случае ошибки
}
//---------- Запись/чтение байта по однопроводной шине: ----------
char TByte(char n, char dat)
{
char res;
char m = Masks[n];
for(char i = 0; i < 8; i++)
{
res = res >> 1;
if(TBit(m, dat & 1)) res |= 0x80;
else res &= ~0x80;
dat = dat >> 1;
}
return(res);
}
//---------- Запись/чтение бита по однопроводной шине: ----------
bool TBit(char m, bool b)
{
char si;
si = __save_interrupt();
__disable_interrupt(); //запрещение прерываний
Port_OWP_0(m); //OWP <- 0
Delay_us(2); //delay 2 uS
if(b) Port_OWP_Z(m); //bit = 1, OWP <- 1
Delay_us(13); //delay 13 uS
bool owp = Pin_OWP(m); //чтение порта
Delay_us(45); //delay 45 uS
Port_OWP_Z(m); //OWP <- 1
__restore_interrupt(si); //восстанавление прерываний
Delay_us(2); //delay 2 uS
return(owp);
}
//---------- Вычисление контрольной суммы: ----------
void Do_Crc(char b, char *crc)
{
for(char i = 0; i < 8; b = b >> 1, i++)
if((b ^ *crc) & 1) *crc = ((*crc ^ 0x18) >> 1) | 0x80;
else *crc = (*crc >> 1) & ~0x80;
}
//---------- Чтение температуры: ----------
int Therm_GetT(char ch)
{
if(ch < CHANNELS)
return(Temp[ch]);
else return(0);
}
Чт май 17, 2012 17:01:30
Сб май 19, 2012 23:22:27
Вс май 20, 2012 00:04:21
Вс май 20, 2012 06:19:55
Вс май 20, 2012 07:40:19
Вс май 20, 2012 14:39:42