Прочитать байт с порта

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

Да я и не говорю взять готовое, просто там есть ответы на все ваши вопросы. Посмотрите реализацию там, сравните с Вашей, разберитесь в чем проблема и почему именно так а не иначе и напишите сами для закрепления знаний.

iopq
Offline
Зарегистрирован: 05.07.2016
ясно же написано. Меряйте размеры ям. По свалу фиксируйте по подъему определяйте что у вас  0,1 или Break. точнее если появился Break, то у вас Адрес.

это совершенно точно. я могу легко определять 0 или 1 данным способом. на данный момент проблема только в том что функция начинает чтение с высокого уровня

iopq
Offline
Зарегистрирован: 05.07.2016
for (uint8_t ii = 0; ii < 8; ii++) {
    // Wait for the slave to toggle a low, or fail
    maxTries = HDQ_DELAY_FAIL_TRIES;
	while (_HDQ_readPin() != 0 && maxTries-- > 0)
		if (maxTries == 1) return 0xFF;

    // Wait until Tdsub and half or one bit has passed
	delayMicroseconds(((HDQ_DELAY_TDW0 - HDQ_DELAY_TDW1) / 2) + HDQ_DELAY_TDW1);
    // Read the bit
    result |= _HDQ_readPin()<<ii;

    // Wait until Tssub has passed
	delayMicroseconds(HDQ_DELAY_TCYCD - HDQ_DELAY_TDW0);
}

ну тут задержки стоят зачем то. явно у меня лучше получается

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

Ну вот когда получится, измерьте общее время чтения вашего алгоритма и того и увидмте что ваши вайлы это теже самые делаи.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016
for (uint8_t ii = 0; ii < 8; ii++) {
    // Wait for the slave to toggle a low, or fail  
    maxTries = HDQ_DELAY_FAIL_TRIES;                //<-  выставляем время таймаута
  while (_HDQ_readPin() != 0 && maxTries-- > 0)  //<-- ждем появление единицы или истечение таймаута
    if (maxTries == 1) return 0xFF;     //<-- выход по таймауту

    // Wait until Tdsub and half or one bit has passed
  delayMicroseconds(((HDQ_DELAY_TDW0 - HDQ_DELAY_TDW1) / 2) + HDQ_DELAY_TDW1);
    // Read the bit
    result |= _HDQ_readPin()<<ii; //<- заносим нужный бит ркхультата
    //  выдите накапливается результат в отдельном байте

    // Wait until Tssub has passed
  delayMicroseconds(HDQ_DELAY_TCYCD - HDQ_DELAY_TDW0);
}

Задержки это константы, ведь пользователь захочит поменять скорость обмена как на передачу, так и прием. Вот и приходят к такой конструкции. Да и такая конструкция более предсказуемая. Не везде в системе есть микрос и прерывание.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

iopq пишет:

спасибо конечно но я что зря третью ночь сижу что бы вот так взять библиотеку? у меня не стоит задача "что бы работало". хочу понимать как оно работает и как подобное создавать не имея даташитов. 

Писать библиотеки, не имея дэйташитов, - идея фикс.

iopq
Offline
Зарегистрирован: 05.07.2016

значит я был не прав и нужно чтение подгонять под тайминги? и всеже для общего развития на вопрос на предыдущей странице хотелось бы ответа. почему читается HIGH ?

