Пытаюсь поработать с датчиком DS1820. Использую готовый рабочий пример. Не работает - вначале думал, датчик не исправен. А потом понял что
проблема с 1wire.
Вот файл onewire.h
Код
#ifdef IAR
/* запись */
#ifndef DQW
#define DQW PORTD_Bit5
#endif
/* чтение */
#ifndef DQR
#define DQR PIND_Bit5
#endif
/* установка направления чтение/запись */
#ifndef DQD
#define DQD DDRD_Bit5
#endif
#include <inavr.h>
#endif
#ifdef CV
/* запись */
#ifndef DQW
#define DQW PORTD.5
#endif
/* чтение */
#ifndef DQR
#define DQR PIND.5
#endif
/* установка направления чтение/запись */
#ifndef DQD
#define DQD DDRD.5
#endif
#include <delay.h>
#endif
/********************************************************************************
**************
Переменные для функции задержки
a = 10us
c = 70us
d = 120us
e = 410us
f = 480us
********************************************************************************
**************/
/*
================================================================================
=======================================
Функция задержки для кварца 4.000 МГц.
CodeVision -> задержка равна ( 11,75 + 2,75*Х ) мкс
IAR -> задержка равна ( 10 + 1,5*Х ) мкс
================================================================================
=======================================
*/
//void delay(unsigned int useconds)
//{
/*~~*/
//int s;
/*~~*/
//for(s = 0; s < useconds; s++)
//{
//};
//}
/*
================================================================================
=======================================
Функция OW_RESET -> сбрасывает шину 1-Wire и определяет наличие подключенных устройств.
Сигнал сброса должен быть длинной минимум 480 мкс.
================================================================================
=======================================
*/
unsigned char ow_reset(void)
{
/*~~~~~~~~~~~~~~~~~~~~~*/
unsigned char presence;
/*~~~~~~~~~~~~~~~~~~~~~*/
DQW = 0;
DQD = 1; /* устанавливаем низкий уровень на линии данных (DQ) */
/* задержка 480us */
#ifdef IAR
__delay_cycles(1920);
#endif
#ifdef CV
delay_us(480);
#endif
DQD = 0; /* возвращаем на линию данных высокий уровень */
/* ждем ответа 70us */
#ifdef IAR
__delay_cycles(280);
#endif
#ifdef CV
delay_us(70);
#endif
presence = DQR; /* определяем наличие устройств на линии */
/* ждем окончания временного промежутка (410us) */
#ifdef IAR
__delay_cycles(1640);
#endif
#ifdef CV
delay_us(410);
#endif
return(presence); /* возвращаем наличие устройств на шине */
} /* 0 = на шине есть устройства, 1 = нет устройств */
/*
================================================================================
=======================================
WRITE_BIT -> запись бита в шину.
================================================================================
=======================================
*/
void write_bit(char bitval)
{
_DISABLE_INTERRUPT;
DQW = 0;
DQD = 1; /* устанавливаем низкий уровень линии данных (DQ) */
/* пауза 10us */
#ifdef IAR
__delay_cycles(40);
#endif
#ifdef CV
delay_us(10);
#endif
if(bitval == 1) DQD = 0;/* устанвливаем высокий уровень линии данных (DQ),если записывается 1 */
/* ждем окончания временного интервала (70us) */
#ifdef IAR
__delay_cycles(280);
#endif
#ifdef CV
delay_us(70);
#endif
DQD = 0; /* устанвливаем высокий уровень линии данных (DQ) */
_ENABLE_INTERRUPT;
}
/*
================================================================================
=======================================
WRITE_BYTE -> запись байта в шину.
================================================================================
=======================================
*/
void write_byte(char val)
{
/*~~~~~~~~~~~~~~~~~*/
unsigned char i;
unsigned char temp;
/*~~~~~~~~~~~~~~~~~*/
for(i = 0; i < 8; i++) /* запись по одному биту */
{
temp = val >> i; /* сдвигаем байт вправо на величину 'i' */
temp &= 0x01; /* копируем младший бит в temp */
write_bit(temp); /* записываем бит в шину */
}
/* ожидаем окончания временного интервала */
#ifdef IAR
__delay_cycles(480);
#endif
#ifdef CV
delay_us(120);
#endif
}
/*
================================================================================
=======================================
READ_BIT -> чтение бита из шины.
================================================================================
=======================================
*/
unsigned char read_bit(void)
{
_DISABLE_INTERRUPT;
DQW = 0;
DQD = 1; /* устанавливаем низкий уровень линии данных (DQ) */
_NOP;
DQD = 0; /* устанвливаем высокий уровень линии данных (DQ) */
/* задержка 10us */
#ifdef IAR
__delay_cycles(40);
#endif
#ifdef CV
delay_us(10);
#endif
_ENABLE_INTERRUPT;
return(DQR);/* возвращаем значение линии данных (DQ) */
}
/*
================================================================================
=======================================
READ_BYTE -> чтение байта из шины.
================================================================================
=======================================
*/
unsigned char read_byte(void)
{
/*~~~~~~~~~~~~~~~~~~~~~~*/
unsigned char i;
unsigned char value = 0;
/*~~~~~~~~~~~~~~~~~~~~~~*/
for(i = 0; i < 8; i++)
{
if(read_bit()) value |= 0x01 << i;/* читаем один бит и записываем его в разряд i */
/* ожидаем окончания временного интервала */
#ifdef IAR
__delay_cycles(480);
#endif
#ifdef CV
delay_us(120);
#endif
}
return(value);
}
/*
================================================================================
=======================================
calc_crc -> подсчет контрольной суммы.
================================================================================
=======================================
*/
char calc_crc(unsigned char* buff, char num_vals)
{
/*~~~~~~~~~~~~~~~~~~~~~~*/
char shift_reg = 0,
data_bit,
sr_lsb,
fb_bit,
i,
j;
/*~~~~~~~~~~~~~~~~~~~~~*/
for(i = 0; i < num_vals; i++)
{
for(j = 0; j < 8; j++)
{
data_bit = (*buff >> j) & 0x01;
sr_lsb = shift_reg & 0x01;
fb_bit = (data_bit ^ sr_lsb) & 0x01;
shift_reg = shift_reg >> 1;
if(fb_bit)
{
shift_reg = shift_reg ^ 0x8c;
}
}
buff++;
}
return(shift_reg);
}
Вот моя программа (часть функций и переменных опущена):
Код
#define CV
#include <delay.h>
#include <stdio.h>
#include "macros.h"
#include "mega8.h"
#include <stdlib.h>
#include <string.h>
#include "NokiaLCD.h"
#include <ctype.h>
#include <onewire.h>
///
void main ()
{
char *s=r;
unsigned char i,j,devices;
int temp;
devices=ow_reset(); // инициализация 1wire, поиск устройств, должна возвращать 0 в случае обнаружения.
LcdInit();
Delay();
LcdGotoXY(2,2);
sprintf(s,"%u ",devices);
LcdStr(FONT_1X,s,NORMAL);
LcdUpdate();
}
На экран вылазит 0 (соответствует обнаружению устройства) даже если к порту ничего не подключено.
Контроллер исправен, порт D исправен, тесты мигалками моргалками проходит
Где ошибка?
Сообщение отредактировал zheka - Mar 26 2006, 10:18