Алгоритм приема пакета по UART.ATmega16.IAR AVR.

Вопросы настройки, программирования, прошивки микроконтроллеров и микросхем программируемой логики
Закрыто
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 1900
Зарегистрирован: Сб фев 21, 2009 13:11:40
Откуда: Москва

Сообщение ibiza11 »

Доброго времени суток уважаемые форумчане. В общем стоит задача безошибочно принимать каждые 30мс пакет данных (время передачи одного пакета = 0,1мс, байты идут друг за другом),

состоящий из 10 байт, по UART(115200 бит/с) и, в случае приема правильного пакета, ответить в обратном канале. Если не проходит несколько пакетов подряд, вывести флаг ошибки соединения,

при восстановлении связи, очистить флаг и продолжать прием в штатном режиме.
Ошибочным считается пакет в котором находится меньше байт, чем должно быть (10).
Написал кое-какой код, вроде даже работает, но по прошествии некоторого времени перестает распознавать ошибку соединения (не выставляет флаг). JTAG отладчика и возможности подключиться к

контроллеру по JTAG, к сожалению нет (ножки заняты).
расскажу как работает мой алгоритм.
в инициализации заводится таймер на 35мс в течение которого ожидается прием безошибочного пакета.
в основном цикле проверяется состояние этого таймера, если время прошло, таймер сбрасывается и инкрементируется счетчик ошибочных пакетов. Если пришел хотя бы один байт в прерывании

сбрасывается таймер 35мс (но продолжает считать), заводится таймер на 5мс, отлавливающий окончание пакета, считается кол-во пришедших байт. При получении последующих байт сбрасываются

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

выставлен флаг прихода пакета, таймер сбрасывается, приемник выключается. Проверяется кол-во пришедших байт, если оно не равно необходимому кол-ву байт, пакет игнорируется. Если кол-во

байт равно необходимому, пакет обрабатывается. Включается передатчик и передается байт обратно. (В прерывании по окончании передачи передатчик выключается) после обработки пакета кол-во

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

вот код прерывания по окончанию передачи

Код: Выделить всё

#pragma vector=USART_TXC_vect
__interrupt void TX_COMPLETE()
{  
  UCSRB&=~((1<<TXCIE)|(1<<TXEN));                           // Запрет прерывания по окончании передачи|выключение передатчика 
}
вот код прерывания по окончанию приема

Код: Выделить всё

#pragma vector=USART_RXC_vect
__interrupt void RX_COMPLETE()
{
  v *var=&Variables;           //указатель на глобальную структуру
  var->PacketToutCnt=0;     //обнуляем счетчик 5мс
  var->LongToutCnt=0; //обнуляем счетчик 35мс 
  Flag.PacketTout=0;  //очищаем флаг окончания таймаута 5мс
  Flag.LongTout=0;	//очищаем флаг окончания таймаута 35мс
  var->WrongPacketCnt=0;  //обнуляем кол-во неправильных пакетов
  Flag.DownCommErr=0;	//очищаем флаг ошибки соединения (down поскольку приемное устройство является подчиненным)
  Flag.PacketToutEn=1;	//"выключатель" таймаута 5мс (1-вкл, 0-выкл)
  if(++var->BytesReceived<=BYTES_IN_PACKET)	//проверка кол-ва пришедших байт (предв. инкремент)
  {
    if (UCSRA&((1<<FE)|(1<<DOR)|(1<<PE)))	/*это я не стал описывать текстк, здесь проверяются биты ошибок приемника UART(FrameError,DataOverRun,ParityError)*/
      var->ByteErrorFlags|=(1<<(var->BytesReceived-1)); //если есть ошибка, в переменной выставляется соответствующий бит
    data.InputBuf[(var->BytesReceived-1)]=UDR;  //входной буфер данных (массив InputBuf)
    if (var->BytesReceived==BYTES_IN_PACKET)	//если кол-во пришедших байт совпадает с кол-вом необходимых в пакете 
    {
      Flag.PacketTout=1;			//выставляем флаг окончания пакета
      Flag.PacketToutEn=0;			//выключаем таймер 5мс
      var->PacketToutCnt=0;			//сбрасываем таймер 5мс (его счетчик)
    }
  }
}
вот код основного цикла

