Jump to content
Pragmatik91

Прерывания По Таймеру И Внешнему Сигналу

Recommended Posts

Значит тема такая: Программа формирования ШИМ сигнала с коэффициентом заполнения 0,4 и 0,6, задаваемым по внешнему прерыванию от двух сигналов, и с периодом 5 кГц. ШИМ сигнал формируется по прерыванию от таймеров. Я написал программу по прерыванию от внешнего сигнала, но прерывание по таймеру не могу написать. Вот программа работающая, но в которой нет прерывания по таймеру:

TIME EQU -(200)
JMP START
ORG 20H
START:
MOV IE,#10000101B ;установка битов регистра разрешения прерываний
CALL SETUPTIMER   ;настройка таймера
MOV R1,#-126
MOV R2,#-40
MOV TCON,#00000101B ;разрешение внешних прерываний по низкому уровню сигнала
JMP TIM
TIM:
CALL FORM  ;подпрограмма формирования сигнала
JMP TIM    ;зациклить на выводе
SETUPTIMER:
MOV  TMOD,#00000001b ;установка таймера в режим 1
MOV P0,#0    ;сброс порта ввода-вывода
RET
DELAY1:
MOV  TH0,#11111111B ;настройка таймера
MOV  TL0,R1
SETB TR0    ;запуск таймера
JNB  TF0,$   ;ожидание переполнения
CLR  TF0    ;сброс флага переполнения
CLR  TR0    ;остановка таймера
RET
DELAY2:
MOV  TH0,#11111111B
MOV  TL0,R2
SETB TR0   
JNB  TF0,$  
CLR  TF0   
CLR  TR0
RET
FORM:
MOV P0,#200  ;вывод точки в порт
CALL DELAY1  ;вызов п/п задержки на высоком уровне
MOV P0,0  ;вывод в порт точки низкого уровня
CALL DELAY2  ;вызов п/п задержки на низком уровне
RET
ORG 0003H  ;адрес источника прерывания INT0
CLR TR0   ;остановка таймера
CLR EA   ;запрет прерываний
MOV R1,#-45
MOV R2,#-120
SETB EA   ;разрешение прерываний
SETB TR0  ;запуск таймера
RETI   ;возврат из п\п прерывания
ORG 0013H  ;адрес источника прерывания INT1
CLR TR0
CLR EA
MOV R1,#-126
MOV R2,#-40
SETB EA
SETB TR0
RETI
END

Как изменить ее так, чтобы вместо подпрограмм задержек по таймеру включалась п\п прерывания?

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

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

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

Подробнее

В общем сделал я ее :) Вот код

org 0h
JMP start
org 03h    ;прерывание по INT0
jmp int0_ok
org 0bh    ;прерывание по таймеру 0
clr tr0    ;остановка таймера 0
jnb p1.0,int0_ok
jb p1.0,int0_ok
org 13h    ;прерывание по INT2
jmp int1_ok
org 1bh    ;прерывание по таймеру 1
clr tr1    ;остановка таймера 1
jnb p1.0,int1_ok
jb p1.0,int1_ok
start:
 mov TCON,#00000101b   ;установка битов управления внешними прерываниями
 mov IE,#10001111b   ;настройка битов регистра разрешения прерываний
 mov TMOD,#00010001b   ;настройка режима работы таймеров
 mov r0,#-126    ;задержка
 mov r1,#-40
 jmp $	 
int0_ok:
 clr tr0	   ;остановка таймера
 jnb p1.0,my4	 ;пауза или импульс
 mov  TH0,#11111111B   ;загрузка на отсчет
 mov  TL0,r0	 ;паузы
 clr p1.0	  ;сброс бита порта
 jmp my5	  
my4:
 mov  TH0,#11111111B ;загрузка на отсчет
 mov  TL0,r1   ;импульса
 setb p1.0	 ;установка бита порта
my5:
 setb  tr0    ;запуск таймера 0
reti	  ;возврат из п\п прерывания
int1_ok:
 clr tr0
 jnb p1.0,my41
 mov  TH1,#11111111B
 mov  TL1,r1
 clr p1.0
 jmp my51
