Форум программистов
 
Контакты: о проблемах с регистрацией, почтой и по другим вопросам пишите сюда - alarforum@yandex.ru, проверяйте папку спам! Обязательно пройдите активизацию e-mail.

Вернуться   Форум программистов > Инженерный раздел > Микроконтроллеры, робототехника, схемотехника, 3D принтеры
Регистрация

Восстановить пароль
Повторная активизация e-mail


Донат для форума - использовать для поднятия настроения себе и модераторам

А ещё здесь можно купить рекламу за 15 тыс руб в месяц! ) пишите сюда - alarforum@yandex.ru

Ответ
 
Опции темы
Старый 19.04.2019, 03:03   #1
NikEvgMaster
Новичок
 
Регистрация: 19.04.2019
Сообщений: 2
Репутация: 10
По умолчанию Греются ds18b20, нет ответа. Atmega328p

Не пойму почему не работает программный 1-Wire на 328 меге. Может я там где-то что-то с портами напутал? Диод мигает с частотой в 0.5 Гц, как положено. Дисплей по i2c пашет, часы тоже. Подлючал gnd, 5v, а между ними пин на пин В1 с подтяжкой к нему 5v через резистор 4, потом еще 10 кОм пробовал.

Дописал проверку присутствия устройств на шине, если ответа нет, то мигает диод - мигает бл.... Ответа нет. Что делать?

Текст библиотечного/хэдерного файла 1-WIRE:
Код:

#define DEVICES_ERROR  1

#define CMD_CONVERTTEMP    0x44
#define CMD_RSCRATCHPAD    0xbe
#define CMD_WSCRATCHPAD    0x4e
#define CMD_CPYSCRATCHPAD  0x48
#define CMD_RECEEPROM      0xb8
#define CMD_RPWRSUPPLY     0xb4
#define CMD_SEARCHROM      0xf0
#define CMD_READROM        0x33
#define CMD_MATCHROM       0x55
#define CMD_SKIPROM        0xcc
#define CMD_ALARMSEARCH    0xec
#define uint64_t long long
#define uint8_t char
#define uint16_t int
#define uint32_t long
uint8_t ONE_WIRE_DQ = 1;

void oneWireInit(uint8_t pin) {
  ONE_WIRE_DQ = pin;
  ONE_WIRE_DDR |= (1 << ONE_WIRE_DQ); // выход
  ONE_WIRE_PORT |= (1 << ONE_WIRE_DQ);
  _delay_ms(400);
  ONE_WIRE_DDR &= ~(1 << ONE_WIRE_DQ); // вход
}

/*
 * сброс
 */
uint8_t reset() {
  uint8_t response=0;

  // импульс сброса, минимум 480us
  ONE_WIRE_DDR |= (1 << ONE_WIRE_DQ); // выход
  ONE_WIRE_PORT &= ~(1 << ONE_WIRE_DQ);//0
  _delay_us(480);

  // Когда ONE WIRE устройство обнаруживает положительный перепад, он ждет от 15us до 60us
  ONE_WIRE_DDR &= ~(1 << ONE_WIRE_DQ); // вход
  _delay_us(65);

  // и затем передает импульс присутствия, перемещая шину в логический «0» на длительность от 60us до 240us.
  response = (ONE_WIRE_PIN & (1 << ONE_WIRE_DQ));
  _delay_us(250);
  if (response){                               //ПРОВЕРКА ОТЗЫВА УСТРОЙСТВ
	  PORTC |= (1<<3);
		_delay_ms(200);
		PORTC &= ~(1<<3);
		_delay_ms(200);
		PORTC |= (1<<3);
		_delay_ms(200);
		PORTC &= ~(1<<3);
		_delay_ms(200);
		PORTC |= (1<<3);
		_delay_ms(200);
		PORTC &= ~(1<<3);
		_delay_ms(200);
		PORTC |= (1<<3);
		_delay_ms(200);
		PORTC &= ~(1<<3);
		_delay_ms(200);
		PORTC |= (1<<3);
		_delay_ms(200);
		PORTC &= ~(1<<3);
		_delay_ms(200);
		PORTC |= (1<<3);
		_delay_ms(200);
		PORTC &= ~(1<<3);
		_delay_ms(200);
		PORTC |= (1<<3);
		_delay_ms(200);
		PORTC &= ~(1<<3);
		_delay_ms(200);
		PORTC |= (1<<3);
		_delay_ms(200);
		PORTC &= ~(1<<3);
  }
  // если 0, значит есть ответ от датчика, если 1 - нет
  return response;
}

/*
 * отправить один бит
 */
