С Новым годом! Форум программистов, компьютерный форум, киберфорум
Микроконтроллеры ATmega AVR
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.80/5: Рейтинг темы: голосов - 5, средняя оценка - 4.80
0 / 0 / 0
Регистрация: 09.03.2011
Сообщений: 18
1

Где ошибка с прерыванием по захвату и приемом сигнала?

19.05.2015, 20:23. Показов 855. Ответов 12
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Подскажите пожалуйста, почему у меня во время прерывания по низсходящему импульсу не срабатывает условие else в прерывании... код программы прилагаю... Уже всю голову сломал и 10 раз переделал программу,а результата нет... Спасибо за помощь...
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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#include <mega8.h>
unsigned char all_data[200][3];
unsigned char otricatH, pologH, regim_priema, i,j, data[3],counter1;
unsigned char counter = 0;
// Timer1 input capture interrupt service routine
interrupt [TIM1_CAPT] void timer1_capt_isr(void)
{
if (TCCR1B&(1<<6)){
TCCR1B&=0b10111111;
//otricatH = ICR1H;
//otricatL = ICR1L;
all_data[counter][0]=0x01;
all_data[counter][1]=ICR1L;
all_data[counter][2]=ICR1H;
TCNT1L=0;
TCNT1H=0;
ICR1L=0;
ICR1H=0;
counter++;
         }
else
{
TCCR1B|=0b01000000;
// pologH = ICR1H;
//pologL = ICR1L;
all_data[counter][0]=0x02;
all_data[counter][1]=ICR1L;
all_data[counter][2]=ICR1H;
TCNT1L=0;
TCNT1H=0;
ICR1L=0;
ICR1H=0;
counter++;
}
if (PINB.1==1){
PORTB.1=0;}
else {PORTB.1=1;}
if (counter==200){counter=0;}
}[/size][/font][/color]
// Declare your global variables here
[color=#000000][font=tahoma][size=2]void main(void)
{
PORTB=0x00;
DDRB=0xFE;
PORTB.2=1;
TCCR1A=0x00;
TCCR1B=0x41;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
TIMSK=0x20;
ACSR=0x80;
SFIOR=0x00;
ADCSRA=0x00;
SPCR=0x00;
TWCR=0x00;
#asm("sei")
regim_priema = 0;
counter1 = 0;
while (1)
         {
 
         switch(regim_priema) {
         case 0:
                 if (all_data[counter1][0]==0){
                         counter1++;
                         break;}
                 else {
                         if ((all_data[counter1][1]>0b00110000)&&(all_data[counter1][1]<0b00111000)){
                         regim_priema=1;}}              
                 counter1++;    
                
                 //pologH==0b00110010&&otricatH==0b00011001){
                 //regim_priema=1;}
                 //break;
         case 1:
                 for (i=0;i<2;i++){
                         for (j=0;j<8;j++){
                                 if (pologH==0b00100101&&otricatH==0b00001100){
                                         data[i]|=(1<<j);}
                                 if (pologH==0b00001100&&otricatH==0b00100101){
                                         data[i]&=~(1<<j);}
                                 }
                         }
                 regim_priema=3;
                 break;
         case 3:
                         if (pologH==0b00011001&&otricatH==0b00110010){
                         regim_priema=0;}
                         //break;}
                         }
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
19.05.2015, 20:23
Ответы с готовыми решениями:

Как работать с приемом сигнала
Здравствуйте,ни как не пойму как работать с сигналами в си, а именно прием сигнала. #include...

Помогите разобраться приёмом сигнала с ПДУ на TSOP.
Использую м.к. stm32f051, IDE - CoIDE. Запускаю отладку, первое срабатывает прерывание по EXTI,...

Ошибка с прерыванием
Здравствуйте. При вводе в программу (mega 128, AVR Studyo 4): ldi...

Ошибка в коде с прерыванием 21h
Добрый день, помогите найти решение проблемы, мне необходимо найти файл по заданным условиям, я...

12
1978 / 1276 / 131
Регистрация: 04.01.2010
Сообщений: 4,607
19.05.2015, 22:35 2
...хороший вопрос ). Предположу, что вы не совсем полно описываете ситуацию. В ДШ сказано:
This flag is set when a capture event occurs on the ICP1 pin. When the Input Capture Register
(ICR1) is set by the WGM13:0 to be used as the TOP value, the ICF1 Flag is set when the counter
reaches the TOP value.
(стр.101) и
Bit 5 – TICIE1: Timer/Counter1, Input Capture Interrupt Enable
When this bit is written to one, and the I-flag in the Status Register is set (interrupts globally
enabled), the Timer/Counter1 Input Capture Interrupt is enabled. The corresponding Interrupt
Vector (see “Interrupts” on page 46) is executed when the ICF1 Flag, located in TIFR, is set.
это по идее означает, что прерывание это вызывается не только при фронтах и спадах на ноге с копированием значения счетчика в ICR1, но и вызывается при переполнении таймера. Поэтому, однозначно нельзя сказать - вызвано ли прерывание от фронт/спада или по достижению TOP-значения.

Добавлено через 2 минуты
ЗЫ: как решение, я бы предложил либо внешнюю переменную, в которой сохранять реальное условие вызова прерывания и проверять счетчик, либо сделать проверку реального состояния входного пина прямо в вызове прерывания. Если пин равен нулю, значит мы поймали спад. Если единица - то поймали фронт ).
1
0 / 0 / 0
Регистрация: 09.03.2011
Сообщений: 18
19.05.2015, 23:02  [ТС] 3
Спасибо за ответ...
Вы имели ввиду такое решение? Код функции прерывания... Только все равно какой сигнал только на выход я не подавал, то при низсходящем импульсе в all_data[counter][0] никак не записывается 0x02... НЕ могу понять где я так жестко туплю...
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
if (PINB.0==1)
 //(TCCR1B&(1<<6))
 {
   TCCR1B&=0b10111111; 
   //otricatH = ICR1H;
   //otricatL = ICR1L;
   all_data[counter][0]=0x01;
   all_data[counter][1]=ICR1;
   all_data[counter][2]=ICR1;
   TCNT1L=0;
   TCNT1H=0;
   ICR1L=0;
   ICR1H=0;  
   counter++;
      }
else
    {
    TCCR1B|=0b01000000;
   // pologH = ICR1H;
    //pologL = ICR1L;
    all_data[counter][0]=0x02;
    all_data[counter][1]=ICR1;
    all_data[counter][2]=ICR1;
    TCNT1L=0;
    TCNT1H=0;
    ICR1L=0;
    ICR1H=0;
    counter++;
    }
0
1978 / 1276 / 131
Регистрация: 04.01.2010
Сообщений: 4,607
20.05.2015, 09:29 4
lancer5610, читайте мануалы. Например, стр.86 ДШ:
Measurement of an external signal’s duty cycle requires that the trigger edge is changed after
each capture. Changing the edge sensing must be done as early as possible after the ICR1
87
8159D–AVR–02/11
ATmega8A
Register has been read. After a change of the edge, the Input Capture Flag (ICF1) must be
cleared by software (writing a logical one to the I/O bit location). For measuring frequency only,
the clearing of the ICF1 Flag is not required (if an interrupt handler is used).
Это значит, что сначала вычитывается ICR1, затем вы меняете полярность срабатывания прерывания, а затем уже сбрасываете флаг ICF1.
Как раз скорее из-за того, что вы не сбрасываете флаг, и не срабатывает прерывание по спаду у вас.

Займитесь отладкой.
1) Убедитесь что вход работает изначально по фронту и по спаду в отдельности. То есть один раз запустите срабатывание по фронту, второй раз - по спаду.
2) Убедитесь, что прерывание срабатывает повторно. То есть срабатывает больше одного раза при любом из выбранных фронт/спадов.
3) Добавьте в код функциональность смены режима сработки прерывания согласно приведенному (из ДШ) выше принципу.
4) Убедитесь, что входной сигнал соответствует требованиям по производительности. Часто случается, что срабатывание сигнала происходит быстрее, чем МК может его обработать. Пользуйтесь аппаратными и программными средствами по отслеживанию шума.
0
0 / 0 / 0
Регистрация: 09.03.2011
Сообщений: 18
23.05.2015, 22:54  [ТС] 5
Разбирался с кодом... вот маленький пример...
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
if (TCCR1B&(1<<6)){
 all_data[counter][1]=ICR1;
 TCCR1B&=0b10111111;
 TIFR&=(1<<5);
 all_data[counter][0]=0x01;
 TCNT1=0;
 counter++;
     }
