0 / 0 / 0
Регистрация: 02.03.2016
Сообщений: 90
1

Прерывания программ микроконтроллеров, создаваемых в Atmel Studio 6.0

02.03.2016, 18:50. Показов 7589. Ответов 47
Метки нет (Все метки)

Я недавно начал осваивать микроконтроллеры и пока еще тока сумел освоить работу с портами ввода/вывода. Сейчас начал пытаться создать программы с использованием функций прерывания. Сначала я пробовал создавать программы используя программу CodeVisionAVR, а сейчас перешел на Atmel Studio 6.0 для проверки работы созданного проекта программы использую Proteus VSM. Когда я создал простую программу с использованием внешних прерываний в CodeVisionAVR то проверка в Proteus VSM дала положительный результат, а скопировав этот код (с небольшой корректировкой) в Atmel Studio 6.0 компиляция проходила без ошибок, а при проверке в Proteus VSM не было результата.
Код из CodeVisionAVR:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
/*****************************************************
    Project : Ext_INT0_Knopka_1
    Version : 1.0
    Date    : 16.08.2015
    Author  : Grey_vsm
    Company : Home_Group
    Comments: 
             Переключение светодиода по
          внешнему прерыванию от кнопки
  *****************************************************/
 
    #include <mega8.h>
   //#include <delay.h>
    
  //-----Prototips Function------------------------------------------------------
      void Init_MK (void); //Прототип функции инициализации МК
  //-----------------------------------------------------------------------------
 
  // Declare your global variables here
    int PD2=0;
  //=============================================================================
    void Init_MK (void)
       {    PORTB=0x02;
            DDRB=0x02;
 
            PORTC=0x00;
            DDRC=0x00;
 
            PORTD=0x04;
            DDRD=0x00;
        
 
 
        // External Interrupt(s) initialization
        // INT0: On
        // INT0 Mode: Rising Edge
        // INT1: Off
            GICR|=0x40;
            MCUCR=0x03;
            GIFR=0x40;
         }  
 
  // External Interrupt 0 service routine
    interrupt [EXT_INT0] void ext_int0_isr(void)
      {
        // Place your code here
        PD2=~PD2;
        }
 
    void main(void)
       {
         Init_MK ();
         #asm("sei")
 
         while (1)
            {
             // Place your code here
             if (PD2)
               {
                PORTB.1=~PORTB.1;
                PD2=~PD2;
                }
              };
         }
А вот код который получился Atmel Studio 6.0
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
/* Ext_INT0_Knopka_1.cpp
 * Created: 29.02.2016 14:36:38
 *  Author: Grey-vsm
 */ 
 
#define F_CPU 8000000
#include <avr/io.h>
#include <avr/interrupt.h>
 
//-----Prototips Function------------------------------------------------------
void Init_MK (void); //Прототип функции инициализации МК
//-----------------------------------------------------------------------------
 
// Declare your global variables here
int T;
//=============================================================================
void Init_MK (void)
   {    PORTB=0xFF;
    DDRB=0xFF;
    
    PORTC=0x00;
    DDRC=0x00;
 
    PORTD=0x04;
    DDRD=0x00;
    
    MCUCR &= ~((1<<ISC11)|(1<<ISC10)|(1<<ISC01)|(1<<ISC00));   // Сбрасываем все биты ISCxx
    MCUCR &=((1<<ISC01)|(1<<ISC00));   // Настраиваем на срабатывание INT0 по переднему фронту
    GICR |=(1<<INT0);   // Разрешаем внешнее прерывание INT0
    sei();   // Выставляем флаг глобального разрешения прерываний
    } 
    
    // External Interrupt 0 service routine
    ISR (INT0_vect)
    {
        T=~T;
    }   
    
int main(void)
  {
   Init_MK ();
  T=0;
    while(1)
    {
      if (T==1)
      {
       //PORTB.1=~PORTB.1;
       PORTB^=((1<<5)|(1<<3)|(1<<1));
       T=~T;
      }
     }
   }