my41:
 mov  TH1,#11111111B
 mov  TL1,r0
 setb p1.0 
my51:
 setb  tr1
reti
end

Share this post


Link to post
Share on other sites

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

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

Подробнее

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

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

Подробнее

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...

  • Сообщения

    • Вы даты сообщений то смотрите. Автор уж давно всё получил, запустил бизнес, разорился и уехал выращивать тыквы на Дальний Восток.
    • А мы рассматриваем случай когда всё имеет фиксированные величины кроме результата и напряжения в процессе многократных рассчётов(то есть фактически тогда, когда все переменные кроме напряжения и результата имеют фиксированные значения в процессе многократных расчётов).  Ты же понимаешь о чём я - просто издеваешься.    Это - такая простота.
    • В инструкции к любому прибору, претендующему на точность, всегда оговариваются условия эксплуатации, в т.ч. и температура окружающей среды. Даже к "детскому" осциллографу ОМЛ-3, емнип, была оговорка, что перед измерениями его нужно прогреть в течении нескольких минут. А на более серьёзных приборах критически важные узлы вообще заключены в изолированный бокс с термостатированием и индикацией готовности. Поэтому, если уши вянут от холодного звука - просто греть предварительно.
    • если изменить пороговое напряжение, то время заряда, до этого напряжения, пропорционально изменится. 
    • Ну ты играешься словами.  Если всё будет одинаковое кроме напряжения то результат будет другим.  Не будь - ребёнком.
    • Всяко бывает. Везде люди работают разные и реагируют на обращения по разному, попадаются, конечно и ленивые уроды.  А вот если строчить посты на форумах, заниматься придумыванием всяких "своих нулей", вместо того, чтобы пинать электросети, то уж точно никто не приедет и не починит. Под лежачий камень вода не течёт.
    • да, результат будет один, если ты вместо 10 подставишь 20, то тогда во столько же раз изменится время, за которое зарядится конденсатор до этого напряжения, и результат - ёмкость не изменится. Это же ясно из формулы определения ёмкости.

  • Сенсорный дисплей 3.5" для Raspberry Pi. 480*320 точек

  • Similar Content

    • By Nosi Usi
      Добрый день. Подскажите пожалуйста, как бы мне реализовать схему автоотключения (забытого включенного света). 
      Что есть: 12v аккумулятор, LED-лента, выключатель. Хочу собрать схему, при которой питание на LED-ленту будет подаваться не более чем N-минут. 
      Всё что находил - это схемы через мосфет и конденсатор но с тач-кнопкой, это не совсем то, т.к. необходимо срабатывание "таймера" при замыкании цепи и отключение таймера и света при размыкании цепи. Желательно, что бы потребление схемы было минимальным, а в идеале - размыкание всей цепи по таймеру.
       
    • 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.


    • By IgnatiusF
      Не могу настроить таймер 0 на работу, и даже не получается понять в чем проблема. Делаю в Proteus, так как это быстрее и нагляднее.
      Пробовал и просто по переполнению делать прерывание (WGM[1..0]  00) и по совпадению (WGM[1..0]  10; OCR0A = 0 - 255), однако прерываний нет. Перед циклом ставлю TCNT0 = 0;
      Тактирование выставляю TCCR0B (CS[2..0] 001, 100, 101).
      Прерывания TIMSK0 (OCIE0A, TOIE0) выставляю, не вызываются. Даже принудительным заносом значения в регистр TIFR0 (OCF0A, TOV0).
      Прерывание пытаюсь выполнить таким образом:
      #include <avr/interrupt.h> volatile unsigned int A = 0; ISR(TIMER0_OVF_vect) { A = 1; } ... while(1) { if (A == 1) PORTB |= (1<<0); } Proteus показывает, что вывод настроен как выход, но всегда 0;
      Конкретный код привести не могу, так как у меня не заработало совсем ничего.
      Внизу я сделал вырезку из даташита на ATMEGA328 по 0 таймеру 8-бит, и занес в один PDF файл.
      ATmega328-106-112.pdf
      Прошу помочь разобраться с таймером и прерываниями для него.
×
×
  • Create New...