iopq
Offline
Зарегистрирован: 05.07.2016
uint8_t readByte() {
 pinMode(2, INPUT);                                 //DDRD &= ~_BV(2);     // Настроили пин на вход
 int bittimeL[8]={};
 int HDQ_DELAY_TDW0 = 145;                        //80 - 145 μs      sends 0
 int HDQ_DELAY_TDW1 = 50;                         //32 - 50 μs       sends 1
 int HDQ_DELAY_TCYCD= 205;                        //190 205 250 μs   Cycle time
for (int i = 0; i < 8; i++) { 
 uint32_t tmout_guard = 400;                     // сторож таймаута
while((PIND & _BV(2)) != LOW)                    //ждем пока появится логический 1
{
if(!--tmout_guard)
 return false;                                   // таймаут поймали
} 
  delayMicroseconds(((HDQ_DELAY_TDW0 - HDQ_DELAY_TDW1) / 2) + HDQ_DELAY_TDW1); //delayMicroseconds(170);
  bittimeL[i]= ((PIND & _BV(2))!= LOW);          // Прочитали состояние порта и записали в переменную
  delayMicroseconds(HDQ_DELAY_TCYCD - HDQ_DELAY_TDW0); //delayMicroseconds(60);
}
 Serial.println("************Start**********");
 Serial.println(bittimeL[0]);
 Serial.println(bittimeL[1]); 
 Serial.println(bittimeL[2]);
 Serial.println(bittimeL[3]);
 Serial.println(bittimeL[4]);
 Serial.println(bittimeL[5]);
 Serial.println(bittimeL[6]);
 Serial.println(bittimeL[7]);
 Serial.println("************END***********");
}

читает то что надо но понимание не достигнуто. 

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Если хотите разобраться то напишите сигнал не горизонтально как привыкли а вертикально. В скетче распустите цикл записав тело цикла 8 раз и совместите на одном листке. Уровень сигнала и соответсвующая строка ее обрабатывающая. Вот тогда и будет у вас понимание что и как и как это прооптимизировать.

uint8_t readByte() {
  //
 const byte bit_ =2
 pinMode(2, INPUT);                                 //DDRD &= ~_BV(2);     // Настроили пин на вход
 int bittimeL[8]={};
 int HDQ_DELAY_TDW0 = 145;                        //80 - 145 μs      sends 0
 int HDQ_DELAY_TDW1 = 50;                         //32 - 50 μs       sends 1
 int HDQ_DELAY_TCYCD= 205;                        //190 205 250 μs   Cycle time
for (int i = 0; i < 8; i++) { 
 uint32_t tmout_guard = 400;                     // сторож таймаута
while((PIND & (1<<bit_) != LOW)                   //ловим момент спада
{
if(!--tmout_guard)
 return false;                                   // таймаут поймали
} 
  delayMicroseconds(((HDQ_DELAY_TDW0 - HDQ_DELAY_TDW1) / 2) + HDQ_DELAY_TDW1); //переходим на середину посылки
  bittimeL[i]= ((PIND & (1<<bit_))!= LOW);          // читаем порт .если подъем был раньше то один уровень, если еще не настал то другой
  delayMicroseconds(HDQ_DELAY_TCYCD - HDQ_DELAY_TDW0); //даем длительную задержку для ловли нового фронта
}
 Serial.println("************Start**********");
 Serial.println(bittimeL[0]);
 Serial.println(bittimeL[1]); 
 Serial.println(bittimeL[2]);
 Serial.println(bittimeL[3]);
 Serial.println(bittimeL[4]);
 Serial.println(bittimeL[5]);
 Serial.println(bittimeL[6]);
 Serial.println(bittimeL[7]);
 Serial.println("************END***********");
}

 

iopq
Offline
Зарегистрирован: 05.07.2016

а чем отличается вот эта запись ((PIND & _BV(2))!= LOW) от  ((PIND & (1<<bit_))!= LOW)

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

iopq, вы точно уверены что занимаетесь своим делом  #define _BV(bit) (1 << (bit))

C:\Program Files (x86)\Arduino\hardware\tools\avr\avr\include\avr\sfr_defs.h 

https://myrobot.ru/stepbystep/pr_mcports.php

iopq
Offline
Зарегистрирован: 05.07.2016

так учиться никогда не поздно. тут вон люди не знают как 2 переменные сравнить.

т.е записи идентичные.

малость понятие появляется и мне удалось прочитать ответ от другого устройства, на которое нет даташита. я просто по такому же принципу проставил задержки.