Я сегодня целый день искал в интернете подходящее описание синтаксиса создаваемой функции внешнего прерывания, но везде были одинаковые варианты, которые я и попытался применить, но в Proteuse программа так и не захотела работать. Подскажите пожалуйста, что у меня не так, заранее благодарен за помощь!
__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
02.03.2016, 18:50
Ответы с готовыми решениями:

Atmel Studio 6.1 прерывания
Здравствуйте! Недавно приступил к изучению Atmel Studyo 6.1! Пока пишу на Assemdlere.Возникла такая...

Atmel Studio 7 AVR и прерывания по умолчанию
Установил я Atmel Studyo 7 и обнаружил следующие, если прерывание объявленно, а обработка прервыная...

Отладка программ созданных в Atmel Studio 6.0
Я пытаюсь программы созданные в AVR Studio 6.0 отлаживать в пошаговом режиме, для просмотра...

Текущая стоимость микроконтроллеров atmel
Мне как новичку интересно те цены котоые я вижу в нигазине на микроконтроллеры этой фирмы в данный...

47
1961 / 1275 / 130
Регистрация: 04.01.2010
Сообщений: 4,607
02.03.2016, 21:57 2
это потому что программы под avr написанные в CV AVR и Atmel Studio не совместимы.
C
1
MCUCR &=((1<<ISC01)|(1<<ISC00)); // Настраиваем на срабатывание INT0 по переднему фронту
Наверное, вы хотели написать:
C
1
MCUCR |=((1<<ISC01)|(1<<ISC00)); // Настраиваем на срабатывание INT0 по переднему фронту
1
0 / 0 / 0
Регистрация: 02.03.2016
Сообщений: 90
03.03.2016, 09:52  [ТС] 3
Спасибо за ответ, возможно я действительно ошибся с символом логической операции, сейчас обязательно попробую это исправить.

Добавлено через 24 минуты
Я извиняюсь, но после исправления логической операции И на |= проверка в Proteuse результата не дала, я уже не знаю где еще можно искать ошибку в программе, если тока это глюк самой Studio.
0
Модератор
Эксперт по электронике
8278 / 4182 / 1595
Регистрация: 01.02.2015
Сообщений: 13,004
Записей в блоге: 3
03.03.2016, 10:02 4
А в результате таких действий
C++
1
2
3
4
5
6
7
8
T=0;
while(1)
{
if (T==1)
{
//.....................
T=~T;
}
В переменной T будут чередоваться значения 0x0000 и 0x0001?
0
1961 / 1275 / 130
Регистрация: 04.01.2010
Сообщений: 4,607
03.03.2016, 10:05 5
объявите переменную T как
C
1
unsigned char volatile T;
Что показывает отладчик ассемблера в протеусе? Контролле вообще входит в прерывание?

Добавлено через 1 минуту
Цитата Сообщение от ФедосеевПавел Посмотреть сообщение
В переменной T будут чередоваться значения 0x0000 и 0x0001?
не будут. Но ошибка там действительно есть. Потому что в момент выполнение по условия может сработать еще одно прерывание, которое снова "перевернет" флаг. В итоге получится двойное срабатывание события.
1
0 / 0 / 0
Регистрация: 02.03.2016
Сообщений: 90
03.03.2016, 11:10  [ТС] 6
Вопрос Voland-у: во-первых уточните пожалуйста почему не подходит "int T;", а вы рекомендуете "unsigned char volatile T;", для Использование в будущем. А во вторых подскажите как вызвать отладчик в Proteuse (этот отладчик может быть тока на ассемблере или на Си его тоже можно включить), и как отследить вход в функцию прерывания. С протеусом я еще тоже тока начал знакомится поэтому знаю не все его возможности. А вход в функцию прерывания я пытался отследить в Studio в пошаговом режиме но этот режим становился неактивным после одного оборота цикла while(1) и я не мог определить заходит он в функцию прерывания или нет.
0
1961 / 1275 / 130
Регистрация: 04.01.2010
Сообщений: 4,607
03.03.2016, 11:18 7
Цитата Сообщение от grey-vsm Посмотреть сообщение
точните пожалуйста почему не подходит "int T;"
ключевое здесь "volatile". Эта директива заставляет компилер использовать постоянное чтение/запись переменной в/из памяти. При использовании такой глобальной переменной в прерываниях это имеет архиважное значение, т.к. иначе (как раз как в вашем случае) обновление значения переменной в прерывании может не учитыватья в главном цикле main(). Что касается int vs char - у вас 8ми-битный контроллер в руках. Это значит, что любые операции с 16тибитным числом займут раза в 2-2,5 больше инструкций по сравнению с 8ми-битной. Мало того, у AVR есть побитовые инструкции работы и условий, поэтому, объявление "bit volatile T;" будет еще более предпочтительнее, т.к. линкер в потенциале может группировать подобные переменные в одну байтовую группу битовых(булевых) переменных.

Цитата Сообщение от grey-vsm Посмотреть сообщение
подскажите как вызвать отладчик в Proteuse (этот отладчик может быть тока на ассемблере или на Си его тоже можно включить)
я использовал брейпоинты в Протеусе и АСМ-овский дизассемблер. Это встроеннная в него функция. В момент запуска симуляци вы можете нажать на паузу и открыть код. Да, не идеально удобно, но возможно, тем не менее.
1
Модератор
Эксперт по электронике
8278 / 4182 / 1595
Регистрация: 01.02.2015
Сообщений: 13,004
Записей в блоге: 3
03.03.2016, 11:32 8
grey-vsm, как вы контролируете выполнение прерывания? По переменной Т? Тогда ещё раз проверьте, чему будет равно значение Т после
C++
1
2
  T=0;
  T=~T;
Неужели T==1?

Добавлено через 6 минут
Плюс. После завершения обработки прерывания (в самом обработчике), нужно сбросить флаги прерываний (так для AtTiny2313):
C++
1
  EIFR   = (1<<INTF0);
1
0 / 0 / 0
Регистрация: 02.03.2016
Сообщений: 90
03.03.2016, 12:01  [ТС] 9
Ну а как в Протеусе можно отследить значение переменной Т, и как там включать дизассемблер.

Добавлено через 5 минут
А после завершения обработки прерывания флаги прерываний разве не сбрасываются автоматически при выходе из функции, или строчки сброса этих флагов при выходе обезательно нужно прописывать самому?
0
1961 / 1275 / 130
Регистрация: 04.01.2010
Сообщений: 4,607
03.03.2016, 12:27 10
ФедосеевПавел, слона-то я и не приметил )).
Цитата Сообщение от grey-vsm Посмотреть сообщение
нужно прописывать самому?
почитайте ДШ для своего чипа. Есть прерывания, которые надо сбрасывать вручную, либо другими способами, типа вычитки данных из какого-то регистра.
0
0 / 0 / 0
Регистрация: 02.03.2016
Сообщений: 90
03.03.2016, 14:19  [ТС] 11
Поискав в файлах описания программы Proteus, я нашел описание режима отладки, там написано, что начать отладку можно нажав клавиши CTRL+F12, должны появиться два всплывающих окна, но у меня не появляется ни одного. Далее написано, если они не появляются их можно активировать из меню Debug, выбрать нужно CPU Source Code и CPU Registers. Но у меня в этом меню из этих двух пунктов есть тока CPU Registers, а другого нет, как же я тогда могу провести отладку программы если окно с исходным кодом программы не активируется.
0
1961 / 1275 / 130
Регистрация: 04.01.2010
Сообщений: 4,607
03.03.2016, 14:54 12
... я так вспоминаю, окна доступны из контекстного меню к МК в Протеусе в момент паузы эмуляции. В другие моменты окна не доступны.
0
0 / 0 / 0
Регистрация: 02.03.2016
Сообщений: 90
03.03.2016, 17:33  [ТС] 13
По поводу контроля значения переменной Т, я в текст программы в главную функцию main(), я решил записывать это значение в порт С.
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
    int main(void)
     {
      Init_MK ();
      T=0;
       while(1)
         {
          PORTC=T;
          if (T==1)
            {
             PORTB ^=((1<<5)|(1<<3)|(1<<1));
             T=~T;
             }
          }
     }
