Jump to content
n_angelo

Прерывание отрабатывает два раза вместо одного

Recommended Posts

По приходящему на ножку A1 импульсу настроено прерывание. Прерывание должно отработать один раз и должно делать следующее: пауза 7 секунд, потом на 1,5 секунды открыть реле. Во время прерывания светодиод на плате гаснет и загорается в такт секундам. Код отрабатывает верно за исключением того, что прерывание отрабатывает 2 раза. Т.е. подали импульс, заморгал светодиод в течении 7ми секунд, потом щёлкнуло реле (открылось), затем опять щёлкнуло (закрылось), потом всё повторяется еще раз (7+1,5). В режиме дебага работает нормально. Пробовал отключать реагирование на прерывания во время его отработки:

disableInterruupts();
...
enableInterruupts(); 

но не помогает.

STM8S103F3P6

Код прерывания

Скрытый текст

INTERRUPT_HANDLER(EXTI_PORTA_IRQHandler, 3)
{
  disableInterrupts();
  int i = 0;
  TIM2_TimeBaseInit(TIM2_PRESCALER_32768, 61); // 1 second
  TIM2_Cmd(ENABLE);
  while(i<8){
    if (TIM2_GetFlagStatus(TIM2_FLAG_UPDATE) == SET) {
          TIM2_ClearFlag(TIM2_FLAG_UPDATE);
          GPIO_WriteReverse(GPIOB, GPIO_PIN_5);
          i++;
    }
  }
  TIM2_Cmd(DISABLE);
  i = 0;
  TIM2_TimeBaseInit(TIM2_PRESCALER_32768, 30); // 0,5 second
  TIM2_Cmd(ENABLE);
  GPIO_WriteHigh(GPIOC, GPIO_PIN_6);
  while(i<4){
    if (TIM2_GetFlagStatus(TIM2_FLAG_UPDATE) == SET) {
          TIM2_ClearFlag(TIM2_FLAG_UPDATE);
          GPIO_WriteReverse(GPIOB, GPIO_PIN_5);
          i++;
    }
  }
  TIM2_Cmd(DISABLE);
  GPIO_WriteLow(GPIOC, GPIO_PIN_6);
  enableInterrupts();
}

 

Код в main.c

Скрытый текст

#include "stm8s.h"

int main( void )
{
  GPIO_Init(GPIOA, GPIO_PIN_1, GPIO_MODE_IN_FL_IT);
  GPIO_Init(GPIOB, GPIO_PIN_5, GPIO_MODE_OUT_OD_HIZ_SLOW);
  GPIO_Init(GPIOC, GPIO_PIN_6, GPIO_MODE_OUT_PP_LOW_SLOW);
  CLK_SYSCLKConfig(CLK_PRESCALER_CPUDIV128);
  CLK_SYSCLKConfig(CLK_PRESCALER_HSIDIV8);

  EXTI_SetExtIntSensitivity(EXTI_PORT_GPIOA, EXTI_SENSITIVITY_FALL_ONLY);
  enableInterrupts();
 
   /* Infinite loop */
  while (1)
  {

  }
}

 

 

Edited by n_angelo

Share this post


Link to post
Share on other sites

Сброс флага прерывания по таймеру вижу, а по входу EXTI не заметил. В обработчике не делают такой большой код 8.5 сек. Лучше в обработчике по EXTI устанавливать флажок, а в основном цикле все действия.

Share this post


Link to post
Share on other sites

Изготовление 2-х слойных плат от 2$, а 4-х слойных от 5$!

Быстрое изготовление прототипа платы всего за 24 часа! Прямая доставка с нашей фабрики!

Смотрите видео о фабрике JLCPCB: https://youtu.be/_XCznQFV-Mw

Посетите первую электронную выставку JLCPCB https://jlcpcb.com/E-exhibition чтобы получить купоны и выиграть iPhone 12, 3D-принтер и так далее...