void writeBit(uint8_t bit) {
  if (bit & 1) {
    //cli();
    // логический «0» на 1us
    ONE_WIRE_DDR |= (1 << ONE_WIRE_DQ); // выход
    ONE_WIRE_PORT &= ~(1 << ONE_WIRE_DQ);//0
    _delay_us(8);
    //sei();
    ONE_WIRE_DDR &= ~(1 << ONE_WIRE_DQ); // вход
    _delay_us(62);
  } else {
    //cli();
    // логический «0» на 1us
    ONE_WIRE_DDR |= (1 << ONE_WIRE_DQ); // выход
    ONE_WIRE_PORT &= ~(1 << ONE_WIRE_DQ);
    _delay_us(62);
    ONE_WIRE_DDR &= ~(1 << ONE_WIRE_DQ); // вход
    //sei();
    _delay_us(8);
  }
}

/*
 * отправить один байт
 */
void writeByte(uint8_t byte) {
  uint8_t i = 8;
  while (i>0) {
    writeBit(byte & 1);
    byte >>= 1;
	i--;
  }
}



/*
 * получить один бит
 */
char readBit (void) {
  uint8_t bit = 0;
  //cli();
  // логический «0» на 1us
  ONE_WIRE_DDR |= (1 << ONE_WIRE_DQ); // выход
  ONE_WIRE_PORT &= ~(1 << ONE_WIRE_DQ);//0
  _delay_us(6);
 
  // освободить линию и ждать 14us
  ONE_WIRE_DDR &= ~(1 << ONE_WIRE_DQ); // вход
  _delay_us(10);

  // прочитать значение
  if (ONE_WIRE_PIN & (1 << ONE_WIRE_DQ)) {
    bit = 1;
  }

  // ждать 45us и вернуть значение
  //sei();
  _delay_us(55);
  return bit;
}


/*
 * получить один байт
 */
uint8_t readByte() {
  uint8_t i = 8, byte = 0;
  while (i>0) {
    byte >>= 1;
    byte |= (readBit() << 7);
	i--;
  }
  return byte;
}

/*
 * читать ROM подчиненного устройства (код 64 бита)
 */
uint64_t readRoom(void) {
  uint64_t oneWireDevice;
  if(reset() == 0) {
    writeByte(CMD_READROM);
    //  код семейства
    oneWireDevice = readByte();
    // серийный номер
    oneWireDevice |= (uint16_t)readByte()<<8 | (uint32_t)readByte()<<16 | (uint32_t)readByte()<<24 | (uint64_t)readByte()<<32 | (uint64_t)readByte()<<40 | (uint64_t)readByte()<<48;
    // CRC
    oneWireDevice |= (uint64_t)readByte()<<56;
  } else {
    return 1;
  }
  return oneWireDevice;
}

/*
 * Команда соответствия ROM, сопровождаемая последовательностью 
 * кода ROM на 64 бита позволяет устройству управления шиной 
 * обращаться к определенному подчиненному устройству на шине.
 */
void setDevice(uint64_t rom) {
  uint8_t i = 64;
  reset();
  writeByte(CMD_MATCHROM);
  while (i--) {
    writeBit(rom & 1);
    rom >>= 1;
  }
}

/*
 * провеска CRC, возвращает "0", если нет ошибок
 * и не "0", если есть ошибки
 */
uint8_t crcCheck(uint64_t data8x8bit, uint8_t len) {
  uint8_t dat, crc = 0, fb, stByte = 0;
  do {
    dat = (uint8_t) (data8x8bit >> (stByte * 8));
    for (int i = 0; i < 8; i++) {  // счетчик битов в байте
      fb = crc ^ dat;
      fb &= 1;
      crc >>= 1;
      dat >>= 1;
      if (fb == 1) {
        crc ^= 0x8c; // полином
      }
    }
    stByte++;
  } while (stByte < len); // счетчик байтов в массиве
  return crc;
}


/*
 * поиск следующего подключенного устройства
 */
uint64_t searchNextAddress(uint64_t lastAddress, uint8_t * lastDiscrepancy) {
  uint8_t searchDirection = 0;
  uint64_t newAddress = 0;
  uint8_t idBitNumber = 1;
  uint8_t lastZero = 0;
  reset();
  writeByte(CMD_SEARCHROM);

  while (idBitNumber < 65) {
    uint8_t idBit = readBit();
    uint8_t cmpIdBit = readBit();

    // id_bit = cmp_id_bit = 1
    if (idBit == 1 && cmpIdBit == 1) {
      return DEVICES_ERROR;
    } else if (idBit == 0 && cmpIdBit == 0) {
      // id_bit = cmp_id_bit = 0
      if (idBitNumber == *lastDiscrepancy) {
        searchDirection = 1;
      } else if (idBitNumber > *lastDiscrepancy) {
        searchDirection = 0;
      } else {
        if ((uint8_t) (lastAddress >> (idBitNumber - 1)) & 1) {
          searchDirection = 1;
        } else {
          searchDirection = 0;
        }
      }
      if (searchDirection == 0) {
        lastZero = idBitNumber;
      }
    } else {
      // id_bit != cmp_id_bit
      searchDirection = idBit;
    }
    newAddress |= ((uint64_t) searchDirection) << (idBitNumber - 1);
    writeBit(searchDirection);
    idBitNumber++;
  }
  *lastDiscrepancy = lastZero;
  return newAddress;
}

