Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: жутко глючит мк
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему
Страницы: 1, 2, 3
_Ivan_33
где почитать про прерывания чтоб было хорошо написано - понятно и просто!?
domowoj
Евстифеев
http://lord-n.narod.ru/walla.html
там много книг по АВР.
tazik
Цитата(_Ivan_33 @ Apr 21 2008, 22:20) *
где почитать про прерывания чтоб было хорошо написано - понятно и просто!?


Вообще все очень подробно написано в книге Фрунзе "Микроконтроллеры - это же просто", правда для 51 семейства - но основной сути это не меняет.

А если на пальцах... В общем выполняет у Вас контроллер какую-то там задачу, например, что-то там считает. И в то же время, Вам надо как-то среагировать на изменение, например, уровня сигнала на ножке контроллера. Можно в ту, первую, задачу вставить периодическую проверку уровня на ножке - для быстрой реакции Вам придется вставлять эту проверку, например, после каждого оператора основной задачи. Согласитесь, это не удобно.
Вот как раз для таких случаев существуют прерывания. В случае изменения уровня на ножке INT0 контроллер автоматически прерывает выполнение основной программы и перепрыгивает на жестко заданый адрес. По этому адресу у Вас должен находиться код для обработки данного события.
В общем прерывания позволяют контроллеру заниматься какими-то другими делами, помимо выполнения основной программы
_Ivan_33
но ведь изменение логического уровня на ноге мк может произойти в разный момент а тут изменение уровня будет много раз...
и чем же их использование в моем случае так важно?
tazik
Цитата(_Ivan_33 @ Apr 21 2008, 23:10) *
но ведь изменение логического уровня на ноге мк может произойти в разный момент а тут изменение уровня будет много раз...
и чем же их использование в моем случае так важно?

Не совсем понял вопрос... Можно как-то более четко задавать вопросы - типа как для тазика?

В Вашем случае изменения уровня на ноге будет происходить не в "разный момент" - а конкретно при пересечении нуля.

Да в принципе, можно и без прерываний обойтись. Но с ними проще и удобней.

1) Прерывание INT0 - включаете гирлянду, запускаете таймер Т0
2) Прерывание от T0 - выключаете гирлянду

- вот и вся программа - в общих чертах
_Ivan_33
кароче все понятно - при пересечении нуля по прерыванию включать и выключать порт
буду осваивать - а с прерываниями не работал раньше
tazik
Цитата(_Ivan_33 @ Apr 21 2008, 23:31) *
буду осваивать - а с прерываниями не работал раньше

Да ладно, никто же не настаивает

Цитата(tazik @ Apr 21 2008, 23:26) *
1) Прерывание INT0 - включаете гирлянду, запускаете таймер Т0
2) Прерывание от T0 - выключаете гирлянду