14 минут назад, snn_krs сказал:

Сброс флага прерывания по таймеру вижу, а по входу EXTI не заметил. В обработчике не делают такой большой код 8.5 сек. Лучше в обработчике по EXTI устанавливать флажок, а в основном цикле все действия.

В stm8s нет флага выхода из прерывания. Я сам удивился, когда пытался долго его найти. В коде я сбрасываю флаг переполнения таймера для подсчёта секунд.

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

Кстати, нет мыслей почему два раза входит в прерывание?

UPD:

Проверил весь порт A осциллографом. Повторных импульсов нет. Значит проблема в коде.

Share this post


Link to post
Share on other sites

Высокая надежность SiC! Как они этого добились?

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

Подробнее

Есть флаг входа в прерывание по EXTI это в регистре EXTI_SR1. Его надо сбросить в прерывании командой типа

TIM2_ClearFlag(TIM2_FLAG_UPDATE);

Только для EXTI. Я пишу для STM32 в Кейле поэтому точно сказать не могу. Если этот флаг не сбросить прерывание будет вызываться постоянно. Почему у вас только два раза не знаю.

Share this post


Link to post
Share on other sites

Материалы вебинара «STM32L5. Секреты оценки энергопотребления»

Опубликованы запись и материалы вебинара КОМПЭЛ, посвященного первому семейству МК STM32L5 на ядре Cortex-M33. На вебинаре было рассказано о самых распространенных ошибках при расчете энергопотребления микроконтроллеров и о специальном тесте ULPMark, позволяющем дать наиболее объективную оценку энергоэффективности. Измерения проводились на демонстрационной платформе STM32L562E-DK.

Подробнее

9 часов назад, snn_krs сказал:

Есть флаг входа в прерывание по EXTI это в регистре EXTI_SR1. Его надо сбросить в прерывании командой типа

TIM2_ClearFlag(TIM2_FLAG_UPDATE);

Только для EXTI. Я пишу для STM32 в Кейле поэтому точно сказать не могу. Если этот флаг не сбросить прерывание будет вызываться постоянно. Почему у вас только два раза не знаю.

Поверьте, этого регистра в STM8S просто нет. Я по привычке хотел обнулить флаг, но статус-регистра там нет.

Не знаю как в STM32, а в STM8L, прерывание отработает и зависнет в конце прерывания, до тех пор пока не сбросить флаг, т.е. повторяться оно не будет.

Share this post


Link to post
Share on other sites

Снижена цена на AC/DC и DC/DC преобразователи Mornsun в Компэл!

Компэл и компания Mornsun снизили цены на преобразователи AC/DC-преобразователи семейств LS и LDE. По привлекательной цене также предлагаются DC/DC-преобразователи изолированных семейств поколений R2 и R3 различного конструктивного исполнения.

Подробнее

55 минут назад, Vitemk сказал:

Дребезг?

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

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

Share this post


Link to post
Share on other sites

У Вас странное представление о прерываниях. Дело не в том, что возникло новое прерывание во время обработчика, а в том, когда гасится флаг. Если в начале, то новое прерывание будет исполнено немедленно после выхода из обработчика, а если в конце, то флаг будет сброшен и никакого нового вызова ISR не будет.

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

ЗЫ. А что там у Вас за бред с запретом-разрешением прерываний в обработчике? Это зачем? Это кто Вас этому научил?

Edited by my504

Share this post


Link to post
Share on other sites
6 часов назад, my504 сказал:

У Вас странное представление о прерываниях. Дело не в том, что возникло новое прерывание во время обработчика, а в том, когда гасится флаг. Если в начале, то новое прерывание будет исполнено немедленно после выхода из обработчика, а если в конце, то флаг будет сброшен и никакого нового вызова ISR не будет.

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

ЗЫ. А что там у Вас за бред с запретом-разрешением прерываний в обработчике? Это зачем? Это кто Вас этому научил?