/*
 * поиск устройств
 */
void searchRom(uint64_t * roms, uint8_t * n) {
  uint64_t lastAddress = 0;
  uint8_t lastDiscrepancy = 0;
  uint8_t err = 0;
  uint8_t i = 0;
  do {
    do {
      lastAddress = searchNextAddress(lastAddress, &lastDiscrepancy);
      if(lastAddress != DEVICES_ERROR) {
        uint8_t crc = crcCheck(lastAddress, 8);
        if (crc == 0) {
          roms[i++] = lastAddress;
          err = 0;
        } else {
          err++;
        }
      } else {
        err++;
      }
      if (err > 3) {
        return;
      }
    } while (err != 0);
  } while (lastDiscrepancy != 0 && i < *n);
  *n = i;
}



/*
 * пропустить ROM
 */
void skipRom() {
  reset();
  writeByte(CMD_SKIPROM);
}

NikEvgMaster вне форума   Ответить с цитированием
Старый 19.04.2019, 03:04   #2
NikEvgMaster
Новичок
 
Регистрация: 19.04.2019
Сообщений: 2
Репутация: 10
По умолчанию

Майн:
Код:

#define F_CPU				16000000UL
#define ONE_WIRE_PORT      PORTB
#define ONE_WIRE_DDR       DDRB
#define ONE_WIRE_PIN       PINB
//#include <asf.h>
#include <avr/io.h>
#include <util/delay.h>
#include <stdlib.h>
#include <math.h>
//#include <avr/interrupt.h>

//#include "сonfig.h"
#include "OwnWire.h"

#include "OLED_Function.h" //включает функции для работы дисплея
#include "drawing.h"	   //включает функции по прорисовке на дисплее определенных элементов, а также массивы шрифтов
#include "function_clock.h"



char Rel1 = 5;//переменные для хранения вкл/выкл реле
char Rel2 = 7;
char Rel3 = 9;
char Rel4 = 11;
char Rel5 = 13;
char D_time = 4;//переменная для хранения значения день- ночь

char hoursH = 0;//переменные для сохранения байтов с часов и вывода на экран
char hoursL = 0;
char minutesH = 0;
char minutesL = 0;
char colon = 10;//:
char secondsL = 0;
char secondsH = 0;

char int_t1 = 28;//переменные для хранения уставок температур и времени в формате +/- ХХ
char int_t2 = 99;
char int_t3 = 0;
char ext_t = 0;

char seconds = 0; //непереработанные данные с часов
char minutes = 0;
char hours = 0;
char days = 0;
char monthes = 0;
char years = 0;
char weekday = 0;

char hour_transf=0;//переработанные часы

char int_t1H = 0;//старшие и младшие разряды температур
char int_t1L = 0;
char sign1 =0;
char int_t2H = 0;
char int_t2L = 0;
char int_t3H = 0;
char int_t3L = 0;
char ext_tH = 0;
char ext_tL = 0;

char temperatura1=0;//с часов
char temperatura2=99;
char temperatura3=33;
char temperatura4=00;//уличная t

//char h=23; //уставки для записи времени в ds3231
//char m=00;
//char s=0;

//=========================================================
char getTemp(uint64_t ds18b20s) { // must contain 64 bit
	char temperatureL=0;
	char temperatureH=0;
	char retd = 0;


	setDevice(ds18b20s);
	writeByte(CMD_CONVERTTEMP);

	_delay_ms(750);

	setDevice(ds18b20s);
	writeByte(CMD_RSCRATCHPAD);

	temperatureL = readByte();
	temperatureH = readByte();

	retd = ((temperatureL>>4)&0b00001111)|((temperatureH<<4)&0b01110000);		//прокатит, если положительная температура

return retd;}
//==========================================================

