Полная версия этой страницы:
жутко глючит мк
_Ivan_33
Apr 21 2008, 14:20
где почитать про прерывания чтоб было хорошо написано - понятно и просто!?
domowoj
Apr 21 2008, 14:38
Цитата(_Ivan_33 @ Apr 21 2008, 22:20)

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

но ведь изменение логического уровня на ноге мк может произойти в разный момент а тут изменение уровня будет много раз...
и чем же их использование в моем случае так важно?
Не совсем понял вопрос... Можно как-то более четко задавать вопросы - типа как для тазика?
В Вашем случае изменения уровня на ноге будет происходить не в "разный момент" - а конкретно при пересечении нуля.
Да в принципе, можно и без прерываний обойтись. Но с ними проще и удобней.
1) Прерывание INT0 - включаете гирлянду, запускаете таймер Т0
2) Прерывание от T0 - выключаете гирлянду
- вот и вся программа - в общих чертах
_Ivan_33
Apr 21 2008, 15:31
кароче все понятно - при пересечении нуля по прерыванию включать и выключать порт
буду осваивать - а с прерываниями не работал раньше
Цитата(_Ivan_33 @ Apr 21 2008, 23:31)

буду осваивать - а с прерываниями не работал раньше
Да ладно, никто же не настаивает
Цитата(tazik @ Apr 21 2008, 23:26)

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

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

и почему не подключена земля к мк?
Землю (и питание) МК я не рисовал, т.к. мне было лень смотреть его описание.
Ошибка в том что я не нарисовал резистор между выходом (4 ногой) H11L1 и +5В. Номинал 1кОм если не запямятовал.
Книги читать начал?
_Ivan_33
Apr 22 2008, 05:57
да, я сейчас заболел - время появилось
_Ivan_33
Apr 22 2008, 09:08
вот узнал чтоб глобально разрешить прерывания нужно набрать #asm("sei") а запретить #asm("cli")
ну типа такого прерывания что на выходе int0(1) есть смена логического уровня такого нету... есть только прерывание по лог0, прерывание по ниспадающему фронту сигнала и по возрастающему
и что делать?
vladi1147
Apr 22 2008, 09:54
Цитата(_Ivan_33 @ Apr 22 2008, 13:08)