Я всегда думал, что очистка Pending Bit инициирует выход из прерывания. Сегодня проверю. Получается, если этого статус-регистра не существует, то любое прерывание может прервать текущее? (Если не настраивать специально приоритеты).


На два раза перечитал свои сообщения. Где я говорил о запрете/разрешении прерывании? Процитируйте.

 

Share this post


Link to post
Share on other sites
INTERRUPT_HANDLER(EXTI_PORTA_IRQHandler, 3)
{
  disableInterrupts();
....................
  enableInterrupts();
}

Это Ваш код? 

Вложенные прерывания невозможно запретить таким методом. Входные скобки обработчиков генерируют сохранение контекста, а выходные восстановление контекста и специальную команду выхода из прерывания IRET. Если вложенные прерывания разрешены, то между  входом в ISR и строкой  disableInterrupts(), а также между строкой enableInterrupts() и выходом более чем достаточно времени для повторного входа в прерывание. А если вложенные прерывания запрещены, то переход по вектору ISR АВТОМАТИЧЕСКИ гасит  глобальное разрешение прерываний, а команда выхода из ISR  - IRET (закрывающая скобка) так же автоматически его разрешает. В ОДНОМ МАШИННОМ ЦИКЛЕ. То есть повторный вход полностью исключен.

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

А вообще, ознакомьтесь с мануалом по программированию выбранного Вами МК:

https://www.st.com/content/ccc/resource/technical/document/programming_manual/43/24/13/9a/89/df/45/ed/CD00161709.pdf/files/CD00161709.pdf/jcr:content/translations/en.CD00161709.pdf

ЗЫ. Я сходу не нашел инструмента запрета вложенности прерываний в STM8. Не исключено, что его нет вообще, ну кроме приоритетов. То есть эти две Ваших строки вообще бессмысленны.

Edited by my504

Share this post


Link to post
Share on other sites
1 час назад, my504 сказал:

INTERRUPT_HANDLER(EXTI_PORTA_IRQHandler, 3)
{
  disableInterrupts();
....................
  enableInterrupts();
}

Это Ваш код? 

Вложенные прерывания невозможно запретить таким методом. Входные скобки обработчиков генерируют сохранение контекста, а выходные восстановление контекста и специальную команду выхода из прерывания IRET. Если вложенные прерывания разрешены, то между  входом в ISR и строкой  disableInterrupts(), а также между строкой enableInterrupts() и выходом более чем достаточно времени для повторного входа в прерывание. А если вложенные прерывания запрещены, то переход по вектору ISR АВТОМАТИЧЕСКИ гасит  глобальное разрешение прерываний, а команда выхода из ISR  - IRET (закрывающая скобка) так же автоматически его разрешает. В ОДНОМ МАШИННОМ ЦИКЛЕ. То есть повторный вход полностью исключен.

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

А вообще, ознакомьтесь с мануалом по программированию выбранного Вами МК:

https://www.st.com/content/ccc/resource/technical/document/programming_manual/43/24/13/9a/89/df/45/ed/CD00161709.pdf/files/CD00161709.pdf/jcr:content/translations/en.CD00161709.pdf

ЗЫ. Я сходу не нашел инструмента запрета вложенности прерываний в STM8. Не исключено, что его нет вообще, ну кроме приоритетов. То есть эти две Ваших строки вообще бессмысленны.

Да, простите, уже и забыл про этот код. В текущей версии удалил его. Я его взял из SPL-библиотеки от STM для STM8S в дефайнах для IAR.

Share this post


Link to post
Share on other sites

Не цитируйте предыдущее сообщение, милейший, а то Вы быстро утратите право писать свои на некоторый предусмотренный Правилами срок. Это иногда неприятно... )))

По делу. Вы в крайних своих сообщениях как то головоломно излагали соображения нащщет прерываний и механизма их функционирования. Мой спич был в основном об этом. Ваши представления  в высшей мере странные...