int main(void){
	//board_init();
	DDRC |= (1<<0)|(1<<1)|(1<<2)|(1<<3);
	PORTC &= ~((1<<0)|(1<<1)|(1<<2)|(1<<3));
	
	
	static_elements();
	//ds3231_init();				//инициализация часов ds3231
	//ds3231_write_time(h,m,s);		//запись времени в часы
	
	//====================
	oneWireInit(1);
	reset();
	char n = 3;
	long long roms[n];					//нужно вместить 64 бита
	searchRom(roms, &n);
	_delay_ms(2000);
	//====================
	
	while (1)
	{
		//=======================================
		temperatura2 = getTemp(roms[0]);
		temperatura3 = getTemp(roms[1]);
		temperatura4 = getTemp(roms[2]);
		_delay_ms(1000);
		
		//======================================
		
		ds3231_read_temper(&int_t1H,&int_t1L, &sign1, &temperatura1);//передал адреса переменных, куда часы сохранят температуру и знак
		ds3231_read_time(&seconds,&minutes,&hours,&days,&monthes,&years,&weekday);
		
		minutesL = minutes&0b00001111;
		minutesH = ((minutes&0b01110000)>>4);
		hour_transf = (((hours & 0xF0) >> 4)*10)+(hours & 0x0F);
		hoursL = hours&0b00001111;
		hoursH = ((hours&0b01110000)>>4);
		secondsL = seconds&0b00001111;
		secondsH = ((seconds&0b01110000)>>4);
		
		drawing_clock(hoursH,hoursL,minutesH,minutesL,colon);
		
		temper_transform(temperatura2,&int_t2H,&int_t2L);//по указателю
		temper_transform(temperatura3,&int_t3H,&int_t3L);
		temper_transform(temperatura4,&ext_tH,&ext_tL);
		
		if(temperatura1<int_t1) {		//реле1 в зависим от t1
			Rel1=6;
			PORTC |= (1<<2);
		}
		else {
			Rel1=5;
			PORTC &= ~(1<<2);
		}
		
		drawing_temperatures(ext_tH,int_t1H,ext_tL,int_t1L,int_t2H,int_t3H,int_t2L,int_t3L);
		
		if((hour_transf>0 && hour_transf<7) || (hour_transf==23)){//в ночное время вкл бойлер на 0 пине порта C
			D_time=15;
			PORTC |= (1<<0);
			Rel5 = 14;
		}
		else {							//днем горит солнышко и бойлер выкл
			D_time=4;
			PORTC &= ~(1<<0);
			Rel5 = 13;
		}
		
		drawing_relay (Rel1,Rel2,Rel3,Rel4,Rel5,D_time);//вывод реле и времени дня
		PORTC |= (1<<3);
		_delay_ms(1000);
		PORTC &= ~(1<<3);
		_delay_ms(1000);
		PORTC |= (1<<3);
		_delay_ms(1000);
		PORTC &= ~(1<<3);
		_delay_ms(1000);
		PORTC |= (1<<3);
		_delay_ms(1000);
		PORTC &= ~(1<<3);
		_delay_ms(1000);
		PORTC |= (1<<3);
		_delay_ms(1000);
		PORTC &= ~(1<<3);
		_delay_ms(1000);
		PORTC |= (1<<3);
		_delay_ms(1000);
		PORTC &= ~(1<<3);
		_delay_ms(1000);
		PORTC |= (1<<3);
		_delay_ms(1000);
		PORTC &= ~(1<<3);
		_delay_ms(1000);
		PORTC |= (1<<3);
		_delay_ms(1000);
		PORTC &= ~(1<<3);
		_delay_ms(1000);
		PORTC |= (1<<3);
		_delay_ms(1000);
		PORTC &= ~(1<<3);
	}
}

NikEvgMaster вне форума   Ответить с цитированием
Старый 19.04.2019, 15:54   #3
digitalis
Профессионал
 
Аватар для digitalis
 
Регистрация: 04.02.2011
Адрес: Минск
Сообщений: 1,516
Репутация: 513
По умолчанию

Если долго не ответят (тут Atmel-щиков мало), можно попробовать
https://radiokot.ru/forum/viewtopic.php?f=57&t=21695
Просто почитать тему; если прояснения не произойдет - зарегиться и спросить. Народ в основном доброжелательный, скорее всего помогут.
Сам я Atmel-щик, но DS-кой этой не занимался и для Мег пишу на асме, не люблю я Си для МК.
digitalis вне форума   Ответить с цитированием
Ответ

Опции темы

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Неправильно работает функция rand() на микроконтроллере ATMEGA328P Marcus75 Микроконтроллеры, робототехника, схемотехника, 3D принтеры 3 01.03.2019 14:33
Cчитывание измеренной температуры с датчика DS18B20 в Excel, используя библиотеку RSAPI.DL aizhan0212 Микроконтроллеры, робототехника, схемотехника, 3D принтеры 57 17.09.2017 23:25
Помощь с программой тестом на Delphi. Не знаю как сделать чтобы был выбор ответа и определение верного/не верного ответа и итог? KiberVioNet Lazarus, Free Pascal, CodeTyphon 7 30.09.2015 10:02
жду ответа вовик 82 Помощь студентам 1 27.05.2011 11:15


19:39.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2019, Jelsoft Enterprises Ltd.

Проекты отопления, пеллетные котлы, бойлеры, радиаторы
интернет магазин respective.ru