|
Есть код для CodeVision. Хочу его адаптировать под WinAVR |
|
|
|
Sep 18 2006, 09:44
|
Знающий
   
Группа: Свой
Сообщений: 559
Регистрация: 6-09-06
Пользователь №: 20 131

|
Вот простенькая программка, работающая в CodeVision: Код unsigned char h=0,m=0,sec=0;
void timer_init(void) { // timer TCNT1H=TCNT1L=0; TCCR1A=0; TCCR1B=12; // cl/256 1000000/256=15625 // 15625/5=3125 OCR1A=3125; TIMSK=16; asm("sei"); }
char get_time() { sec++;
if(sec==60) {sec=0;m++;} if(m==60) {m=0;h++;} if(h==23) {h=0;} }
interrupt[TIM1_COMPA] comp(void) {get_time();} // на эту строку ругается компилятор. Посмотрел я в хидеры - в CodeVision TIM1_COMPA равняется 8. В WinAVR восьмерке соответствует SIG_OUTPUT_COMPARE1B. По моему что-то не то... В общем программка должна каждую секунду что-нибудь делать а точнее, запускать get_time(). Помогите, плз.
|
|
|
|
3 страниц
1 2 3 >
|
 |
Ответов
(1 - 34)
|
Sep 18 2006, 10:33
|
Местный
  
Группа: Участник
Сообщений: 416
Регистрация: 18-04-06
Из: Челябинск
Пользователь №: 16 219

|
Цитата(-=Женек=- @ Sep 18 2006, 12:44)  Посмотрел я в хидеры - в CodeVision TIM1_COMPA равняется 8. В WinAVR восьмерке соответствует SIG_OUTPUT_COMPARE1B. По моему что-то не то...
В общем программка должна каждую секунду что-нибудь делать а точнее, запускать get_time().
Помогите, плз. В WinAVR процедуры обработки пррываний, насколько мне известно, имеют квалификатор SIGNAL. А, а общем, смотрите руководство по компилятору. Там должно быть все написано.
|
|
|
|
|
Sep 18 2006, 11:19
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(-=Женек=- @ Sep 18 2006, 15:14)  мне бы примерчик прерывания по таймеру каждую секунду Лови: Код #include <avr/interrupt.h> #include <avr\io.h> #include <avr\iotn2313.h>
unsigned char h=0,m=0,sec=0;
void timer_init(void) { TCNT1H=TCNT1L=0; OCR1A=15624; TCCR1A=0; TCCR1B=(1<<WGM12)|(1<<CS11)|(1<<CS10); //clk/64 TIMSK=(1<<OCIE1A); }
ISR (TIMER1_COMPA_vect) { if (sec!=59) { sec++; return; } sec=0; if (m!=59) { m++; return; } m=0;
if (h!=23) { m++; return; } h=0; }
int main(int argc, char* argv[]) { timer_init(); asm("sei");
while (1);
return 0; }
|
|
|
|
|
Sep 18 2006, 11:25
|
Знающий
   
Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484

|
Цитата(-=Женек=- @ Sep 18 2006, 15:14)  мне бы примерчик прерывания по таймеру каждую секунду Пример работы с прерываниями таймера в WinAVR у вас на диску уже есть уже: X:\WinAVR\examples\demo\demo.c
|
|
|
|
|
Sep 18 2006, 11:51
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(-=Женек=- @ Sep 18 2006, 15:35)  В Вашем коде таймер не срабатывает. Кстати при компиляции выдается warning "unused parameter TIMER1_COMPA_vect"
И еще - на PD2 у меня подключена пишалка. В теле программы пока нет функции синтеза для нее звука, но при запуске вашей программы она стала жужать. )))
У меня контроллер ATMEGA32 Незнаю в чем у Вас дело, но при замене Код #include <avr/interrupt.h> #include <avr\io.h> #include <avr\iotn2313.h> на Код #include <avr/interrupt.h> #include <avr\io.h> #include <avr\iom32.h> в AVR Studio все симулируется. "unused parameter TIMER1_COMPA_vect", странно, это ведь номер прерывания.
|
|
|
|
|
Sep 18 2006, 12:14
|
Знающий
   
Группа: Свой
Сообщений: 559
Регистрация: 6-09-06
Пользователь №: 20 131