Edited by my504

Share this post


Link to post
Share on other sites
28.02.2020 в 08:51, n_angelo сказал:

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

4 дня назад я делал под заказ одно устройство на Atmega8. Принцип работы схож с Вашим. Посчитал что контроллер больше ничего делать не будет, поэтому запихнул весь код обработки в системное прерывание. Так вот при отладке удивился увидев точно ВАШУ ситуацию. Код отработал два раза. Нажимаешь кнопку и код последовательно проходил цикл , а потом небольшая задержка и повтор. Как-бы код очень простой и я дошел вывода что даже при большой желании и наличии места очень НЕ  правильно засовывать задержки в обработчик прерывания. Изменил три строчки вынеся код в главный цикл, а в обработчике установил флаг - вуаля ! Все работает отлично!!!


"Мы все учились понемногу, чему-нибудь и как-нибудь...")

Share this post


Link to post
Share on other sites

но причина повторного запуска так и не названа ...


Мудрость приходит вместе с импотенцией...

Share this post


Link to post
Share on other sites

Полагаю, что есть какая-то защита от зависания в прерывании.

Share this post


Link to post
Share on other sites

Код не может зависать в прерывании, только если в обработчике нет бесконечного цикла. Однако код может немедленно СНОВА зайти в прерывание после выхода из него, если флаг прерывания либо остался поднятым, либо был поднят снова за время исполнения обработчика.

Share this post


Link to post
Share on other sites
12 часов назад, my504 сказал:

либо был поднят снова за время исполнения обработчика.

Значит вполне может быть дребезг контактов в процессе длительного выполнения обработчика. 


"Мы все учились понемногу, чему-нибудь и как-нибудь...")

Share this post


Link to post
Share on other sites

на сколько я знаю, флаг сбрасывается аппаратно при выходе из обработчика.

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


Мудрость приходит вместе с импотенцией...

Share this post


Link to post
Share on other sites
10 часов назад, Starichok сказал:

флаг сбрасывается аппаратно при выходе из обработчика.

те у АВР если произойдет событие в момент работы обработчика , событие будет потеряно?

Share this post


Link to post
Share on other sites
4 минуты назад, IMXO сказал:

у АВР если произойдет событие в момент работы обработчика , событие будет потеряно?

Нет. @Starichok не прав: флаг сбрасывается ПРИ ВХОДЕ в обработчик, точнее, сразу при переходе на соответствующий вектор, в обработчике флаг уже не стоит. Если флаг будет повторно установлен во время работы обработчика, после выхода из него, если нет других более приоритетных запросов, после исполнения 1 команды снова произойдет вызов этого обработчика...

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


Если забанить всех, кто набрался смелости думать независимо, здорово будет на форуме - как на кладбище: тишина, птички поют...

Share this post


Link to post
Share on other sites

благодарю, приму к сведению.

Share this post


Link to post
Share on other sites
9 часов назад, ARV сказал:

Нет. @Starichok не прав: флаг сбрасывается ПРИ ВХОДЕ в обработчик

прошу извинить, писал по памяти, но в памяти моей это перепуталось ...


Мудрость приходит вместе с импотенцией...

Share this post


Link to post
Share on other sites

Join the conversation