Код: Выделить всё

__C_task void main(void)
{
   ...............//тут инициализация данных
  UBRRH=(unsigned char)(CUR_UBRR>>8);                               //установка скорости UART
  UBRRL=(unsigned char)(CUR_UBRR&0x00FF);
#ifdef DOUBLE_SPEED
  UCSRA|=(1<<U2X);
#endif
  UCSRC=(1<<URSEL)|(1<<UCSZ0)|(1<<UCSZ1)|(1<<UPM1);                 // Выбор UCSRC регистра|Включение проверки четности|8-битная посылка
  UCSRB=(1<<RXCIE)|(1<<RXEN);                                       // Разрешение прерывания по приему|включение приемника

  for (;;)
  {  
    if(Flag.LongTout)
    {
      //в течение LongTimeout не пришло ни одного правильного пакета
      Flag.LongToutEn=1;	//включение таймаута 35мс (в обработчике этого таймера он автоматом выключается)
      Flag.LongTout=0;		//сброс флага таймаута 35мс
      if(var->WrongPacketCnt<MAX_WRONG_PACKETS)	//если кол-во неправильных пакетов еще не достигло макс значения
      {
        var->WrongPacketCnt++;		//то инкрементируем значение
      }
      else
      {
        Flag.DownCommErr=1;		//иначе выставляем флаг ошибки соединения
      }
    }
    else			//в случае если не было срабатывания таймера 35мс
    {
      if (Flag.PacketTout)	//проверяем флаг таймаута 5мс (таймаут прихода правильного пакета)
      {
        UCSRB&=(~((1<<RXCIE)|(1<<RXEN)));	//выключаем приемник
        Flag.PacketTout=0;			//очищаем флаг таймаута 5мс
        var->LongToutCnt=0;			//обнуляем счетчик таймаута 35мс
        if(var->BytesReceived==BYTES_IN_PACKET)	//если кол-во байт равно кол-ву необходимых байт
        {
          if(var->ByteErrorFlags!=0)//обработка переменной флагов ошибок байтов пакета
          {
            var->ByteErrorFlags=0;	//если есть ошибки приема данных (Parity,Frame,OverRun) здесь можно их обработать (я их тупо сбрасываю)
          }
          else
          {
            ........//здесь идет долгая обработка пакета данных (около 3мс)
            UCSRB|=(1<<TXCIE)|(1<<TXEN);// Разрешение прерывания по окончании передачи|включение передатчика 
            UDR=var->TrData;	// Передаем ответные данные (1 байт)
          }
        }
        UCSRB|=(1<<RXCIE)|(1<<RXEN); // Разрешение прерывания по окончании приема|включение приемника
        var->BytesReceived=0;	//обнуление счетчика кол-ва пришедших байт в пакете
      }
    }
  }
} 
в общем жду помощи. повторяю вопрос: почему после некоторого времени работы алгоритм перестает определять ошибку соединения. (Flag.DownCommErr)
Ставим плюсы: )
Реклама
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2482
Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень

Сообщение vitalik_1984 »

ibiza11 писал(а):JTAG отладчика и возможности подключиться к

контроллеру по JTAG, к сожалению нет (ножки заняты).
расскажу как работает мой алгоритм.
Можно и без джи таг отладчика:)
1.просто отправлять код по уарт.
Наставить везде меток где считаешь, что они необходимы.
Все равно ведь контролируешь что идет по УАРТ
2.Полный код, пжалст
В поисках истины человек развивается.
Контактная информация:
Реклама
Друг Кота
Аватара пользователя
Сообщения: 3961
Зарегистрирован: Пн июл 13, 2009 14:37:39
Откуда: Московская область, наукоград.....

Сообщение Meteor »

Настораживает что пакеты идут с периодом 30 мс, а таймауты настроены на 35 мс.
Всегда думал надо делать наоборот - таймаут короче периода следования.
По коду ничего не скажу :dont_know:
Загружая на вход компьютера "мусор", на выходе получим "мусор^32".
PS. Не работаю с: Proteus, Multisim, EWB, Micro-Cap... не спрашивайте даже
Контактная информация:
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2482
Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень

Сообщение vitalik_1984 »

Meteor писал(а):Настораживает что пакеты идут с периодом 30 мс, а таймауты настроены на 35 мс.
Всегда думал надо делать наоборот - таймаут короче периода следования.
По коду ничего не скажу :dont_know:
35 это видать 30 между и 5 передача.Если ни одного байта, то ошибка.

В этом случае нужно еще не забывать при окончании или при начале передачи обнулять счетчик.
В поисках истины человек развивается.
Контактная информация:
Реклама
Эиком - электронные компоненты и радиодетали
Друг Кота
Аватара пользователя
Сообщения: 3961
Зарегистрирован: Пн июл 13, 2009 14:37:39
Откуда: Московская область, наукоград.....

Сообщение Meteor »

vitalik_1984 писал(а):35 это видать 30 между и 5 передача.Если ни одного байта, то ошибка.
А я думал что умею по русски читать
ibiza11 писал(а):задача безошибочно принимать каждые 30мс пакет данных (время передачи одного пакета = 0,1мс, байты идут друг за другом), состоящий из 10 байт, по UART(115200 бит/с)
Я бы таймауты сделал значительно короче - скажем 1 мс, после первого принятого символа в пакете.
Кстати, у меня пакеты всегда начинаются с преамбулы - очень облегчает обмен и отладку
Загружая на вход компьютера "мусор", на выходе получим "мусор^32".
PS. Не работаю с: Proteus, Multisim, EWB, Micro-Cap... не спрашивайте даже
Контактная информация:
Реклама
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 1900
Зарегистрирован: Сб фев 21, 2009 13:11:40
Откуда: Москва

Сообщение ibiza11 »

Спасибо всем за ответы :)
Полный код на 7 с лишним килобайт, там много лишнего, не относящегося к теме.
Код по уарт надо отправлять только при получении пакета, а если слать в любой момент, то не будем соответствовать необходимому протоколу.
Meteor писал(а):Настораживает что пакеты идут с периодом 30 мс, а таймауты настроены на 35 мс.
Всегда думал надо делать наоборот - таймаут короче периода следования.
Возможно Вы неправильно поняли, у меня этот таймаут выставляет флаг ошибки соединения, т.е. извещает о том, что не пришло два пакета подряд. А таймаут 5мс извещает о том, что больше нет принимаемых данных в UART в течение 5мс, что соответствует окончанию пакета - т.е. здесь как раз таки есть связь.
в штатном режиме при нормальном приеме пакетов каждые 5мс наступает таймаут. Таймаут 35мс никогда не наступит, если пакеты исправно идут каждые 30 мс, поскольку счетчик этого таймаута сбрасывается при приеме хотя бы одного байта.
vitalik_1984 писал(а):В этом случае нужно еще не забывать при окончании или при начале передачи обнулять счетчик.
счетчики и флаги сбрасываются при приеме байта, в коде есть коментарии.
Meteor писал(а):Я бы таймауты сделал значительно короче - скажем 1 мс, после первого принятого символа в пакете.
прием пакета из 10 байт на скорости 115200 занимает около 0,1мс, период следования пакетов 30мс, поэтому что 1мс, что 5мс не имеет значения, поскольку оба значения больше времени приема 1 байта и меньше периода следования пакетов. Я все равно попробовал, проблема остается.
Meteor писал(а):Кстати, у меня пакеты всегда начинаются с преамбулы - очень облегчает обмен и отладку
я бы с радостью, но, к сожалению, прибор разрабатывается как дополнение к уже готовому прибору и протокол уже нельзя изменить.

Если сложно по коду разбираться, было бы хорошо, если кто-нибудь привел бы свой алгоритм.
Ставим плюсы: )
Реклама
Сверлит текстолит когтями
Аватара пользователя
Сообщения: 1262
Зарегистрирован: Пн дек 08, 2008 10:58:48
Откуда: Винница

Сообщение urry »

При такой скорости обмена Вы не будете вылезать из прерывания.
На Вашем месте я просто перешел бы на ЮСБ .
Контактная информация:
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 1900
Зарегистрирован: Сб фев 21, 2009 13:11:40
Откуда: Москва

Сообщение ibiza11 »

urry писал(а):При такой скорости обмена Вы не будете вылезать из прерывания.
На Вашем месте я просто перешел бы на ЮСБ .
кхм... это подтверждено какими-то расчетами или просто личное мнение? у меня около 80% времени крутится основной цикл. Думаю осциллограф не будет врать!?
Ставим плюсы: )
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2482
Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень

Сообщение vitalik_1984 »

1.Я подумал и решил, что может послужить причиной ваших неурядиц- простая рассинхронизация протоколов.Вы ведь сказали, что таймер продолжает работать.А нужно при каждом окончании передачи, или хотя бы через несколько передач происходил перезапуск таймера.
2.Есть предложение действительно изменить время тайм аута.И просто по истечении его добавлять к переменной- счетчику таймаутов 1-цу.При достижении допустим величины шесть при таймауте 5мс равняется 35мс.Величина счетчика проверяется при входе в обработку Т-аута. в таком случае еще было бы не плохо перезапускать таймер при начале передачи потом при каждом превышении значения Х посылать ошибку соединения.Соответственно при прерывании от байта все обнуляется.
В поисках истины человек развивается.
Контактная информация:
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2482
Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень

Сообщение vitalik_1984 »

совет: 1.можно выкинуть лишние части программы, которые не влияют на получение данных.

и 2.все таки использовать возможность применения джи тага.ведь вся обвязка не нужна, чтоб получить байт.
можно даже сделать два диодика для режимов прерывания и основного цикла.И третий для ошибки:)
В поисках истины человек развивается.
Контактная информация:
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 1900
Зарегистрирован: Сб фев 21, 2009 13:11:40
Откуда: Москва

Сообщение ibiza11 »

vitalik_1984 писал(а):1...простая рассинхронизация протоколов.....А нужно при каждом окончании передачи происходил перезапуск таймера.
вот мои слова:
Если пришел хотя бы один байт в прерывании сбрасывается таймер 35мс (но продолжает считать)
это означало,что сбрасывается счетчик таймера,но сам таймер не останавливается(здесь таймер-абстрактное понятие,просто переменная,которая проверяется в прерывании таймера микроконтроллера,если переменная достигает значения задаваемого константой,выставляется флаг,который проверяется в основном цикле программы)
Вот код находящийся в прерывании переполнения.

Код: Выделить всё

  var->PacketToutCnt=0;     //обнуляем счетчик 5мс
  var->LongToutCnt=0; //обнуляем счетчик 35мс 
  Flag.PacketTout=0;  //очищаем флаг окончания таймаута 5мс
  Flag.LongTout=0;   //очищаем флаг окончания таймаута 35мс
vitalik_1984 писал(а):2.Есть предложение действительно изменить время тайм аута.И просто по истечении его добавлять к переменной- счетчику таймаутов 1-цу.При достижении допустим величины шесть при таймауте 5мс равняется 35мс.Величина счетчика проверяется при входе в обработку Т-аута.
таймаут 35 мс запускается сразу, обнуляется при приходе любого байта. 5мс запускается только после приема первого байта и выключается после приема последнего байта пакета. не получится. или я чего-то не понял из ваших мыслей. расскажите алгоритм.

Совет насчет выкидывания лишних частей программы возьму на рассмотрение, думаю можно организовать. Спасибо за совет;)
Ставим плюсы: )
Сверлит текстолит когтями
Аватара пользователя
Сообщения: 1262
Зарегистрирован: Пн дек 08, 2008 10:58:48
Откуда: Винница

Сообщение urry »

2 таймера, 1 таймер, скажем на 5 мс., второй на 35 мс. 1 не останавливается, а перезагружается этим значением.
Автоматическая синхронизация.
Флаг приема пакета, флаг ошибки, флаг успешного приема , курсор - счетчик принятых байт
//
В прерывании по приему байта
аппаратные ошибки приема были ?
да -> {курсор =0, Флаг приема пакета =0}
иначе-> {Флаг приема пакета =1
курсор++}
курсор == 10 байтам? -> да{ флаг успешного приема =1, курсор =0, Флаг приема пакета =0, сбрасываем 2 таймер}
всегда -> перезагрузить таймер

// В прерывании по 1 таймеру
флаг приема пакета == 1 ?
да -> ошибка, не хватило байт - { Флаг приема пакета =0 , курсор =0,флаг ошибки=1}
нет -> курсор =0
всегда ->перезагрузить таймер

// В прерывании по 2 таймеру
раз сюда зашли, в течении 35 мс он не сбрасывался, пропуск пакета
флаг отсутствия пакета =1, перезагрузить таймер
всегда ->перезагрузить таймер
---------------------------------------------------------------------------------------------------
Контактная информация:
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2482
Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень

Сообщение vitalik_1984 »

urry писал(а):2 таймера, 1 таймер, скажем на 5 мс., второй на 35 мс. 1 не останавливается, а перезагружается этим значением.
Автоматическая синхронизация.

// В прерывании по 2 таймеру
раз сюда зашли, в течении 35 мс он не сбрасывался, пропуск пакета
флаг отсутствия пакета =1, перезагрузить таймер
всегда ->перезагрузить таймер
---------------------------------------------------------------------------------------------------
1.не понял как тут будет автоматическая синхронизация будет осуществляться.
2.с какого момента второй таймер запускается.Ведь если нет пакета, то не факт, что он появится точно к нолю(или рядом) второго таймера.Есть, вероятность что второе устройство промолчит пол цикла второго таймера(вот про эту синхронизацию я говорил:) )про
В поисках истины человек развивается.
Контактная информация:
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2482
Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень

Сообщение vitalik_1984 »

urry писал(а):2 таймера, 1 таймер, скажем на 5 мс., второй на 35 мс. 1 не останавливается, а перезагружается этим значением.
Автоматическая синхронизация.

// В прерывании по 2 таймеру
раз сюда зашли, в течении 35 мс он не сбрасывался, пропуск пакета
флаг отсутствия пакета =1, перезагрузить таймер
всегда ->перезагрузить таймер
---------------------------------------------------------------------------------------------------
1.не понял как тут будет автоматическая синхронизация будет осуществляться.
2.с какого момента второй таймер запускается.Ведь если нет пакета, то не факт, что он появится точно к нолю(или рядом) второго таймера.Есть, вероятность что второе устройство промолчит пол цикла второго таймера(вот про эту синхронизацию я говорил:) )
В поисках истины человек развивается.
Контактная информация:
Сверлит текстолит когтями
Аватара пользователя
Сообщения: 1262
Зарегистрирован: Пн дек 08, 2008 10:58:48
Откуда: Винница

Сообщение urry »

1.Автоматическая синхронизация - сброс курсора в 0 при отсутствии в течении 5 мс прерываний по приему.
2. Не понял Вашего вопроса- если беспокоит то, что в течении времени до 1 пакета будет индикация пропуска. то запуск второго таймера сделать одновременно с первым принятым пакетом. Т.е - не запущен, запустить, ставим флаг.
Контактная информация:
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2482
Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень

Сообщение vitalik_1984 »

ладно, курсор сбросили через три мс начался прием байтов.получается нужно второй таймер в это время запустить.Или я не прав?
вы не смотрите, что не я тему начал, просто я в ближайшем времени собираюсь примерно тоже самое делать.Поэтому интересуюсь, а так как проверять пока не на чем, задаю много вопросов:)
В поисках истины человек развивается.
Контактная информация:
Сверлит текстолит когтями
Аватара пользователя
Сообщения: 1262
Зарегистрирован: Пн дек 08, 2008 10:58:48
Откуда: Винница

Сообщение urry »

второй таймер запускаем по первому правильному приему пакета и уже не выключаем его - хай молотит. Каждый правильный пакет через 30 мс его перезагружает опять на 35 мс значением и сработать по прерыванию он не сможет, пока нет пропуска пакета.
Контактная информация:
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2482
Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень

Сообщение vitalik_1984 »

urry писал(а):второй таймер запускаем по первому правильному приему пакета и уже не выключаем его - хай молотит. Каждый правильный пакет через 30 мс его перезагружает опять на 35 мс значением и сработать по прерыванию он не сможет, пока нет пропуска пакета.
но ведь он сработает, если пакет неправильный,так? значит обработать можно будет по флагам какое исключение возникло.

Возник тут вопрос:А зачем нам гробить два таймера на решение такой простой задачи как эта, ведь устройство может быть использовано и для других целей, не только для приема этих байтов.Можно ли оптимизировать использовав 1 таймер- тот что попроще. где нет шим,например.
Вот вариант

===========
прием байта
------
таймер1 старт 5мс
курсор ++
аппаратные ошибки приема были ?
да -> {курсор =0, Флаг приема пакета =0,}
иначе-> {Флаг приема пакета =1,
курсор++}
курсор == 10 байтам? -> да{ флаг успешного приема =1, курсор =0, Флаг приема пакета =0,счет циклов=0}
всегда -> перезагрузить таймер

===========
прерывание таймера1
выбор счет циклов{
0----
флаг приема пакета == 1 ?
да -> ошибка, не хватило байт - { Флаг приема пакета =0 , курсор =0,флаг ошибки=1}
нет -> курсор =0}
6----
раз сюда зашли, в течении 35 мс он не сбрасывался, пропуск пакета
флаг отсутствия пакета =1, перезагрузить таймер,счетчик циклов=1
иначе ----
ничего не делаем, ждем посылок:)
}
счет циклов++
всегда ->перезагрузить таймер

Вот типа того.
правда как это скажется на быстродействии не знаю
В поисках истины человек развивается.
Контактная информация:
Сверлит текстолит когтями
Аватара пользователя
Сообщения: 1262
Зарегистрирован: Пн дек 08, 2008 10:58:48
Откуда: Винница

Сообщение urry »

да, конечно, можно использовать и один таймер.
Просто повторять в своей конструкции такой алгоритм не советую, здесь он от безысходности - есть готовый пакет, который нужно подсмотреть и изменить который мы не можем, поэтому как-то так...
В случае, когда выбирается свой протокол, когда пакет формируется самостоятельно, то уже ставим контрольную сумму в конец, идет полноценный обмен - приняло - подтверждение или предложение повторить и т.д.
Эти самописные протоколы работают, конечно, но когда как бы хочется какой-то унификации в дальнейшем - если сразу перейти на какой-нить модбас, сэкономится время.
Контактная информация:
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 1900
Зарегистрирован: Сб фев 21, 2009 13:11:40
Откуда: Москва

Сообщение ibiza11 »

ibiza11 писал(а):(здесь таймер-абстрактное понятие,просто переменная,которая проверяется в прерывании таймера микроконтроллера,если переменная достигает значения задаваемого константой,выставляется флаг,который проверяется в основном цикле программы)
:)
вот код:

Код: Выделить всё

unsigned char Flag;  //флаговая переменная
unsigned short TimerCnt;  //счетчик таймера
enum{TimerEnable,//флаг включения/выключения таймера
TimerOvf//счетчик таймера
};
#define TIMER_MAX 200 //кол-во циклов до переполнения

// ****этот код должен обрабатываться в основном цикле****
    if(Flag&(1<<TimerOvf))
    {
      //обработчик таймера
      Flag&=~(1<<TimerOvf);
    }

// ****этот код должен обрабатываться в прерывании таймера****
if (Flag&(1<<TimerEnable))
  {
    if (++TimerCnt==TIMER_MAX)
    {
      TimerCnt=0;//сброс счетчика
      Flag&=~(1<<TimerEnable);//выключение таймера (можно исключить, но удобно использовать при разовой задержке)
      Flag|=(1<<TimerOvf);//возведение флага переполнения таймера
    }
  }
по теме, протокол остался в том же состоянии, что и был, временно перешел на другую часть программы. позже буду переписывать заново.
Ставим плюсы: )
Закрыто

Вернуться в «Микроконтроллеры и ПЛИС»