|
Вот ваша программа - я добавил туда пикалку (функция beep()). Код #include <inttypes.h> #include <stdio.h> #include <avr/interrupt.h> #include <avr\io.h> #include <avr\delay.h> #include <avr\iom32.h>
unsigned char h=0,m=0,sec=0;
beep() { int i; for (i=0;i<300;i++) { PORTD |= _BV(PD2); _delay_ms(1); PORTD &= ~_BV(PD2); _delay_ms(1); } }
void tri_beep() { beep(); _delay_ms(100); beep(); _delay_ms(100); beep(); _delay_ms(100); }
void timer_init(void) { TCNT1H=TCNT1L=0; TCCR1A=0; TCCR1B=12; // cl/256 1000000/256=15625 // 15625/5=3125 OCR1A=3125; TIMSK=16;
}
ISR (TIMER1_COMPA_vect) { beep(); }
int main(int argc, char* argv[]) { DDRD =0xFF; timer_init(); asm("sei"); while (1); return 0; } обратите внимание на комментарии перед beep в главном цикле - если комментарий убрать - пикалка звучит постоянно
Сообщение отредактировал -=Женек=- - Sep 18 2006, 12:54
|
|
|
|
|
Sep 18 2006, 12:34
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Смотрите коментарии Код #include <inttypes.h> #include <stdio.h> #include <avr\interrupt.h> #include <avr/io.h> #include <avr\delay.h> #include <avr\iom32.h>
unsigned char h=0,m=0,sec=0;
beep() // <--------------------------Примерно 600ms - 0,6sek { int i; for (i=0;i<300;i++) { PORTA |= _BV(PA2); _delay_ms(1); PORTA &= ~_BV(PA2); _delay_ms(1); } }
void tri_beep() { beep(); _delay_ms(100); beep(); _delay_ms(100); beep(); _delay_ms(100); }
void timer_init(void) { TCNT1H=TCNT1L=0; OCR1A=15624; TCCR1A=0; TCCR1B=(1<<WGM12)|(1<<CS11)|(1<<CS10); //clk/64 TIMSK=(1<<OCIE1A); }
ISR (TIMER1_COMPA_vect) {
if (sec!=59) { beep(); //<--------- каждую сек beep - 0,6sek sec++; return; } sec=0; if (m!=59) { m++; return; } m=0;
if (h!=23) { m++; return; } h=0; }
int main(int argc, char* argv[]) { DDRA =0xFF; //beep();
timer_init(); asm("sei"); while (1); return 0; } обратите внимание на комментарии перед beep в главном цикле - если комментарий убрать - пикалка звучит постоянно [/quote] Вызывать задержки из прерывания, да и еще такой длительности Ваша программа только и делает что сидит в прерывании и пикает
|
|
|
|
|
Sep 18 2006, 12:41
|
Знающий
   
Группа: Свой
Сообщений: 559
Регистрация: 6-09-06
Пользователь №: 20 131

|
Хочу вам сказать, что с _delay_ms у меня явно какф-то фигня... Вообще, блин.. начинаю ненавидеть WinAVR. В CodeVision все было как говорится "what you see is what you get". Все что я делал получалось с первого или почти с первого раза. Тут же - проблема на проблеме... Так вот... delay_ms генерирует задежрку раз этак в 10 меньше чем указываешь. Так что там не 0,6 сек. Цитата Вызывать задержки из прерывания, да и еще такой длительности Ваша программа только и делает что сидит в прерывании и пикает Да дело не в этом - beep в обработчике прерывания вообще не вызывается. А работает beep тот, который ЕДИНОЖДЫ встречается в главном цикле. Вы невнимательно читали мой код.
|
|
|
|
|
Sep 18 2006, 12:55
|
Знающий
   
Группа: Свой
Сообщений: 559
Регистрация: 6-09-06
Пользователь №: 20 131

|
Цитата Судя по всему у Вас постоянно происходит ресет. Хорошая мысль, ибо установка с помощью CSx делителя не влияет на характер звука. Что за собака? Объясните. См. выше пост №8- я привел код таким, какой он есть сейчас. Пикалка молчит.
|
|
|
|
|
Sep 18 2006, 13:04
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(-=Женек=- @ Sep 18 2006, 16:55)  Цитата Судя по всему у Вас постоянно происходит ресет. Хорошая мысль, ибо установка с помощью CSx делителя не влияет на характер звука. Что за собака? Объясните. См. выше пост №8- я привел код таким, какой он есть сейчас. Пикалка молчит. собака = Watchdog Timer если включить, выполняет ресет через опред. время (подробнее в Datasheet) Ищите почему у Вас происходит Reset.
|
|
|
|
|
Sep 18 2006, 13:27
|
Знающий
   
Группа: Свой
Сообщений: 559
Регистрация: 6-09-06
Пользователь №: 20 131

|
ПРочел. биты 0 и 1 равны единице. А вот мои фьюзы: Код Fuses OSCCAL = CB, CB, C4, C5 BLEV = 1 BODEN = 1 SUT = 2 CKSEL = F BLB1 = 3 BLB0 = 3 OCDEN = 1 JTAGEN = 1 CKOPT = 0 EESV = 1 BSIZ = 0 BRST = 1
|
|
|
|
|
Sep 18 2006, 14:17
|
Знающий
   
Группа: Свой
Сообщений: 559
Регистрация: 6-09-06
Пользователь №: 20 131

|
к разъему для программирования. У меня Altera byte blaster, который можно не снимать после программирования. А еще кнопочка от ресета идет на питание для ручного сброса. Вот еще что: Код void timer_init(void) { TCNT1H=TCNT1L=0; TCCR1A=0; TCCR1B=12; // cl/256 1000000/256=15625 15625/5=3125 OCR1A=3125; //TIMSK=16;
} после комментирования строки TIMSK=16 контроллер перестает ресетиться.
|
|
|
|
|
Sep 18 2006, 14:42
|
Знающий
   
Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484

|
Цитата(-=Женек=- @ Sep 18 2006, 15:35)  В Вашем коде таймер не срабатывает. Кстати при компиляции выдается warning "unused parameter TIMER1_COMPA_vect" В ранних версиях 'avr-libv' для описания функции обработчика прерывания использовалось макро SIGNAL(), сейчас оно переименовано в ISR(). Посмотрите в определено ли в файле 'avr/interrupt.h' ISR()? Какая у вас версия WinAVR? Анатолий.
|
|
|
|
|
Sep 18 2006, 15:18
|
Знающий
   
Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484

|
Цитата(-=Женек=- @ Sep 18 2006, 19:12)  У меня WinAVR-20050214
в interrupt.h нет не SIGNAL() не ISR() Но компилятор не ругается на ISR (TIMER1_COMPA_vect)
через поиск попробовал найти файлы содержащие строку "ISR" - не найдено тогда вместо ISR(...) должно быть: SIGNAL(SIG_OUTPUT_COMPARE1A) PS: Если компилятор сказал "warning" - это не значит что нет ошибки. Анатолий. ADD: И добавте еще: #include <avr/signal.h>
Сообщение отредактировал aesok - Sep 18 2006, 15:48
|
|
|
|
|
Sep 18 2006, 15:32
|
Знающий
   
Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484

|
Цитата(-=Женек=- @ Sep 18 2006, 19:14)  в очередной раз задаюсь вопросом - почему в CodeVision все работает как часы, а в WinAVR, который хвалят как очень рациональную программу - вечно какие-то проблемы... В WinAVR конечно-же есть проблемы, но в данном случае претензии к нему не уместны. Кто Вам мешает открыть файл X:\WinAVR\doc\avr-libc\avr-libc-user-manual.pdf и посмотреть как нужно определять прерывания. Прерывания не определены в стандарте на язык C, и каждый разработчик компилятора имеет право придумать свой синтаксис. Анатолий.
|
|
|
|
|
Sep 18 2006, 15:55
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(-=Женек=- @ Sep 18 2006, 18:17)  к разъему для программирования. У меня Altera byte blaster, который можно не снимать после программирования. А еще кнопочка от ресета идет на питание для ручного сброса. 1. Отключите таки ByteBlaster и проверте что reset подтянут к питанию(через резистор). 2. флаг EXTRF в регистре MCUCSR однозначно указывает на то что у Вас происходит External Reset. 3. И наконец смените вот этот код: Код void timer_init(void) { TCNT1H=TCNT1L=0; TCCR1A=0; TCCR1B=12; // cl/256 1000000/256=15625 15625/5=3125 OCR1A=3125; TIMSK=16;
} 1000000/256=15625  это круто 15625/5=3125 откуда взялась 5 ? 1000000/256=3906,25 при ваших установках получаем: OCR1=3125 T=(OCR1+1)*256=3126*256=800256 мкс Я Вам настоятельно рекомендую сменить Вот на это: Код TCNT1H=TCNT1L=0; OCR1A=15624; TCCR1A=0; TCCR1B=(1<<WGM12)|(1<<CS11)|(1<<CS10); //clk/64 1000000/64=15625 TIMSK=(1<<OCIE1A); T=(OCR1+1)*64=15625*64=1000000 , т.е. ровно 1 сек.
|
|
|
|
|
Sep 18 2006, 16:39
|
Знающий
   
Группа: Свой
Сообщений: 559
Регистрация: 6-09-06
Пользователь №: 20 131

|
УУУААААУУУУУУУ!!!! Заработало!!!!!! Оказалось нужны были обе меры - и SIGNAL(SIG_OUTPUT_COMPARE1A) и #include.... Теперь я понял, почему компилятор не ругался на ISR - он думал, что я определяю новую функцию с именем ISR, потому и выдавал warning по поводу unused parameter в ней. Всем спасибо!!!! Теперь все работает как часы. Цитата T=(OCR1+1)*64=15625*256=1000000 , т.е. ровно 1 сек. Я вам верю, но пикает явны больше 1 раза в секнуду. Сейчас у меня вот что: Код OCR1A = 0xf424; OCR1B = 0xf424; TCNT1 = 0x0bdc; TCCR1A = 0x00; TCCR1B = 0x04; TIMSK=16; сгенерировал при помощи AtmanAvr
|
|
|
|
|
Sep 18 2006, 16:54
|
Местный
  
Группа: Свой
Сообщений: 200
Регистрация: 10-04-06
Из: Украина,Запорожье
Пользователь №: 15 979

|
Цитата(-=Женек=- @ Sep 18 2006, 19:14)  У меня WinAVR-20050214
в interrupt.h нет не SIGNAL() не ISR() Но компилятор не ругается на ISR (TIMER1_COMPA_vect)
через поиск попробовал найти файлы содержащие строку "ISR" - не найдено
в очередной раз задаюсь вопросом - почему в CodeVision все работает как часы, а в WinAVR, который хвалят как очень рациональную программу - вечно какие-то проблемы... Перейти на WinAVR я был вынужден, так как библиотека для моего LCD есть только для WinAVR В таком случае можно посоветовать AtmanAVR.Тот же GCC только удобства такие же как в CV и гемора с созданием проета нету(СodeЦizard,генерация makefile). Имеется плугины там под LCD и еще чтото.Правда триальный период 30 дней,но лекарство в сети имеется. http://www.atmanecl.com/EnglishSite/SoftwareEnglish.htm
|
|
|
|
|
Sep 18 2006, 17:20
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата У меня WinAVR-20050214
в interrupt.h нет не SIGNAL() не ISR() Но компилятор не ругается на ISR (TIMER1_COMPA_vect) А у меня WinAVR-20060421 и ISR в interrupt.h есть Цитата(-=Женек=- @ Sep 18 2006, 20:39)  Цитата T=(OCR1+1)*64=15625*64=1000000 , т.е. ровно 1 сек. Я вам верю, но пикает явны больше 1 раза в секнуду. Сейчас у меня вот что: Код OCR1A = 0xf424; OCR1B = 0xf424; TCNT1 = 0x0bdc; TCCR1A = 0x00; TCCR1B = 0x04; TIMSK=16; сгенерировал при помощи AtmanAvr Ну это конечно Ваше дело. Те установки которые я давал, дают точно 1 сек. на кварце 1МГц.
|
|
|
|
|
Sep 18 2006, 17:59
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(-=Женек=- @ Sep 18 2006, 21:25)  А функция _delay_ms() из delay.h как должна испльзоваться? в хидере установлена частота 1 МГц. Менять хидер под новый кварц? Кстати #define F_CPU 16000000UL в фале программы не помогает. -=Женек=- Убедительная просьба к Вам, в следующий раз задавая вопрос пишите сразу же примерно так: чип ATmega32 clock 16МГц компилятор WinAVR-XXXXXXXX далее суть проблемы... Иначе слишком много времени тратится зря
|
|
|
|
|
Sep 18 2006, 18:35
|
Знающий
   
Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484

|
Цитата(-=Женек=- @ Sep 18 2006, 21:25)  А функция _delay_ms() из delay.h как должна испльзоваться? в хидере установлена частота 1 МГц. Менять хидер под новый кварц? Кстати #define F_CPU 16000000UL в фале программы не помогает. Я не использовал _delay_ms[us](). Но если F_CPU задаеться в Makefile то та установка будет иметь более высокий приоритет. Посмотрите чему равна F_CPU в Makefile и задайте правильное значение. Анатолий.
|
|
|
|
|
Sep 18 2006, 19:11
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(-=Женек=- @ Sep 18 2006, 20:39)  Сейчас у меня вот что: Код OCR1A = 0xf424 TCNT1 = 0x0bdc; TCCR1A = 0x00; TCCR1B = 0x04; TIMSK=16; сгенерировал при помощи AtmanAvr неправильно ! должно быть: Код OCR1A = 0xf423 TCNT1 = 0; TCCR1A = 0x00; TCCR1B = 0x04; TIMSK=16;
|
|
|
|
|
Sep 18 2006, 19:33
|
Знающий
   
Группа: Свой
Сообщений: 559
Регистрация: 6-09-06
Пользователь №: 20 131

|
Я уже сделал, как мне советовали. Код TCNT1H=TCNT1L=0; OCR1A=15624; TCCR1A=0; TCCR1B=(1<<WGM12)|(1<<CS12)|(1<<CS10); TIMSK=(1<<OCIE1A); ТОлько делитель поменял, учитывая что частота 16 МГц
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|