Пардон, у Вас на выходе тиристор? Тогда я Вам наврал ( Правильно как предлагает domowoj
_Ivan_33
симистор
domowoj
Еще раз повторюсь
реши простую задачку без зажигания лампочек:
выведи на один из выходов сигнал на входе,
т.е. задача посмотреть момент перехода через 0 входной
синусоиды.
INT0 пусть работает по любому изменению сигнала.
Осциллограф есть?
_Ivan_33
нету, вот эту штуку сделаю его и куплю...
Omen_13
Цитата(_Ivan_33 @ Apr 21 2008, 10:17) *
и почемувывод на кренке 5 вольт он 4-ий?

КР142ЕН5А в 3-х ногом корпусе имеет "золотого" старшего брата 142ЕН5А, там другой корпус. Номера выводов на графическом обозначении для обоих исполнений было решено оставить одинаковыми.
Цитата(_Ivan_33 @ Apr 21 2008, 10:17) *
и почему не подключена земля к мк?

Землю (и питание) МК я не рисовал, т.к. мне было лень смотреть его описание. laughing.gif
Ошибка в том что я не нарисовал резистор между выходом (4 ногой) H11L1 и +5В. Номинал 1кОм если не запямятовал.

Книги читать начал?
_Ivan_33
да, я сейчас заболел - время появилось
_Ivan_33
вот узнал чтоб глобально разрешить прерывания нужно набрать #asm("sei") а запретить #asm("cli")
ну типа такого прерывания что на выходе int0(1) есть смена логического уровня такого нету... есть только прерывание по лог0, прерывание по ниспадающему фронту сигнала и по возрастающему
и что делать?
vladi1147
Цитата(_Ivan_33 @ Apr 22 2008, 13:08) *
и что делать?


Добрый день всем!

Пусть меня старшие товарищи поправят, если я ошибаюсь, но мне кажется было бы полезно познакомиться с программой FlowCode. Она, кажется, для PIC-контроллеров, но позволяет отвлечься от кодирования на ассемблере или Си и сосредоточиться на происходящих событиях. Полученный hex-файл можно загрузить в Proteus, если не хватает внешних элементов, и увидеть происходящее без осциллографа, как если бы он был.

Конечно, окончательный ответ будет найден на макетной плате, но его легче искать, когда ясна суть происходящего.
tazik
Цитата(_Ivan_33 @ Apr 22 2008, 17:08) *
вот узнал чтоб глобально разрешить прерывания нужно набрать #asm("sei") а запретить #asm("cli")
ну типа такого прерывания что на выходе int0(1) есть смена логического уровня такого нету... есть только прерывание по лог0, прерывание по ниспадающему фронту сигнала и по возрастающему
и что делать?


Почему нету? Есть - MCUCR ISC01=0, ISC00=1 - any change - при любом изменении.
Более того, помимо INT0, INT1 есть еще прерывание PCINT - при изменении уровня на одной из 6 ножек

Цитата(vladi1147 @ Apr 22 2008, 17:54) *
Добрый день всем!

Пусть меня старшие товарищи поправят, если я ошибаюсь, но мне кажется было бы полезно познакомиться с программой FlowCode. Она, кажется, для PIC-контроллеров, но позволяет отвлечься от кодирования на ассемблере или Си и сосредоточиться на происходящих событиях.


Спасибо за ссылку. Думал, что кроме Algoritm Buildera ничего нет. Уже есть и для AVR, и для ARM )
_Ivan_33
блин перерыл книги там мало что написано.... ну может кто-нить сюда хоть откуда-то скопирует... я наверное штук 5 книг смотрел уже - на 2 страницах максимум написано...
tazik
Цитата(_Ivan_33 @ Apr 22 2008, 18:37) *
блин перерыл книги там мало что написано.... ну может кто-нить сюда хоть откуда-то скопирует... я наверное штук 5 книг смотрел уже - на 2 страницах максимум написано...


А что именно ты сейчас ищешь?
_Ivan_33
как делать прерывания... хотя бы на изменение лог уровня на ноге...
domowoj
Цитата(_Ivan_33 @ Apr 22 2008, 20:27) *
как делать прерывания... хотя бы на изменение лог уровня на ноге...

Вот нашел кое-что- это какие-то регуляторы,
есть и на си, с прерыванием.
_Ivan_33
нашел на gaw.ru детектор нуля... сейчас буду разибрать...
если что не понятно напишу...
а кто-то мне еще хотел про шИМ написать....
_Ivan_33
вот в книжке евстифеева написано что есть вектор прерывания изменения логического уровня на ноге. в ДШ на тиню написано вот это 0x000B PCINT Pin Change Interrupt. как мне его использовать?????
напишите в общей форме как вообще инициализировать прерывания!!! кто-нибудь помогите пожалуйста!!!
domowoj
Там же все написано.
В GIMSK устанавливаешь PCIE, в PCMSK устанавливаешь нужный PCINTx,
при установленном общем прерывании готово прерывание полюбому изменению сигн.
на выбранной ноге МК.
_Ivan_33
а вот написано - изменение сигналов на выводах - на каких выводах? и если их много как установить чтоб было тока на 1 выводе?

как записать в регистр GIMSK 5-ий разряд называемый PCIE лог.1????
tazik
Цитата(_Ivan_33 @ May 1 2008, 17:46) *
а вот написано - изменение сигналов на выводах - на каких выводах? и если их много как установить чтоб было тока на 1 выводе?

как записать в регистр GIMSK 5-ий разряд называемый PCIE лог.1????


Км, уважаемый, а мы вообще в этом веке планируем читать datasheets от производителя? Или уже только в следующем?
Там все четко написано.
С Вашей стороны не видно совершенно никаких усилий, это удручает

GIMSK|=(1<<PCIE);
domowoj
Не в GIMSK , а в PCMSK- маска прерывания.
Посмотри в начале книги цоколевку и назначение выводов МК.
PCINT5 - PB5 - 17 нога у тини2313.
_Ivan_33
я его сегодня скачал!!! и тем более я пока начинающий - еще не знаю что к чему

нашел этот регистр в ДШ...
tazik
Цитата(_Ivan_33 @ May 1 2008, 17:59) *
я его сегодня скачал!!! и тем более я пока начинающий - еще не знаю что к чему


Только сегодня?
Понятно, что начинающий, я ж не против. Просто Вам потребуется усвоить более-менее приличный объем информации. Хорошо было бы иметь под рукой знающего человека, чтобы общаться с ним вживую. То есть более оперативно решать вопросы. Если такого человека нет, то придется грызть все самому, по книжкам. \
bb-offtopic.gif
_Ivan_33
Each PCINT7..0-bit selects whether pin change interrupt is enabled on the corresponding
I/O pin. If PCINT7..0 is set and the PCIE bit in GIMSK is set, pin change interrupt is
enabled on the corresponding I/O pin. If PCINT7..0 is cleared, pin change interrupt on
the corresponding I/O pin is disabled. - вот похоже я пошел правильным путем!


а почему в разряды записываются лог. состояния именно так?
вроде в регистры порта записывается просто PORTB=2...

ну ERRATa я скачал раньше!
domowoj
Цитата(_Ivan_33 @ May 1 2008, 17:12) *
Each PCINT7..0-bit selects whether pin change interrupt is enabled on the corresponding
I/O pin. If PCINT7..0 is set and the PCIE bit in GIMSK is set, pin change interrupt is
enabled on the corresponding I/O pin. If PCINT7..0 is cleared, pin change interrupt on
the corresponding I/O pin is disabled. -
а почему в разряды записываются лог. состояния именно так?
вроде в регистры порта записывается просто PORTB=2...

Ну на чистом англицком и у Евстифеева на чистом русском написано.
Таким образом ты организовал прерывание внешнее или програмное, если изменить этот бит порта.
Читать внимательнее!!! Все поймешь.
tazik
Цитата(_Ivan_33 @ May 1 2008, 18:12) *
Each PCINT7..0-bit selects whether pin change interrupt is enabled on the corresponding
I/O pin. If PCINT7..0 is set and the PCIE bit in GIMSK is set, pin change interrupt is
enabled on the corresponding I/O pin. If PCINT7..0 is cleared, pin change interrupt on
the corresponding I/O pin is disabled. - вот похоже я пошел правильным путем!
а почему в разряды записываются лог. состояния именно так?
вроде в регистры порта записывается просто PORTB=2...

ну ERRATa я скачал раньше!


Есть конечно, команды sbi и cbi, позволяющие обращаться к битам регистров индивидуально. Другое дело, что только к I/O регистрам. GIMSK к ним не относится.

можно было бы сделать так:
ldi r16, 1<<TOIE1
out TIMSK,r16

Но при этом изменятся биты, которые мы не хотели трогать

В итоге приходится делать так - для установки бита в 1:
in r16,TIMSK
andi r16,1<<TOIE1
out TIMSK,r16

на С:
TIMSK|=(1<<TOIE1); - установка в 1

TIMSK&=!(1<<TOIE1); - сброс в 0

Регистры и биты взяты произвольные - для примера
_Ivan_33
все... поехал в сад... вечером буду...
tazik
Цитата(_Ivan_33 @ May 1 2008, 18:41) *
ну а почему записывается в регистры именно так а не как в регистры порта?

Архитектура контроллера такая.
АВРСтудио под рукой есть? Попробуйте сами.

The CBI and SBI instructions work with registers 0x00 to 0x1F only.

Цитата(_Ivan_33 @ May 1 2008, 18:41) *
все... поехал в сад... вечером буду...


Нормально. Удачи
_Ivan_33
#include <tiny2313.h>
#include <delay.h>
void main(void) {
#asm("sei");
DDRB=2;
GIMSK|=(1<<PCIE);
PCMSK|=(1<<PCINT7);}
void interrupt [PCINT7](void) {
PORTB=2;} - в чем ошибки?? в кодевижне пишет что PCIE PCINT7 - неизвестные символы...
domowoj
#include <tiny2313.h>

// Pin change 0-7 interrupt service routine
interrupt [PCINT] void pin_change_isr0(void)
{
// Place your code here

}

Вот что пишет коде визард кодвижна.
_Ivan_33
а мне подсказали что исправить на номера битов это все...
другой вопрос ... типа у меня в программе
if (a==0||a==17) {function1(2);
function1(4);
function1(8);
function1(16);};


и так далее .... а мне нужно заменить функцию на прерывание и чтоб кусок кода который будет выполняться был от разных переменных - в данном случае - 2,4,8,16
domowoj
Цитата(_Ivan_33 @ May 2 2008, 00:50) *
а мне подсказали что исправить на номера битов это все...
другой вопрос ... типа у меня в программе
if (a==0||a==17) {function1(2);
function1(4);
function1(8);
function1(16);};
и так далее .... а мне нужно заменить функцию на прерывание и чтоб кусок кода который будет выполняться был от разных переменных - в данном случае - 2,4,8,16