и что делать?
Добрый день всем!
Пусть меня старшие товарищи поправят, если я ошибаюсь, но мне кажется было бы полезно познакомиться с программой FlowCode. Она, кажется, для PIC-контроллеров, но позволяет отвлечься от кодирования на ассемблере или Си и сосредоточиться на происходящих событиях. Полученный hex-файл можно загрузить в Proteus, если не хватает внешних элементов, и увидеть происходящее без осциллографа, как если бы он был.
Конечно, окончательный ответ будет найден на макетной плате, но его легче искать, когда ясна суть происходящего.
Цитата(_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
Apr 22 2008, 10:37
блин перерыл книги там мало что написано.... ну может кто-нить сюда хоть откуда-то скопирует... я наверное штук 5 книг смотрел уже - на 2 страницах максимум написано...
Цитата(_Ivan_33 @ Apr 22 2008, 18:37)

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

как делать прерывания... хотя бы на изменение лог уровня на ноге...
Вот нашел кое-что- это какие-то регуляторы,
есть и на си, с прерыванием.
_Ivan_33
Apr 29 2008, 09:57
нашел на gaw.ru детектор нуля... сейчас буду разибрать...
если что не понятно напишу...
а кто-то мне еще хотел про шИМ написать....
_Ivan_33
May 1 2008, 08:45
вот в книжке евстифеева написано что есть вектор прерывания изменения логического уровня на ноге. в ДШ на тиню написано вот это 0x000B PCINT Pin Change Interrupt. как мне его использовать?????
напишите в общей форме как вообще инициализировать прерывания!!! кто-нибудь помогите пожалуйста!!!
domowoj
May 1 2008, 09:10
Там же все написано.
В GIMSK устанавливаешь PCIE, в PCMSK устанавливаешь нужный PCINTx,
при установленном общем прерывании готово прерывание полюбому изменению сигн.
на выбранной ноге МК.
_Ivan_33
May 1 2008, 09:46
а вот написано - изменение сигналов на выводах - на каких выводах? и если их много как установить чтоб было тока на 1 выводе?
как записать в регистр GIMSK 5-ий разряд называемый PCIE лог.1????
Цитата(_Ivan_33 @ May 1 2008, 17:46)

а вот написано - изменение сигналов на выводах - на каких выводах? и если их много как установить чтоб было тока на 1 выводе?
как записать в регистр GIMSK 5-ий разряд называемый PCIE лог.1????
Км, уважаемый, а мы вообще в этом веке планируем читать datasheets от производителя? Или уже только в следующем?
Там все четко написано.
С Вашей стороны не видно совершенно никаких усилий, это удручает
GIMSK|=(1<<PCIE);
domowoj
May 1 2008, 09:51
Не в GIMSK , а в PCMSK- маска прерывания.
Посмотри в начале книги цоколевку и назначение выводов МК.
PCINT5 - PB5 - 17 нога у тини2313.
_Ivan_33
May 1 2008, 10:06
я его сегодня скачал!!! и тем более я пока начинающий - еще не знаю что к чему
нашел этот регистр в ДШ...
Цитата(_Ivan_33 @ May 1 2008, 17:59)

я его сегодня скачал!!! и тем более я пока начинающий - еще не знаю что к чему
Только сегодня?
Понятно, что начинающий, я ж не против. Просто Вам потребуется усвоить более-менее приличный объем информации. Хорошо было бы иметь под рукой знающего человека, чтобы общаться с ним вживую. То есть более оперативно решать вопросы. Если такого человека нет, то придется грызть все самому, по книжкам. \
_Ivan_33
May 1 2008, 10: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 я скачал раньше!
domowoj
May 1 2008, 10:28
Цитата(_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...
Ну на чистом англицком и у Евстифеева на чистом русском написано.
Таким образом ты организовал прерывание внешнее или програмное, если изменить этот бит порта.
Читать внимательнее!!! Все поймешь.
Цитата(_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
May 1 2008, 10:41
все... поехал в сад... вечером буду...
Цитата(_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
May 1 2008, 17:10
#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
May 1 2008, 17:19
#include <tiny2313.h>
// Pin change 0-7 interrupt service routine
interrupt [PCINT] void pin_change_isr0(void)
{
// Place your code here
}
Вот что пишет коде визард кодвижна.
_Ivan_33
May 1 2008, 17:50
а мне подсказали что исправить на номера битов это все...
другой вопрос ... типа у меня в программе
if (a==0||a==17) {function1(2);
function1(4);
function1(8);
function1(16);};
и так далее .... а мне нужно заменить функцию на прерывание и чтоб кусок кода который будет выполняться был от разных переменных - в данном случае - 2,4,8,16
domowoj
May 1 2008, 18:12
Цитата(_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
May 1 2008, 18:26
ну вообщем мы объявили функцию... там выполняется кусок кода относительно переменной... в этом коде это и написано ...
а мне нужно чтоб после объявления функции обработки прерывания в общем виде потом в главной функции ставилось уже обработчик прерывания но относительно какого либо значения переменной
понимаю что бредово написал так как прерывания идут обособленно от функции...
switch (a)
{
case 0 : .... break; // разрешаем нужное прерывание и ждем или программно вызывем его
case 17: .... break; //то-же самое
}
Значениям а лучше дать осмысленные названия через ENUM.
_Ivan_33
May 7 2008, 15:32
кароче мне объяснили как сделать это.... но вопрос стоит - использовать счетчик или delay_ms () для подсчета времени... так ли это принципиально и если что предстоит исчитывать периоды для плавного загорание лампочки...
_Ivan_33
May 8 2008, 17:59
начал изучать счетчики - вопрос: как записать и куда записать значение при котором счетчик должен отреагировать? т.е. конечное значение счета...
Цитата(_Ivan_33 @ May 8 2008, 21:59)

начал изучать счетчики - вопрос: как записать и куда записать значение при котором счетчик должен отреагировать? т.е. конечное значение счета...
В регистр сравнения OCR, при совпадении его значения со значением счетного регистра будет сгенерировано прерывание.
Либо записываешь начальное значение в счетный регистр и ждешь переполнения.
_Ivan_33
May 9 2008, 10:34
Цитата
#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
May 25 2008, 15:24
вот пишу опять сюда... ничего не получается... тот же самый случай
Цитата
#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 ком
возникла мысль поменять блок питания...
Сергей Борщ
May 25 2008, 15:40
Цитата(_Ivan_33 @ May 25 2008, 18:24)

вот пишу опять сюда... ничего не получается... тот же самый случай
На этом форуме буквально через день ищется одна и та же ошибка. Если у вас переменная меняется в прерывании, а проверяется в основной программе, то она
обязательно должна быть объявлена с квалификатором
volatile! Поэтому у вас должно быть volatile int a = 0;
_Ivan_33
May 25 2008, 15:55
эффект тот же... но мигать стало почаще
domowoj
May 25 2008, 16:07
Цитата(_Ivan_33 @ May 25 2008, 22:24)

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

1) взято с аналогичного девайса но + диод на ногу мк
2) таймера нету ... просто если посмотреть на волну переменного тока там будет 2 перехода через 0 и исходя из периода волны мы считаем
Вольт сколько подаешь ?
Диод на землю не нужен тк он есть внутри МК.
_Ivan_33
May 25 2008, 16:26
220 вольт...
не на землю а эту переменку и выпрямить ...
если что я уходить не буду - пишите
Для просмотра полной версии этой страницы, пожалуйста,
пройдите по ссылке.