You are posting as a guest. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

  • Сообщения

    • 24 В при токе 2.5 А это 60 Вт. 27000 вольт при 60 Вт это ток один-два миллиампера. Которые имеют ток утечки выше миллиампера. Собственно, заряжать столь слабым источником не получится, что ты и получил на практике. Перематывай трансформатор на гораздо меньшее напряжение, но на гораздо больший ток, хотя бы в 30 раз!
    • Карочь ребя  , все по  фне шую ...  Холодильник в кухню , капутер  в гостинную ...  
    • Делаю зарядное устройство для электролитических конденсаторов, заряжать решил от ТДКС и схемы ZVS драйвера. Питание беру от лабораторного источника питания (выставляю около 24В и 2,5 А). Зарядить нужно блок флэш электролитов (те, что применяются в вспышке фотоаппаратов, 330В, 120 мкФ каждый) со смешанным подключением (общей емкостью 1280 мФ и напряжением 990В). Этот способ уже рассмотрен здесь: https://youtu.be/et0DtOzbB0U https://youtu.be/t7iZNVMdrU8 Подключил ТДКС к блоку - напряжение зарядки выше 60В не растёт. То есть, показание на мультиметре доходит до 60В и остаётся на месте. При этом, без нагрузки ТДКС работает стабильно, выдаёт хорошую дугу и напряжение выше киловольта. Сами конденсаторы - рабочие. Чем может быть связана такая просадка? Пробовал подключать отдельно линию из 10 параллельных конденсаторов - напряжение достигает максимум 30 В.
    • Если жесткий диск механический, то ему такое не понравится, надо ццд ставить.
    • Это и есть датчик тока - что для отключения, что для стабилизации. Все зависит от того, как сделан стабилизатор тока. Если правильно - то шунт и будет около 0,01 Ом. Только т огда ему нужен будет усилитель сигнала.   - вот вам и стабилизатор тока, и напряжения, и датчик тока 0,01 Ом. И ток 5А или около того.

  • Пластиковые гайки барашковые от М5 до М10

  • Similar Content

    • By 9Klima
      Здравствуйте обитатели форума, вернулся к кодингу и на форум после лет 12 паузы.
      взялся за STM8 перед тем как штурмовть стм32 там уже получил по лбу когда-то и откотился.
      суть вопроса сконфигурировал второй таймер. второй канал на кристале STM8S103F3  как ШИМ1 всё класно работает гордость за не напрасно потраченное время на дробления  RM0016.
      наступил момент написания библиотеки для удобности обращения с шимом и тут началась эпопея:
      Сначала как посчитать что загрузить чтобы получить желаемую частоту, потом проверка всё на осциллограммах и тут на меня приходит озарение что наверное что то не так, временные интервалы до частоты 122Hz рросчитываются и совпадают.
      А после просто треш : тактовая частота HSI 16 000 000 без делителей прямо на вход таймера.
      PSCR =0;  ARR=65535;   Fout=244Hz
      PSCR =1;  ARR=65535;   Fout=121Hz
      PSCR =2;  ARR=65535;   Fout=60Hz
      PSCR =3;  ARR=65535;   Fout=30Hz
      PSCR =4;  ARR=65535;   Fout=15Hz
      PSCR =5;  ARR=65535;   Fout=7,59Hz
      PSCR =6;  ARR=65535;   Fout=3,8Hz
      PSCR =7;  ARR=65535;   Fout=1,91Hz
      PSCR =8;  ARR=65535;   Fout=0,98Hz
      Вроде всё гармонично но по факту както у меня не сошлось с расчётами. Там где должно быть 80 там 60. Я понимаю что встроенный генератор не блещет стабтильностью но всё равно что-то с расчётами не так либо я вообще не знаю что делаю не так.
      Fout= Fтактирования/([PSCR]+1)/([ARR]+1) тз сих выходит:
      PSCR =8;  ARR=65535;   Fout=???Hz
      16 000 0000/9/65536/=27Hz
      Что не так? где лыжи не едут?
      чувствую нужно срочно заказать частотомер для измерения до чёрто знаков дабы  невроз не лечить.
       
       
       
    • By n_angelo
      Привет, знатоки. Написал свою первую программу для контроллера STM8L152C6T6 (STM8L-Discovery). Это, собственно, моя первая программа для контроллеров вообще. Я многого не знаю и не понимаю. Возможно ваш ответ на мой вопрос будет банален.
      Используемая периферия: DAC, DMA, TIM4, CLK, GPIO
      Задача у программы такая:
      В EEPROM зашит один период синусоиды с дискретизацией 44100Гц. Период занимает ровно 101 байт, что по сути должно быть равно 2,29мс (1/44100*101). В коде программы только конфигурация периферии, одно прерывание на кнопке и пустой бесконечный цикл, который ничего не делает. Всю работу выполняет таймер, который настроен выдавать запрос к DMA на каждые 1/44100 (ядро тактируется 2мГц, таймер считает до 45). В свою очередь DMA забирает из EEPROM по одному байту на каждый запрос от таймера и передаёт его в DAC. Далее DAC выводит бесконечную синусоиду на ногу PF0. Прерывание на кнопке запускает весь этот механизм и зажигает светодиод.
      Проблема:
      Измеряя ногу PF0 осциллографом было замечено, что период синусоиды занимает около ≈4мс. Фото под катом.
      Меня это расстроило. Экспериментально выяснилось, что стоит только вписать в бесконечный цикл какую-нибудь проверку, например, [если значение текущего байта синусоиды = 0xFF, то зажечь светодиод, если 0x00, то потушить], то осциллограф показывает правильный тайминг в 2(с копейками)мс. В принципе в теле цикла может быть что угодно, кроме пустоты, и тайминг налаживается.
      Я не могу отдебажить дизассемблер, т.к. его не знаю. Это у меня в планах. Но я очень хочу понять, что происходит и почему пустой цикл рушит тайминг.
      Спасибо.
       
       
       
       
    • By n_angelo
      Привет. Хочу узнать ваше мнение. Я новичок в embedded. Можно сказать, что пришел с веба. Малость Python, JS, C. Меня, конечно, предупреждали начать с AVR, но я уверенный в себе решил сразу залезть на STM32. Вынашивая идею для проекта, параллельно курив Reference Manual и Data Sheet по STM32, я понял что его будет слишком жирно для проекта. Я перескочил на STM8L. И тут меня начал огорчать мир embedded. При переходе между stm8 и stm32 нужно менять IDE (TrueStudio на STVD). Во избежание таких курьёзов я пересаживаюсь на IAR. В процессе подключения родной библиотеки от ST, понимаю что библиотека от IAR для того же самого STM8L152C6T6 дико отличается (макросы, структуры). Привет веб-разработка. Как такое могло произойти, что под один и тот же контроллер ST даёт одну библиотеку, а IAR другую. И нигде в уроках тебя не предупредят об этом. Ну, ребят, у меня всего одна жизнь. Вы уже договоритесь там между собой? Придите к единому стандарту. Или они так решили новичков завендерлочить? Моё мнение (не претендует на правильное): пробираясь сквозь тернии популярной архитектуры ARM, инфраструктуры, инструментария, забываешь про бизнес-логику устройств. А еще просто пропасть между "я ничего не понимаю" и "господи, я зажег светодиод". Речь не о копипастерах с уроков, а действительно понимая что ты делаешь, в каком регистре, что меняешь. Это путь в 2000 (а то и больше) страниц на английском перечитанных по несколько раз, чтобы отоложилось. И в конце тебя ждут разные версии одной и той же библиотки в разных IDE. И сидишь вдупляешь... ну почему... я же в правильный регистр кладу правильную маску... ох, наболело. Такое ощущение что не для людей это всё делали, не для людей.
      Ваше мнение?
    • By megavolt3101
      Здравствуйте уважаемые форумчане. Пытаюсь связать два микроконтроллера по шине LIN. В качестве мастера выбрал контроллер STM8S103F3P6 (Его Usart умеет только LIN MASTER). В качестве ведомого выбрал STM8S208RBT6 (У него 2 Усарта, один из которых умеет быть ведомым LIN) Собрал на двух макетных платах. LIN трансивер TJA1020 Прием и передача работают нормально. Но как дошло дело до защиты от потери линии связи, тут возникли проблемы. После обрыва линии связи и ее восстановления связь возобновляется. Но вот после короткого замыкания шины LIN ведомое (SLAVE) устройство намертво виснет. Точнее виснет в обработчике прерывания от USART3. Я пытался принудительно очистить флаг приема по узарту (UART3_FLAG_RXNE) и флаг приема хедер байта (UART3_FLAG_LHDF). А также скидывал флаг брэйк байта (UART3_FLAG_LBDF). Ничего не помогает программа не возвращается из прерывания по приему от USART_3. Но зато если в этот момент с ведущего устройства снова подать команду, то работоспособность ведомого устройства восстанавливается. Тоже самое помогает, если в обработчике прерывания по USART_3 принудительно подать рандомную команду на передачу. То есть, так как линия одна, она сама свою же команду и принимает, получается. Вроде все нормально, но как то коробит такой колхозный способ защиты от короткого замыкания шины. Подскажите, может я забываю еще какой нибудь скинуть флаг при случае коротыша на линии LIN или есть еще каrой нибудь правильный способ обойти защиту от потери связи после кратковременного замыкания на шине. Надеюсь тут есть люди, которые что-то делали с шиной LIN ?

      Прилагаю инициализацию для мастер устройства 
      UART1_Init( 9600, UART1_WORDLENGTH_8D, UART1_STOPBITS_1, UART1_PARITY_NO, UART1_SYNCMODE_CLOCK_DISABLE, UART1_MODE_TXRX_ENABLE);
      UART1_LINBreakDetectionConfig( UART1_LINBREAKDETECTIONLENGTH_11BITS);
      UART1_ITConfig( UART1_IT_RXNE_OR, ENABLE);
      UART1_LINCmd( ENABLE);
      enableInterrupts();

      И для Ведомого устройства
      UART3_Init( 9600, UART3_WORDLENGTH_8D, UART3_STOPBITS_1, UART3_PARITY_NO, UART3_MODE_TXRX_ENABLE);
      UART3_LINConfig( UART3_LIN_MODE_SLAVE, UART3_LIN_AUTOSYNC_ENABLE,UART3_LIN_DIVUP_LBRR1);
      UART3_LINBreakDetectionConfig( UART3_LINBREAKDETECTIONLENGTH_11BITS);
      UART3_ITConfig( UART3_IT_RXNE_OR, ENABLE);
      UART3_ITConfig( UART3_IT_LBDF, ENABLE);
      UART3_ITConfig( UART3_IT_LHDF, ENABLE);
      UART3_LINCmd( ENABLE);
      enableInterrupts();

      А также обработчик прерывания для ведомого устройства
      //Обработчик прерывания для UART3.
      INTERRUPT_HANDLER( UART3_RX_IRQHandler, 21)
      {
      if( UART3_GetFlagStatus( UART3_FLAG_LHDF)){recUART3_Header=UART3_ReceiveData8(); UART3_ClearFlag(UART3_FLAG_LHDF);}
      if( UART3_GetFlagStatus( UART3_FLAG_RXNE)){recUART3_Data=UART3_ReceiveData8(); UART3_ClearFlag(UART3_FLAG_RXNE);}
      if( UART3_GetFlagStatus( UART3_FLAG_LBDF)){ UART3_ClearFlag( UART3_FLAG_LBDF);}
      if( UART3_GetFlagStatus(UART3_FLAG_OR_LHE)){UART3_SendData8(0x00);UART3_ClearFlag(UART3_FLAG_OR_LHE);}// Отправляю пустую команду через USART_3
      }
    • By Евгений61
      Здравствуйте! Помогите пожалуйста разобраться с заголовочным файлом.
      По идее pragma vector должен быть прописан в IOSTM8s003f3.h
      но там почему то не прописаны аектора внешних прерываний. Помогите!
      И еще вопросик. Как посмотреть что описано в "#define" файле. Может его можно самому написать.


      А В ДАТАШИТЕ ВЕКТОРА ЕСТЬ
       

×
×
  • Create New...