В остальном осталось все без изменений. И хотел-бы на картинках показать результат. Я добавлю две картинки Ris_1 и Ris_2. На первом рисунке работа схемы после запуска, а на втором работа после нажатия на кнопку. После очередного нажатия кнопки схема выглядит также как на первом рисунке, итак и далее повторяется.
Миниатюры
Прерывания программ микроконтроллеров, создаваемых в Atmel Studio 6.0   Прерывания программ микроконтроллеров, создаваемых в Atmel Studio 6.0  
0
0 / 0 / 0
Регистрация: 02.03.2016
Сообщений: 90
03.03.2016, 17:39  [ТС] 14
Ни как не могу понять почему PortB не меняет своего состояния
0
Модератор
Эксперт по электронике
8278 / 4182 / 1595
Регистрация: 01.02.2015
Сообщений: 13,004
Записей в блоге: 3
03.03.2016, 17:47 15
Упёртый до смешного, grey-vsm. Я уже не буду третий раз подсказывать, почему не выполняется Т==1. Это ваша беда - неумение читать.
0
0 / 0 / 0
Регистрация: 02.03.2016
Сообщений: 90
03.03.2016, 18:16  [ТС] 16
Я не упертый, а всего навсего использую свои знания языка программирования Си. А Т==1 у меня это условие выполнения оператора ветвления if(условное_выражение). Или в программе Studio условие записывается как то иначе?
0
Модератор
Эксперт по электронике
8278 / 4182 / 1595
Регистрация: 01.02.2015
Сообщений: 13,004
Записей в блоге: 3
03.03.2016, 18:32 17
При T=0 после T=~T в переменной T будет 0xFF.
Что мешает написать
C++
1
2
3
4
  if (T)
  {
  ............
  }
1
0 / 0 / 0
Регистрация: 02.03.2016
Сообщений: 90
03.03.2016, 18:45  [ТС] 18
Спасибо такой вариант помог, но все-таки мне непонятно а чем не устраивал вариант Т==1, ведь это по правилам языка Си
0
Модератор
Эксперт по электронике
8278 / 4182 / 1595
Регистрация: 01.02.2015
Сообщений: 13,004
Записей в блоге: 3
03.03.2016, 18:55 19
После возникновения прерывания в переменной Т значение становилось равным то 0х00, то 0хFF, но никогда 0х01.
Хотя бы поэтому.
И "добро пожаловать в С". В этом языке принято, что значение 0 - ложь, а не ноль - истина. Там ещё много чего, в том числе и ошибки вида if (T=1) - присваивание вместо сравнения.
В общем "Хулиган Ритчи" в помощь (в смысле Керриган и Ритчи "Язык программирования С").
1
0 / 0 / 0
Регистрация: 02.03.2016
Сообщений: 90
03.03.2016, 19:07  [ТС] 20
Ну вообще-то if (T=1) я бы и не написал, т.к. язык Си я начал изучать еще в институте, но только мы там с переменными в которые записываются двоичные и шеснадцатиричные числа не использовали поэтому с такими числами у меня нет опыта работы.
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
03.03.2016, 19:07
Помогаю со студенческими работами здесь

Ассемблер для микроконтроллеров Atmel AVR
Всем приветы, люди кто может помочь с написанием программки на ассемблере для микроконтроллеров...

Ищем инженера-программиста микроконтроллеров для Atmel 8-bit ARM
Для поддержки устройств GPS мониторинга транспорта нужен программист микроконтроллеров для Atmel...

Прерывания по таймеру на Arduino Due (Atmel SAM3X8E)
Каким образом можно организовать прерывание по таймеру на Arduino due(sam3x8e)? Стандартные...

Почему AVR Studio 4, а не Atmel Studio 6?
По какой причине большинство специалистов по AVR микроконтроллерам в основном используют AVR Studyo...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2023, CyberForum.ru