Jump to content
Sign in to follow this  
limbura

Прерывания

Recommended Posts

Приветствую всех!

Я только-только начал иметь иметь дело как с контроллерами, так и с ассемблером.

Пишу сейчас в Atmel Studio 6 для ATMega16. Чтобы получше разобраться, вбил я такой код:

.include "m16def.inc"

//-------------------------------
.CSEG

.ORG $000 ; (RESET)
RJMP Reset
.ORG $002
RETI ; (INT0) External Interrupt Request 0
.ORG $004
RETI ; (INT1) External Interrupt Request 1
.ORG $006
RETI		 ; (TIMER2 COMP) Timer/Counter2 Compare Match
.ORG $008
RETI ; (TIMER2 OVF) Timer/Counter2 Overflow
.ORG $00A
RETI		 ; (TIMER1 CAPT) Timer/Counter1 Capture Event
.ORG $00C
RETI ; (TIMER1 COMPA) Timer/Counter1 Compare Match A
.ORG $00E
RETI ; (TIMER1 COMPB) Timer/Counter1 Compare Match B
.ORG $010
RETI ; (TIMER1 OVF) Timer/Counter1 Overflow
.ORG $012
RETI ; (TIMER0 OVF) Timer/Counter0 Overflow
.ORG $014
RETI ; (SPI,STC) Serial Transfer Complete
.ORG $016
RJMP RX_OK ; (USART,RXC) USART, Rx Complete
.ORG $018
RETI ; (USART,UDRE) USART Data Register Empty
.ORG $01A
RETI ; (USART,TXC) USART, Tx Complete
.ORG $01C
RETI		 ; (ADC) ADC Conversion Complete
.ORG $01E
RETI ; (EE_RDY) EEPROM Ready
.ORG $020
RETI ; (ANA_COMP) Analog Comparator
.ORG $022
RETI ; (TWI) 2-wire Serial Interface
.ORG $024
RETI ; (INT2) External Interrupt Request 2
.ORG $026
RETI ; (TIMER0 COMP) Timer/Counter0 Compare Match
.ORG $028
RETI ; (SPM_RDY) Store Program Memory Ready

 .ORG INT_VECTORS_SIZE 	; Конец таблицы прерываний


RX_OK:	 IN R16,UDR		

 RETI			


Reset: LDI R16,Low(RAMEND)	
 OUT SPL,R16		

 LDI R16,High(RAMEND)
 OUT SPH,R16

 SEI			
 LDI R17,(1<<RXCIE)	
 OUT UCSRB,R17

M1:	 NOP			
 NOP
 NOP
 NOP
 RJMP M1

Начну с того, что команда SEI не меняет значение флага I регистра SREG.

Но это еще не все. Если забить и установить этот флаг вручную, то при установки флага прерывания RXC в регистре UCSRA ничего не происходит - на следующий же такт он сам возвращается в исходное состояние, а контроллер продолжает бегать циклом по NOP.

Что я забыл, что не так?

Share this post


Link to post
Share on other sites

Я не знаю, что там с SEI, но что ты забыл сделать - включить приёмник битом RXEN в том же регистре UCSRB :D .

У Вас же он отключен и никогда никакого прерывания Вам не сгенерит ...

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

Edited by hd44780

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-принтер и так далее...

Начну с того, что команда SEI не меняет значение флага I регистра SREG.

Плохо смотрели, всё меняет.


Никогда не спорьте с дураком - люди могут не заметить между вами разницы

Share this post


Link to post
Share on other sites

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

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

Подробнее

Я не знаю, что там с SEI, но что ты забыл сделать - включить приёмник битом RXEN в том же регистре UCSRB :D .

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

А на счет SEI, уж поверьте, не вру, но флаг I почему-то не хочет ставить.

Ума не приложу, что же может быть не так.

Попробую создать новый проект и заново написать код.

Share this post


Link to post
Share on other sites

Вебинар «Практическое использование TrustZone в STM32L5»(10.12.2020)

Приглашаем на вебинар, посвященный экосистеме безопасности и возможностях, которые появились у разработчиков благодаря новой технологии TrustZone в микроконтроллерах STM32L5. Программа рассчитана на технических специалистов и тех, кто уже знаком с основами защиты ПО в STM32.

