реклама на сайте
подробности

 
 
> Прерывание на си, Переехал с ассемблера, вопросы..
Araxnid
сообщение Jan 28 2012, 11:30
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 45
Регистрация: 3-11-11
Пользователь №: 68 125



МК - ATmega16.
До этого работал с ассемблером и все было очень понятно и ясно, вот сейчас начал С осваивать, написал обычную программу привет светодиод..
На PC2 повешен светодиод, на INT0 кнопка ( при нажатии "0", если отпущена то "1")
Настроил прерывание по INT0, если зафиксирован уровень "0", то светодиод должен погаснуть\засветится.
Вот код
CODE
#define F_CPU 6000000UL // 6 MHz
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>

SIGNAL(INT0_vect)
{
PORTC ^= (1<<PC2);
}

int main(void)
{
int i=0;
TCCR0 = 1<<CS02|1<<CS00;
TIMSK = 1<<TOIE0;
DDRC = 1<<DDC2;
PORTC = 1<<PC2;
GICR = 1<<INT0;
sei();
while(1)
{
i++;
i++;
i--;
i--;
}
}


Проверяю в протеусе, если без прерываний, то светодиод горит, если с прерываниями то, тоже горит, но на нажатие кнопки не реагирует.
TCCR0 и TIMSK - это я с таймером экспериментировал, но там тоже ничего не вышло..
GICR - регистр для разрешение прерываний по INT0.

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

Ах да, если это важно, то компилирую в Avr studio v.5

Сообщение отредактировал Araxnid - Jan 28 2012, 11:33
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов (1 - 8)
Палыч
сообщение Jan 28 2012, 12:04
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Даже если считать, что кнопка не имеет дребезга контактов, то, хорошо бы, условие прерывания настроить не на уровень (как сейчас), а на перепад из высокого в низкий уровень (см. регистр MCUCR)
Go to the top of the page
 
+Quote Post
Xenia
сообщение Jan 28 2012, 12:24
Сообщение #3


Гуру
******

Группа: Модератор FTP
Сообщений: 4 479
Регистрация: 20-02-08
Из: Москва
Пользователь №: 35 237



Цитата(Araxnid @ Jan 28 2012, 15:30) *
До этого работал с ассемблером и все было очень понятно и ясно, вот сейчас начал С осваивать, написал обычную программу привет светодиод..
Проверяю в протеусе, если без прерываний, то светодиод горит, если с прерываниями то, тоже горит, но на нажатие кнопки не реагирует.

А вы попросите компилятор сгенерировать ассемблерный листинг, а потом проверьте по листингу, так оно или не так, раз уж вы ассемблер уже знаете. Когда уже знаешь ассемблер, изучать С просто, куда труднее в обратную сторону - привычка к С расхолаживает.
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Jan 28 2012, 12:29
Сообщение #4


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



И по шагам пройдитесь, а то неясно, чего Вам неясно. Протеус тоже.. расхолаживает.
Go to the top of the page
 
+Quote Post
Araxnid
сообщение Jan 28 2012, 16:16
Сообщение #5


Участник
*

Группа: Участник
Сообщений: 45
Регистрация: 3-11-11
Пользователь №: 68 125



Да, менял уже уровень сигнала для вызова прерывания, и по спаду, и по фронту ставил, ничего..

В авр студио прошагал, все отлично, если флаг прерывания выставляется (в ручную), то и прерывание вызывается..

В протеусе прерывание не вызывается, нажимаю я кнопку, отпускаю - ничего. И "зажимать" пробовал.
Дребезга нет, посмотрел на осциллографе.
Протеу,с по крайнее мере, главный цикл и инициализацию точно правильно прошагивает.
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Jan 28 2012, 17:20
Сообщение #6


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Ну я не знаю.. скиньте проект, в последнем протезе можно проверить...
Зы левом.

Сообщение отредактировал _Pasha - Jan 28 2012, 17:20
Go to the top of the page
 
+Quote Post
RabidRabbit
сообщение Jan 28 2012, 19:41
Сообщение #7


Местный
***

Группа: Свой
Сообщений: 397
Регистрация: 3-12-09
Из: Россия, Москва
Пользователь №: 54 040



А по-моему зря прерывание от таймера включено, оно ведь каждый раз при сработке таймера будет программу перезапускать...
Вот слегка подпиленный код, с антидребезгом (как я его себе представляю sm.gif )
CODE

#define F_CPU 6000000UL // 6 MHz
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>

volatile int i=0;

SIGNAL(INT0_vect)
{
GICR = (0 << INT0);
PORTC ^= (1<<PC2);
i = 30000;
}

int main(void)
{
//TCCR0 = 1<<CS02|1<<CS00;
//TIMSK = 1<<TOIE0;
DDRC = 1<<DDC2;
PORTC = 1<<PC2;
DDRD = (0 << DDD2);
PORTD = (1 << PORTD2);
GICR = 1<<INT0;
sei();

while(1)
{
//
if ( PIND & (1 << PIND2) )
{
//
if ( i )
{
//
if ( ! (--i) )
{
//
GICR = (1 << INT0);
}
}
}
}
}

Go to the top of the page
 
+Quote Post
Araxnid
сообщение Jan 30 2012, 08:27
Сообщение #8


Участник
*

Группа: Участник
Сообщений: 45
Регистрация: 3-11-11
Пользователь №: 68 125



2RabidRabbit
О! Ваш код заработал!
Только зачем здесь вот этот кусок:
CODE
if ( i )
{
//
if ( ! (--i) )

Go to the top of the page
 
+Quote Post
Палыч
сообщение Jan 30 2012, 08:56
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(Araxnid @ Jan 30 2012, 12:27) *
Только зачем здесь вот этот кусок

Подавление дребезга контактов кнопки. При возникновении прерывания при нажатии кнопки, они (прерывания от кнопки) будут запрещены, до тех пор, пока МК не "открутит" до нуля вычитанием переменную i (пропуская таким образом время дребезга контактов), установленную в некоторое значение (в данном случае 30000) в процедуре прерывания от кнопки.

Цитата(Araxnid @ Jan 30 2012, 12:27) *
О! Ваш код заработал!

Ваш код тоже - худо-бедно но заработал бы, если бы Вы удалили из него разрешения прерывания от таймера (выше Вам это подсказывали).
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 24th July 2025 - 21:55
Рейтинг@Mail.ru


Страница сгенерированна за 0.01426 секунд с 7
ELECTRONIX ©2004-2016