Честно, не знаю, да и не понятно что ты хочешь.
_Ivan_33
ну вообщем мы объявили функцию... там выполняется кусок кода относительно переменной... в этом коде это и написано ...


а мне нужно чтоб после объявления функции обработки прерывания в общем виде потом в главной функции ставилось уже обработчик прерывания но относительно какого либо значения переменной


понимаю что бредово написал так как прерывания идут обособленно от функции...
WHALE
switch (a)
{
case 0 : .... break; // разрешаем нужное прерывание и ждем или программно вызывем его
case 17: .... break; //то-же самое
}
Значениям а лучше дать осмысленные названия через ENUM.
_Ivan_33
кароче мне объяснили как сделать это.... но вопрос стоит - использовать счетчик или delay_ms () для подсчета времени... так ли это принципиально и если что предстоит исчитывать периоды для плавного загорание лампочки...
_Ivan_33
начал изучать счетчики - вопрос: как записать и куда записать значение при котором счетчик должен отреагировать? т.е. конечное значение счета...
fredo
Цитата(_Ivan_33 @ May 8 2008, 21:59) *
начал изучать счетчики - вопрос: как записать и куда записать значение при котором счетчик должен отреагировать? т.е. конечное значение счета...

В регистр сравнения OCR, при совпадении его значения со значением счетного регистра будет сгенерировано прерывание.
Либо записываешь начальное значение в счетный регистр и ждешь переполнения.
_Ivan_33
Цитата
#include <tiny2313.h>
#include <delay.h>
bit a=0;
bit b=0;
void main(void) {
#asm("sei");
TCCR1B|=(1<<2);
TCCR1B|=(1<<0);
DDRB=2;
GIMSK|=(1<<5);
PCMSK|=(1<<7);
while(1) {
if (a==1&&b==1) {a=0;
PORTB=2;
...
if(a==1) {a=0;
PORTB=0;};};};}
void interrupt [PCINT.7](void) {
a=1;
delay_xc(1000);
a=0;}
void interrupt [TIM1_COMPA]{
b=1;}


вместо ... напишите отсчет времени по счетчику ну скажем 2 секунды...
прога для attiny2313
и потом выключить отсчет времени...
_Ivan_33
вот пишу опять сюда... ничего не получается... тот же самый случай
Цитата
#include <tiny2313.h>
#include <delay.h>
int a=0;
void main(void) {
#asm("sei");
DDRB=2;
GIMSK|=(1<<5);
PCMSK|=(1<<7);
while(1) {
if (a==200) {a=0;
PORTB=2;
if(a==200) {a=0;
PORTB=0;};};};}
interrupt [PCINT] void pin_change_isr0(void) {
a++;}

опять ничто не получается... я уже просто не знаю что делать ...
ничего не мигает ... ну если только иногда ...
цепь питания - блок питания - 500 мкф на 25 вольт кренка 100 мкф на 25 вольт 0,1 мкф - сам контроллер


цепь определения перехода - 560 ком и диод 1N4007...


на резет подано лог1 через 10 ком

возникла мысль поменять блок питания...
Сергей Борщ
Цитата(_Ivan_33 @ May 25 2008, 18:24) *
вот пишу опять сюда... ничего не получается... тот же самый случай
На этом форуме буквально через день ищется одна и та же ошибка. Если у вас переменная меняется в прерывании, а проверяется в основной программе, то она обязательно должна быть объявлена с квалификатором volatile! Поэтому у вас должно быть volatile int a = 0;
_Ivan_33
эффект тот же... но мигать стало почаще
domowoj
Цитата(_Ivan_33 @ May 25 2008, 22:24) *
цепь определения перехода - 560 ком и диод 1N4007...

Откуда 560 ком и куда диод?
WHALE
дык а зачем вам прерывание от смены уровней на пинах и где у вас инициализация и прерывание от таймера?и разрешать прерывния лучше в конце инциализации контроллера прямо перед входом в главный цикл.
_Ivan_33
1) взято с аналогичного девайса но + диод на ногу мк
2) таймера нету ... просто если посмотреть на волну переменного тока там будет 2 перехода через 0 и исходя из периода волны мы считаем
domowoj
Цитата(_Ivan_33 @ May 25 2008, 23:10) *
1) взято с аналогичного девайса но + диод на ногу мк
2) таймера нету ... просто если посмотреть на волну переменного тока там будет 2 перехода через 0 и исходя из периода волны мы считаем

Вольт сколько подаешь ?
Диод на землю не нужен тк он есть внутри МК.
_Ivan_33
220 вольт...
не на землю а эту переменку и выпрямить ...
если что я уходить не буду - пишите
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.