else
   {
   all_data[counter][1]=ICR1;
   TCCR1B|=0b01000000;
   TIFR&=(1<<5);
   all_data[counter][0]=0x02;    
   TCNT1=0;
  counter++;
Так вот... если закоментировать строчки "counter++;" то все работает, а как только делаю их активными, то все перестает работать... ПОчему?
0
6770 / 2739 / 384
Регистрация: 17.02.2013
Сообщений: 4,048
23.05.2015, 23:40 6
Очевидно, потому, что когда counter становится слишком большим, то твой обработчик прерывания начинает писать за пределами массива и что-нибудь там затирает.
0
0 / 0 / 0
Регистрация: 09.03.2011
Сообщений: 18
24.05.2015, 08:49  [ТС] 7
нет, counter не становиться слишком большим... в прерывании идет проверка его :
C
1
if (counter==199) counter=0;
и даже если бы становился слишком большим, то хоть бы какието данные записались бы, а так получаеться, что в all_data вообще ничего не записываеться...
0
1280 / 1185 / 175
Регистрация: 02.12.2013
Сообщений: 4,883
24.05.2015, 09:46 8
Цитата Сообщение от lancer5610 Посмотреть сообщение
if (counter==199) counter=0;
Я бы вот так написал
C
1
if (counter >= 199) counter=0;
0
0 / 0 / 0
Регистрация: 09.03.2011
Сообщений: 18
24.05.2015, 21:27  [ТС] 9
Пускай будет и так, только от этого все равно не меняеться ничего...
0
6770 / 2739 / 384
Регистрация: 17.02.2013
Сообщений: 4,048
24.05.2015, 23:04 10
А зачем у тебя в главном цикле программы при case 0 делается counter1++ вне зависимости от того приняты данные alldata[0] или не приняты ? И до каких значений counter1 добегает ?

Вообще, у тебя программа написана коряво и так и работает. Пока не перепишешь ее просто, ясно и безупречно, она так и будет работать, хоть как ее крои. Принимаемые данные должны складываться в кольцевой буфер. У буфера должен быть указатель на голову и хвост. Обработчик прерывания данные в буфер складывает, продвигая по кольцу голову. Головная программа выгребает, пододвигая к голове хвост. Если обработчик прерывания заполнил весь буфер (голова упирается в хвост) и места в нем больше нет, то он не должен еще не выбранные из него данные затирать. Только флажок выставить - я данные теряю. И головная программа тут-же должна тебе просигнализировать - мол флажок выставился, ты хреново программируешь. Что-то типа того.

Добавлено через 6 минут
И еще - сначала отлаживаешь только прием данных. Ничего лишнего в коде при этом не должно быть. Отработал прием и он идеален - только тогда добавляешь в код обработку данных. Т.е. программу надо собирать последовательно, а не пытаться сбацать одним махом все.
0
0 / 0 / 0
Регистрация: 09.03.2011
Сообщений: 18
25.05.2015, 22:33  [ТС] 11
Вот код программы которая выполняет только прием... Проверял в протэусе, на вход подключаю генератор с частотой 3 Гц... Так вот когда counter++ закоментировано, то все работает правда результаты измерения постоянно присваиваються только нулевому элементу массива all_data... но как только раскоментирую counter++ то данные записываються только один раз... Хотя прерывания срабатывает....
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
65
66
67
68
69
70
71
72
73
74
75
76
#include <mega8.h>
 
unsigned char  all_data[200][2];
unsigned char counter=0;
// Timer1 input capture interrupt service routine
interrupt [TIM1_CAPT] void timer1_capt_isr(void)
{
 
if (PINB.1==0)
    PORTB.1=1;
else
    PORTB.1=0;
if (TCCR1B&(1<<6)){
 all_data[counter][1]=ICR1;
 TCCR1B&=0b10111111;
 TIFR&=(1<<5);
 all_data[counter][0]=0x01;
 TCNT1=0;
     }
else
   {
   all_data[counter][1]=ICR1;
   TCCR1B|=0b01000000;
   TIFR&=(1<<5);
   all_data[counter][0]=0x02;    
   TCNT1=0;
    }    
 //  counter++; 
  if (counter>=199) counter=0;
 
}
 
 
void main(void)
{
 
PORTB=0x01;
DDRB=0x02;
 
PORTC=0x00;
DDRC=0x00;
PORTD=0x00;
DDRD=0x00;
TCCR0=0x00;
TCNT0=0x00;
TCCR1A=0x00;
TCCR1B=0x03;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;
MCUCR=0x00;
TIMSK=0x20;
UCSRB=0x00;
ACSR=0x80;
SFIOR=0x00;
ADCSRA=0x00;
SPCR=0x00;
TWCR=0x00;
 
#asm("sei")
 
while (1)
      {
      // Place your code here
 
      }
}
0
6770 / 2739 / 384
Регистрация: 17.02.2013
Сообщений: 4,048
26.05.2015, 00:39 12
Цитата Сообщение от lancer5610 Посмотреть сообщение
TIFR&=(1<<5);
Разве этот бит не обнуляется автоматически, когда происходит прерывание ?

Добавлено через 25 минут
Цитата Сообщение от lancer5610 Посмотреть сообщение
Хотя прерывания срабатывает....
ПрерываниЯ срабатываЮт или прерываниЕ срабатываЕт ? Т.е. прерывания просходят неоднократно ?

Если неоднократно, то должны же данные куда-то писаться. Не могут-же они не писаться никуда. Дас ист фантастиш.
Добавлено через 1 минуту
Цитата Сообщение от lancer5610 Посмотреть сообщение
Проверял в протэусе
Вот не верю я Протеусам. Изыди сатана ...

Добавлено через 12 минут
Цитата Сообщение от lancer5610 Посмотреть сообщение
if (counter>=199) counter=0;
if (counter>199) counter=0;
Это если строго.

Сделай ка буферок пока не на 200 элементов, а на 100. А то там ОЗУ всего килобайт. Аллах его знает как там Си память распределяет. Но это уже пошли поиски отчего происходит то, чего не может быть.

Добавлено через 1 минуту
Вопрос - по какому адресу в ОЗУ переменная counter сидит ? Она за пределы килобайта не выползла ?

Добавлено через 12 минут
Терпеть не могу Си. Никогда не ясно что он там накомпилировал ? То-ли дело асм.
0
1978 / 1276 / 131
Регистрация: 04.01.2010
Сообщений: 4,607
26.05.2015, 09:10 13
ТС, ваша программа с точки зрения компилятора ничего не делает, потому что вы пишете в массив, который нигде не используется.
1) Поставьте тип volatile переменным, используемым в прерываниях.
2) Отключите оптимизацию.
0
26.05.2015, 09:10
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
26.05.2015, 09:10
Помогаю со студенческими работами здесь

