WinAvr в вопросах и ответах
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18544
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: WinAvr в вопросах и ответах
я вообще ничего не понял, как связаны программные извраты с количеством внешних прерываний...
но дам вам пару советов:
1. когда пишите код - будьте внимательны и анализируйте то, что вы НАПИСАЛИ, а не то, ЧТО ХОТИТЕ получить, т.к. часто это не одно и то же.
2. наплюйте на "черточки" в протеусе - раз компилятор что-то выкинул, значит, оно было лишним. случаев, чтобы компилятор выкинул то, что нельзя, не замечено. зато полно случаев, когда написанное ведет себя не так, как хотелось - см.п.1
но дам вам пару советов:
1. когда пишите код - будьте внимательны и анализируйте то, что вы НАПИСАЛИ, а не то, ЧТО ХОТИТЕ получить, т.к. часто это не одно и то же.
2. наплюйте на "черточки" в протеусе - раз компилятор что-то выкинул, значит, оно было лишним. случаев, чтобы компилятор выкинул то, что нельзя, не замечено. зато полно случаев, когда написанное ведет себя не так, как хотелось - см.п.1
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
Re: WinAvr в вопросах и ответах
ARV писал(а):но дам вам пару советов:
С Новым Годом ВСЕМ!!! Я за всегда рад выслушать совет. А вот мысли свои выложить не могу. Но то чего я хотел у меня получилось, может кому надо:
int fol=0x0F;
ISR(TIMER0_OVF_vect){ // Timer/Counter0 Overflow
wip=PIND|fol;
if(wip==0X1F){
PORTD&=~(1<<0);
fol|=(1<<5);
_delay_ms(50);PORTD|=(1<<0);
}
if(PIND&0X20) fol&=~(1<<5);
wip=PIND|fol;
if(wip==0X2F){
PORTD&=~(1<<0);
fol|=(1<<4);
_delay_ms(50);PORTD|=(1<<0);
}
if(PIND&0X10) fol&=~(1<<4);
Это для двух кнопок. А вот только на счёт задержки сомневаюсь,надо ли она.
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18544
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: WinAvr в вопросах и ответах
всегда плохо, когда в обработчике прерываний делаются задержки... так же не хорошо, когда из обработчика прерывания вызываются сторонние функции (не статические, а библиотечные). не знаю, какая у вас конкретная задача, но лично я никогда в прерываниях кнопки не обслуживаю - нет нужды. по мне, так самое простое - это в главном цикле время от времени проверять состояние кнопок, вот и все.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
Re: WinAvr в вопросах и ответах
Начал переходить с асма на Си и тут же уперся в нежелание незатейливой программки работать.
В отладчике командой sei флаг прерываний не устанавливается, в тоже время программа крутится не в главном цикле, а вокруг прерывания.. Собственно не работает прерывание..
Что здесь может не работать - ума не приложу??
В отладчике командой sei флаг прерываний не устанавливается, в тоже время программа крутится не в главном цикле, а вокруг прерывания.. Собственно не работает прерывание..
Что здесь может не работать - ума не приложу??
Код: Выделить всё
#include <util/delay.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdlib.h> //
//#include "bits_macros.h" //
unsigned int cnt_S;
//XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
int main (void)
{
// ____ Configuration of ports _____
DDRA = 0b11111111; //; PA0-7=Out
PORTA = 0b00000000; //; PA0-7=low
DDRB = 0b00010000; //; PB4-????? ??? ???????? ???????????
PORTB = 0b11100011; //; pin3-????????? R-r
DDRC = 0b11100000; //; PC6,7,8=out, PC0,1,2,3,4,5=In
PORTC = 0b00011111; //; PC6,7,8= no R-rs, PC0,1,2,3,4,5= set R-rs
DDRD = 0xFC; // for LCD
//_______ Init. interrupt timer0 _____
TIMSK =(1<<TOIE0); // Timer0 overflow interrupt enable
TCCR0 = 3; // ;Prescaller > ;0=STOP; 2=F/8; 3=F/64 4=F/256;
cnt_S = 0;
sei() ; // установить флаг I
//SREG |= (1<<(7)); // установить флаг I
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
while(1)
{
if (cnt_S >= 1000) // проверить состояние счетчика
{
PORTC ^= (1<<(5)); // инвертировать вывод
cnt_S = 0; // обнулить счетчик
};
};
return (0);
}
//*****************************************************************
ISR (TIMER0_OVF_vect) // прерывание переполнения Т0
{
cnt_S ++ ;
TCNT0 = (0xff - 0x83); // прерывание каждую мс
}; - ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18544
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: WinAvr в вопросах и ответах
вы совершили традиционную для начинающих ошибку. avr-gcc (оно же WinAVR) не прощает вольностей по отношению к стандарту языка Си. ваша переменная cnt_S используется и в обработчике прерывания и в главной функции, а значит, она обязательно должна объявляться volatile-переменной! иначе компилятор считает, что эта переменная внутри основного цикла никогда не изменит свое значение, а значит, ни на что повлиять не сможет. бесполезные переменные и код для их обслуживания компилятор выбрасывает - у вас получается черти что: есть прерывание, но оно ничего не делает!
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
Re: WinAvr в вопросах и ответах
ARV писал(а): она обязательно должна объявляться volatile-переменной! иначе компилятор считает, что эта переменная внутри основного цикла никогда не изменит свое значение, а значит, ни на что повлиять не сможет. !
Спасибо, буду знать !!
Объявил как volatile unsigned int cnt_S; - не помогло...
Пернес проверку счетчика в само прерывание - тоже не работает..
Код: Выделить всё
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
while(1)
{
/* if (cnt_S >= 1000) //
{
PORTA ^= (2<<(5)); //
cnt_S = 0; //
};*/
};
return (0);
}
//*****************************************************************
ISR (TIMER0_OVF_vect) //
{
cnt_S ++ ;
TCNT0 = (0xff - 0x83); //
if (cnt_S >= 1000) //
{
PORTA ^= (1<<(5)); //
cnt_S = 0; //
};
};)))) что-то мудреный этот Си..
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18544
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: WinAvr в вопросах и ответах
ничего там мудреного. вы что хотите сделать?
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
Re: WinAvr в вопросах и ответах
ARV писал(а):ничего там мудреного. вы что хотите сделать?
Да у меня есть прогграмма, написанная на асме. Я ее решил переписмать на Си, для изучения последнего. Вот попытался вести в программу прерывание - не работает. Теперь просто хочу его запустить - помигать хотя бы светодиодом.. ))) Ничего не выходит. Где-то что-то упускаю.
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18544
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: WinAvr в вопросах и ответах
просто помигать можно вот так, без прерываний:или так, с прерываниями:
и чего тут мудреного?
Код: Выделить всё
#include <avr/io.h>
#include <util/delay.h>
int main(void){
DDRB = 1;
while(1){
PORTB ^= 1;
_delay_ms(500);
}
}Код: Выделить всё
#include <avr/io.h>
#include <avr/interrupt.h>
ISR(TIMER0_OVF_vect){
PORTB ^= 1;
}
int main(void){
DDRB = 1;
TIMSK = _BV(TOIE0);
TCCR0 = _BV(CS02) | _BV(CS00);
sei();
while(1);
}и чего тут мудреного?
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
Re: WinAvr в вопросах и ответах
Спасибо, разберу ваши примеры. Но мне мигание нужно для того в данный момент, чтобы включить прерывание. А в рабочем варианте в прерывании у меня выставляется флаг 1мс, по которому в основном цикле уже отсчитываются всевозможные интервалы..
Прошу прощения, а какая частота мигания будет в вашем варианте с прерыванием?? Мне кажется туда счетчик все-равно надо вводить.. Иначе частота будет намного выше визуально видимой..
Прошу прощения, а какая частота мигания будет в вашем варианте с прерыванием?? Мне кажется туда счетчик все-равно надо вводить.. Иначе частота будет намного выше визуально видимой..
Последний раз редактировалось R_ura Пн янв 03, 2011 23:49:52, всего редактировалось 1 раз.
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18544
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: WinAvr в вопросах и ответах
откуда ж мне знать. какая у вас тактовая частота? для таймера я включил делитель на 1024, переполнение возникнет спустя 256 этих тиков, т.е. итоговое деление тактовой частоты получается на 262144... если тактовая 1 МГц, то период мигания будет почти 8 секунд... ну а при тактовой 8 МГц - соответственно, 1 секунда (почти)... глазом ОООООЧЕНЬ заметно будетR_ura писал(а):Прошу прощения, а какая частота мигания будет в вашем варианте с прерыванием?? Мне кажется туда счетчик все-равно надо вводить.. Иначе частота будет намного выше визуально видимой..
я вам просто показал, как помигать, раз у вас даже это не выходило. а счетчик и т.п. - это уже от вашей задачи зависит...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
Re: WinAvr в вопросах и ответах
ARV писал(а):откуда ж мне знать. какая у вас тактовая частота? для таймера я включил делитель на 1024, переполнение возникнет спустя 256 этих тиков, т.е. итоговое деление тактовой частоты получается на 262144... если тактовая 1 МГц, то период мигания будет почти 8 секунд... ну а при тактовой 8 МГц - соответственно, 1 секунда (почти)... глазом ОООООЧЕНЬ заметно будетR_ura писал(а):Прошу прощения, а какая частота мигания будет в вашем варианте с прерыванием?? Мне кажется туда счетчик все-равно надо вводить.. Иначе частота будет намного выше визуально видимой..
я вам просто показал, как помигать, раз у вас даже это не выходило. а счетчик и т.п. - это уже от вашей задачи зависит...
Прошу прощения, я не хотел вас уколоть. Я не думал, что на 8 битном таймере можно организовать секундные задержки.. Спасибо, вы правы..
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18544
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: WinAvr в вопросах и ответах
я толстокожий, об меня не один ёжик иголки обломал (типа лицар)
так что ваши опасения напрасны.
просто тонкости настройки таймеров не имеют прямого отношения к WinAVR... а по сути WinAVR вы пока не сильно вопросы задаете...
просто тонкости настройки таймеров не имеют прямого отношения к WinAVR... а по сути WinAVR вы пока не сильно вопросы задаете...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
Re: WinAvr в вопросах и ответах
ARV писал(а):я толстокожий, об меня не один ёжик иголки обломал (типа лицар) : .
Так то ж вы в одном месте толстокожий - для їжаків)))))
Задам еще, дай бог прерывание включить.. Создам проект заново, а то и ваш пример не работает нифига..((
Re: WinAvr в вопросах и ответах
ARV писал(а):всегда плохо, когда в обработчике прерываний делаются задержки... так же не хорошо, когда из обработчика прерывания вызываются сторонние функции (не статические, а библиотечные). не знаю, какая у вас конкретная задача, но лично я никогда в прерываниях кнопки не обслуживаю - нет нужды. по мне, так самое простое - это в главном цикле время от времени проверять состояние кнопок, вот и все.
Спасибо. Вы не первый кто мне это говорит, но я не понимаю, ведь программа дойдя до замкнутого цикла стоит там ждёт прерываний, она же не может вернутся в начало.
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18544
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: WinAvr в вопросах и ответах
а вы продумайте алгоритм своей программы так, чтобы она в цикле не стояла, а что-то делала. и как раз опрос кнопок тут самое подходящее занятие. я уже не раз говорил: для чего нужно прерывание? для немедленной и мгновенной реакции на какое-то событие. а кнопка, которую нажимает человек, ну никак не может требовать такой реакции, ибо человек не в состоянии заметить задержку в реакции на свое действие, если эта задержка менее 0,02 секунды, а его тело вообще не в состоянии совершить какое-то действие быстрее, чем за 0,15 секунды - и то такая скорость реакции у специально тренированных людей. а 0,15 секунд для МК - это дико много, и строить работу с кнопками по прерываниям от них - это нелогично. практически любая программа любительского уровня может делаться по такому скелету:
как видите, основной цикл занят делом: он работает с кнопками и занимается изменением режима индикации. а вот все прочие функции могут делаться и по прерываниям - особенно хорошо укладывается в это динамическая индикация. можно проводить какие-товычисления и т.п. работу, а в прерываниях делать только то, что требует МГНОВЕННОЙ НЕЗАМЕДЛИТЕЛЬНОЙ реакции - например, принимать ИК-команды с пульта, следить за переходом сети через 0, принимать из USART и т.п. кстати, принимать из USART так же далеко не всегда требуется по прерываниям - иной раз проще делать это в основном цикле.
вот как-то так.
Код: Выделить всё
uint8_t get_key(void); // эта функция опрашивает порт с кнопками и возвращает код, соответствующий комбинации нажатых кнопок
void indicate(uint8_t mode); // эта функция обеспечивает индикацию в соответствии с режимом работы mode
static void init(void); // эта функция инициализирует всю аппаратуру МК
int main(void){
uint8_t mode = 0;
uint8_t key;
init();
while(1){
indicate(mode);
key = get_key();
switch(key){
case KEY1 : // тут обрабатываем нажатие первой кнопки
// если нужно - переключаем режим mode
break;
case KEY2 : // тут обрабатываем нажатие второй кнопки
// и так далее все возможные комбинации нажатий кнопок
}
}
}как видите, основной цикл занят делом: он работает с кнопками и занимается изменением режима индикации. а вот все прочие функции могут делаться и по прерываниям - особенно хорошо укладывается в это динамическая индикация. можно проводить какие-товычисления и т.п. работу, а в прерываниях делать только то, что требует МГНОВЕННОЙ НЕЗАМЕДЛИТЕЛЬНОЙ реакции - например, принимать ИК-команды с пульта, следить за переходом сети через 0, принимать из USART и т.п. кстати, принимать из USART так же далеко не всегда требуется по прерываниям - иной раз проще делать это в основном цикле.
вот как-то так.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
Re: WinAvr в вопросах и ответах
ARV писал(а):
я вам просто показал, как помигать, раз у вас даже это не выходило. а счетчик и т.п. - это уже от вашей задачи зависит...
Хе-хе.. Сделал новый проект - не пашет это прерывание.. Светодиоды не то что не мигают, а вообще не горят..)
Код: Выделить всё
#include <avr/io.h>
#include <avr/interrupt.h>
ISR(TIMER0_OVF_vect){
PORTA ^= 0xFF;
}
int main(void){
DDRA = 0xFF;
TIMSK = _BV(TOIE0);
TCCR0 = _BV(CS02) | _BV(CS00);
sei();
while(1);
}А вот такой вариант работает. Стало быть с портом все в порядке...
Код: Выделить всё
#include <avr/io.h>
#include <util/delay.h>
int main( void )
{
DDRA = 0xFF;
while(1)
{
_delay_ms(500);
PORTA ^= 0xFF;
}
return 0;
} Что за чертовщина с этим прерыванием - никак не хочет работать?
В программе на Паскале работает нормально, значит проц рабочий..
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18544
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: WinAvr в вопросах и ответах
и вправду, чертовщина у вас какая-то... пригласите попа с кадилом, пусть освятит вашу лабораторию, ибо я вот только что в студии просимулировал этот код (только поменял PORTA на PORTB, т.к. у меня заточено на atmega8) - работает, ё! как и было обещано. так что это у вас лыжи неправильные 
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
Re: WinAvr в вопросах и ответах
Вот проекты то и надо цеплять, а не голые исходники
и версию указывать.
и версию указывать.Будете проходить мимо- проходите!