Подробнее

limbura, вы же не думаете, что я вру? Я проверил именно ваш проект. После 6-го шага флаг I стоит, как вкопанный.

post-132912-0-35717200-1346674069_thumb.gif

Edited by Григорий Т.

Никогда не спорьте с дураком - люди могут не заметить между вами разницы

Share this post


Link to post
Share on other sites

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

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

Подробнее

Да нет, конечно не думаю, просто пытаюсь понять, почему же у меня та же самая программа не работает, а у вас работает?

В результате снес Atmel Studio 6 и поставил взамен AVR Studio 5.1

Все заработало как надо.

Толи встал криво, то ли разработчики поспешили с выпуском новой версии.

Edited by limbura

Share this post


Link to post
Share on other sites

Ещё раз убедился, что эмуляторы - зло.

Никогда их не любил. Какашка. Бр-р :D

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. 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...
Sign in to follow this  

  • Сообщения

    • есть формула, без любого значения для неё - никуда.
    • Вот это есть максимальное напряжение - без него никуда.    Я всё понимаю - но я сейчас не об этом.
    • выставлю то напряжение, до которого должен будет заряжаться конденсатор, тогда, например, при заряде стабильным током, можно будет получить время (тогда отношение времени заряда к паузе (во время паузы - разряд до нуля), будет определять ток который будет прямо пропорционален ёмкости, который можно измерить миллиамперметром, я встречал схемы измерителей ёмкости и индуктивности построенных на таком принципе). дельты - это не сомножители, а значки, их нельзя сократить.
    • Послушай Ёмкость - это количество заряда к напряжению.    Вверху есть формула - там для дураков написано.  Дельты сокращаем.  И получается чистый заряд на напряжение.   Это строгая формула.   А без сокращения более простая.  Там не написано дельта 1 и дельта 2 ,  это абсолютно одинаковые дельты.  Их написали чтобы более широко проилюстрировать процесс.    А можно и без них.   Просто формулу сделали более развёрнутую.   Вот и всё.
    • Это глупость, ты смешиваешь в кучу ЗАРЯД  конденсатора и его ЁМКОСТЬ, а это разные вещи. Если налить в ведро 5 литров воды, то ёмкость ведра так и останется 10 литров, а "заряд" в нём будет 5.
    • Выставишь пороговое - то есть макс.(я правильно понял)? Правильнее сказать что разные величины порогового напряжения при одном алгоритме измерения будут по разному влиять на результат.    Мы это уже и математически доказали и по всякому.    Ну что ты споришь?
    • нет не будет, ёмкость будет получатся одна и та же   выставив пороговое напряжение для компаратора, если буду задаваться напряжением, или длительностью (время) импульса заряда, если буду задаваться временем.

  • Набор из 276 компонентов для дремеля (бормашинки)

  • Similar Content

    • By LiSiY5
      Работаю в Mplab X 5.40, написал основной код программы для Pic16 на Си и есть небольшой код на ассемблере. Так вот, подскажите как правильно сделать переход на подпрограмму с Си на ассемблер и назад. Может на каком либо примере где-то есть. Заранее всем спасибо.
    • By Sambler
      У меня была похожая тема,  я решил проблему установив в include util/delay.h
      Но возникла еще одна ошибка, не могу понять, что оно хочет


      p.s. Я обещал, что предыдущая - последняя тема, но я ошибся, не думал, что тут 2 разные программы будут. В этот раз 100 процентов последняя тема и пойду сдавать работы Ы)

       

    • By Sambler
      Дана следующая программа и следующая схема.
      После запуска, циклично выдает одни и те же ошибка и до такой степени, что ПК не выдерживает нагрузку и приходится принудительно закрывать программу ( когда обычно, запустил программу и она не продолжает запускаться, а сразу указывает на ошибку в коде, а тут она даже не останавливается )
      При создании проекта выбираю WINAvr!!!



      Я не могу остановить симуляцию, приходится закрывать принудительно.
      Z
    • By Сергей Фомин
      Изучаю прерывания на attiny13. Пока остановился на прерываниях по переполнению. Сделал тестовый код в Atmel Studio и сразу через программатор заливаю на тиньку со светодиодом. Проблема в том что гореть он должен 10 секунд и выключаться, а горит примерно 20-23 секунды. Прошу помощи в правильном расчёте. Код ниже (пока учусь сильно не ругайтесь) :
      #define F_CPU 1000000 #define LED PB2 #include <avr/io.h> //#include <util/delay.h> #include <avr/interrupt.h> unsigned char work_time =384;    //  1000000/1024/256=3.8  (0.026 сек)    10/0.026=384 volatile unsigned char temp =0; ISR (TIM0_OVF_vect) {      TCNT0=0x00;     temp ++;     if (temp>=work_time)     {         PORTB &=~(1<<LED);  //Инвертируем состояние         TCCR0B=0x00    // остановка таймера         cli (); //общее запрещение прерываний     } } int main (void) {     init();               while (1)     {              } } void init () {          DDRB |= (1<<LED); // выход     PORTB =(1<<LED); //включен     TCCR0B =0x05; // установка делителя на 1024     TIMSK0 |= _BV(TOIE0);     sei();   // Либо SREG |= (1<<SREG_I); //Разрешаем прерывания глобально     TCNT0 = 0X00;        //Обнулить счётный регистр }  
    • By katet
      Добрый день. Может быть,кто-нибудь уже сталкивался с таким. 
      Занимаюсь доработкой чужого проекта в среде STM32CubeMX, первый раз работаю с библиотекой HAL.
      В этом проекте осуществлялся прием байт по USART1 из ComMon. Проект был открыт в STM32CubeMX, где мной дополнительно были активированы новые модули - RTC, SD, USART2. Настройки USART1 не менялись. 
      Часы реального времени RTC: питание от батарейки, тактирование – от LSE. 
      При приеме байт по USART1 в новом проекте (активны  USART1, RTC, SD, USART2) было выявлено, что после приема 2 байт по USART1 перестает инкрементироваться значение переменной uwTick, отвечающей за прерывания Systick, в результате чего дальнейшая отладка невозможна. Не удается выяснить, в каком месте и почему перестает увеличиваться значение uwTick. При работе со старым проектом (где активен только USART1) uwTick инкрементируется после приема 2 байт.
      Смены приоритета прерываний не происходит, в  функцию HAL_Delay() отладчик не попадает. При вызове функции HAL_ResumeTick(), возобновляющей прерывания Systick, ничего не меняется, значение uwTick остается неизменным.
      Остановка прерываний была обнаружена при попадании в функцию:
      static HAL_StatusTypeDef UART_WaitOnFlagUntilTimeout(UART_HandleTypeDef *huart, uint32_t Flag, FlagStatus Status, uint32_t Tickstart, uint32_t Timeout)
      {
        /* Wait until flag is set */
        while((__HAL_UART_GET_FLAG(huart, Flag) ? SET : RESET) == Status) 
        {
          /* Check for the Timeout */
          if(Timeout != HAL_MAX_DELAY)
          {            
            if((Timeout == 0U)||((HAL_GetTick() - Tickstart ) > Timeout))
            {
              /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */
              CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE));
              CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
              
              huart->gState  = HAL_UART_STATE_READY;
              huart->RxState = HAL_UART_STATE_READY;
              
              /* Process Unlocked */
              __HAL_UNLOCK(huart);
              
              return HAL_TIMEOUT;
            }
          }
        }
        
        return HAL_OK;
      }
      В новом проекте текущее значение uwTick, возвращаемое функцией HAL_GetTick(), всегда равно значению Tickstart. В старом проекте сначала также, но затем uwTick начинает увеличиваться. Выяснить, в каком именно месте кода значение uwTick должно начать увеличиваться, не удается.
      Может быть, у кого-нибудь есть хоть какие-то идеи, с чем может быть связана остановка увеличения значений uwTick, помогите пожалуйста)
      Распиновка и конфигурация обоих проектов: верхняя часть рисунков - первоначальный, работающий вариант,  нижняя - сбой прерываний Systick.


×
×
  • Create New...