Работа с хуком по захвату мыши
Здравствуйте! Имеется вот такой вот интересный хук мыши:...

Timer2 STM32F103RBT6 прерывание по захвату
Здрасте всем! Помогите решить задачку! Мне надо по каждому изменению фронта на ноге мк...

Создать программу по захвату с COM порта
Есть устройство которое передает данные через компорт. Очень нужна програмка, которая бы...

Прерывание по захвату TIM4! f103cbt
Задача такая , есть у меня сигнал статического кода с пульта ворот (сигнал с rf приемника) на пине...

Ошибка с приемом данных чере сокет IP 204.204.204.204
#define MY_PORT 666 char buff; if (WSAStartup(0x0202,(WSADATA *) &amp;buff)) { //.... } SOCKET...

прерывание по захвату + шим для сервопривода
Всем привет. Разрабатываю пропорциональное управление на AVR. В программировании я совсем новичок...

[Решено] Не срабатывает прерывание по захвату таймера А
Не срабатывает прерывание по захвату таймера А. Вот код, я уже вырезал все, оставил только...


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

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
Новые блоги и статьи
Как работать с GraphQL на TypeScript
InfoMaster 08.01.2025
Введение в GraphQL и TypeScript В современной разработке веб-приложений GraphQL стал мощным инструментом для создания гибких и эффективных API. В сочетании с TypeScript, эта технология. . .
Счётчик на базе сумматоров + регистров и генератора сигналов согласования.
Hrethgir 07.01.2025
Создан с целью проверки скорости асинхронной логики: ранее описанного сумматора и предополагаемых fast регистров. Регистры созданы на базе ранее описанного, предполагаемого fast триггера. То-есть. . .
Как перейти с Options API на Composition API в Vue.js
BasicMan 06.01.2025
Почему переход на Composition API актуален В мире современной веб-разработки фреймворк Vue. js продолжает эволюционировать, предлагая разработчикам все более совершенные инструменты для создания. . .
Архитектура современных процессоров
inter-admin 06.01.2025
Процессор (центральный процессор, ЦП) является основным вычислительным устройством компьютера, которое выполняет обработку данных и управляет работой всех остальных компонентов системы. Архитектура. . .
История создания реляционной модели баз данных, правила Кодда
Programming 06.01.2025
Предпосылки создания реляционной модели В конце 1960-х годов компьютерная индустрия столкнулась с серьезными проблемами в области управления данными. Существовавшие на тот момент модели данных -. . .
Полезные поделки на Arduino, которые можно сделать самому
raxper 06.01.2025
Arduino как платформа для творчества Arduino представляет собой удивительную платформу для технического творчества, которая открывает безграничные возможности для создания уникальных проектов. Эта. . .
Подборка решений задач на Python
IT_Exp 06.01.2025
Целью данной подборки является предоставление возможности ознакомиться с различными задачами и их решениями на Python, что может быть полезно как для начинающих, так и для опытных программистов. . . .
С чего начать программировать микроконтроллер­­ы
raxper 06.01.2025
Введение в мир микроконтроллеров Микроконтроллеры стали неотъемлемой частью современного мира, окружая нас повсюду: от простых бытовых приборов до сложных промышленных систем. Эти маленькие. . .
Из чего собрать игровой компьютер
inter-admin 06.01.2025
Сборка игрового компьютера требует особого внимания к выбору комплектующих и их совместимости. Правильно собранный игровой ПК не только обеспечивает комфортный геймплей в современных играх, но и. . .
Обновление сайта www.historian.b­y
Reglage 05.01.2025
Обещал подвести итоги 2024 года для сайта. Однако начну с того, что изменилось за неделю. Добавил краткий урок по последовательности действий при анализе вредоносных файлов и значительно улучшил урок. . .
Как использовать GraphQL в C# с HotChocolate
Programming 05.01.2025
GraphQL — это современный подход к разработке API, который позволяет клиентам запрашивать только те данные, которые им необходимы. Это делает взаимодействие с API более гибким и эффективным по. . .
Модель полного двоичного сумматора с помощью логических операций (python)
AlexSky-coder 04.01.2025
def binSum(x:list, y:list): s=^y] p=x and y for i in range(1,len(x)): s. append((x^y)^p) p=(x and y)or(p and (x or y)) return s x=list() y=list()
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru