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

 
 
> Мой первый блин), Перехожу на Си
novlev
сообщение Oct 6 2009, 13:08
Сообщение #1


Частый гость
**

Группа: Участник
Сообщений: 116
Регистрация: 24-09-06
Пользователь №: 20 645



CODE
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/wdt.h>
volatile int i = 0;
int main()
{
PORTE = 0x01;
DDRE = 0x7F;

wdt_disable();


TCNT0 = 0x00;
TCCR0A = 0;
TCCR0B = 3;
TIFR0 = 0;
TIMSK0 = 0x01;
sei();
//cli();
while (1)
{

if (PORTK == 255)
PORTK = 0;
else
PORTK++;

}
}


ISR(TIMER0_OVF_vect)
{
//TCNT0 = 0x00;

if(i++ == 0xFF55)
{
PORTE ^= 0x01;
i = 0;
}
}


Суть проблемы - прерывание срабатывает, но на ноге порта Е никаких изменений, а если убрать условие (if) то все норм. Чиво не так сделал?
Заранее спасибо.
Причина редактирования: Нарушение правил цитирования исходников.
Go to the top of the page
 
+Quote Post
4 страниц V  < 1 2 3 4 >  
Start new topic
Ответов (15 - 29)
Ledmaster
сообщение Oct 6 2009, 14:43
Сообщение #16


Частый гость
**

Группа: Свой
Сообщений: 142
Регистрация: 18-02-08
Из: Челябинск
Пользователь №: 35 141



А так?
Код
unsigned char i = 0x00;
ISR(TIMER0_OVF_vect)
{
    i++;
    if(i == 0x55)
        {
            PORTE ^= 0x01;
            i = 0;
        }
}
Go to the top of the page
 
+Quote Post
novlev
сообщение Oct 6 2009, 14:48
Сообщение #17


Частый гость
**

Группа: Участник
Сообщений: 116
Регистрация: 24-09-06
Пользователь №: 20 645



Цитата(_Pasha @ Oct 6 2009, 17:37) *
Объявите в теле прерывания как static. Или глобально volatile unsigned char i=0;


Я проверил оба эти варианта, на осмыслографе ожидаемы пеньки не появились...


Цитата(Ledmaster @ Oct 6 2009, 17:43) *
А так?

Пробовал, но без комбинации глобальная/статическая переменная.

Последняя на сегодня мысль, поставлю 16 вместо 17 студии, проверю еще так. И WinAVR переставлю.
Причина редактирования: Излишнее цитирование.
Go to the top of the page
 
+Quote Post
OLEG_BOS
сообщение Oct 6 2009, 15:16
Сообщение #18


Местный
***

Группа: Свой
Сообщений: 386
Регистрация: 1-12-05
Пользователь №: 11 639



Цитата(novlev @ Oct 6 2009, 17:48) *
Последняя на сегодня мысль, поставлю 16 вместо 17 студии, проверю еще так. И WinAVR переставлю.


ОFFTOP a14.gif
Если не получится попробуйте еще и Windows переставить. А если и это не поможет то и комп. сменить biggrin.gif

А если серьезно - откройте книжку по "Си" и почитайте там об типах переменных, их расположением в памяти ( я имею ввиду ключевые слова static и volatile) . Тогда и не надо будет ничего переставлять - путь длинный но зато надежный и с малым количеством "грабель" в будущем wink.gif

P.S. Кстати у Вас там используется порт E контроллера. А у Вас какой контроллер ( я так думаю Atmega64(128)) - есть там порт Е ? smile.gif
Go to the top of the page
 
+Quote Post
novlev
сообщение Oct 6 2009, 17:48
Сообщение #19


Частый гость
**

Группа: Участник
Сообщений: 116
Регистрация: 24-09-06
Пользователь №: 20 645



Цитата(OLEG_BOS @ Oct 6 2009, 18:16) *
ОFFTOP a14.gif
Если не получится попробуйте еще и Windows переставить. А если и это не поможет то и комп. сменить biggrin.gif

А если серьезно - откройте книжку по "Си" и почитайте там об типах переменных, их расположением в памяти ( я имею ввиду ключевые слова static и volatile) . Тогда и не надо будет ничего переставлять - путь длинный но зато надежный и с малым количеством "грабель" в будущем wink.gif

P.S. Кстати у Вас там используется порт E контроллера. А у Вас какой контроллер ( я так думаю Atmega64(128)) - есть там порт Е ? smile.gif


Спасибо за помощь, но ерничать все же не стоит.. С типами данных я знаком, на сях пишу достаточно долго (С#), таких вот проблем))) с типами не встречал. Просто в первый же день захотел много). А проц обычная атмега640. Задача у меня - бутлоадер написать, поэтому и решил на си. Если кто сталкивался или сразу видит причину - ткните уже носом меня, и если есть дока по подводным камням авр студии - поделитесь, пожалуйста. Всем еще раз спасибо.

Сообщение отредактировал novlev - Oct 6 2009, 18:11
Go to the top of the page
 
+Quote Post
INT1
сообщение Oct 6 2009, 18:31
Сообщение #20


deleted
****

Группа: Свой
Сообщений: 555
Регистрация: 28-08-05
Пользователь №: 8 024



Я конечно не спец по Си , но чегото бросилось в глаза, PORTK++;, а так можно делать? И не плохо бы указать, какому компилятору(реализации) вы это поручаете, а то я чегото все время уверен, что это наверняка ИАР smile.gif.
Go to the top of the page
 
+Quote Post
novlev
сообщение Oct 6 2009, 18:46
Сообщение #21


Частый гость
**

Группа: Участник
Сообщений: 116
Регистрация: 24-09-06
Пользователь №: 20 645



Цитата(INT1 @ Oct 6 2009, 21:31) *
Я конечно не спец по Си , но чегото бросилось в глаза, PORTK++;, а так можно делать? И не плохо бы указать, какому компилятору(реализации) вы это поручаете, а то я чегото все время уверен, что это наверняка ИАР smile.gif.

PORTK++ - думаю можно, взяли что было, инкремент и перезаписали. По поводу чему я это поручаю... Есть в студии привязка к WinAVR-20090313, там есть утилиты avr-gcc.exe(компилятор
языков C и C++ для AVR) и make.exe(автоматический генератор Make-файлов for AVR GCC), пока это все что я знаю) я пока еще не освоился во всем обилии средств рвзработки...
А что посоветуете? просто "будет работать из коробки" не состоялось))

Сообщение отредактировал novlev - Oct 6 2009, 19:10
Go to the top of the page
 
+Quote Post
INT1
сообщение Oct 6 2009, 19:08
Сообщение #22


deleted
****

Группа: Свой
Сообщений: 555
Регистрация: 28-08-05
Пользователь №: 8 024



Насколько помнится операции над портом (если мы говорим про МК) типа инкркемент и т.п. напрямую производить нельзя. Т.е. туда(в регистр порта) можно или писать или читать. Т.е. нужно объявить переменную, сделать с ней что захотеть, а потом значенеие записать в порт.
ЗЫ, хотя компилятор должен был бы заматериться на это дело (почему и спросил про реализацию). Но подробно в вашу проблему не вникал, извините ...smile.gif
Go to the top of the page
 
+Quote Post
novlev
сообщение Oct 6 2009, 19:43
Сообщение #23


Частый гость
**

Группа: Участник
Сообщений: 116
Регистрация: 24-09-06
Пользователь №: 20 645



Цитата(INT1 @ Oct 6 2009, 22:08) *
насколько помнится операции над портом (если мы говорим проМК) типа инкркемент и т.п. напрямую производить нельзя. Т.е. туда можно или писать или читать. Т.е. объявить переменную, сделать с ней что захотеть, а потом значенеие записать в порт.


Ничего утверждать не берусь, но вот пример дизасма:
Код
23:       if (PORTK == 255)
+00000099:   91800108    LDS       R24,0x0108     Load direct from data space
+0000009B:   3F8F        CPI       R24,0xFF       Compare with immediate
+0000009C:   F419        BRNE      PC+0x04        Branch if not equal
24:       PORTK = 0;
+0000009D:   92100108    STS       0x0108,R1      Store direct to data space
+0000009F:   CFF9        RJMP      PC-0x0006      Relative jump
26:       PORTK++;
+000000A0:   91800108    LDS       R24,0x0108     Load direct from data space
+000000A2:   5F8F        SUBI      R24,0xFF       Subtract immediate
+000000A3:   93800108    STS       0x0108,R24     Store direct to data space
+000000A5:   CFF3        RJMP      PC-0x000C      Relative jump

Никаких замечаний и ошибок нет, эмулятор все корректно отображает. И под volatile unsigned int выделил 2 байта. Т е в теории все красиво.

Вот пример моего мейкфайла.
Прикрепленные файлы
Прикрепленный файл  Makefile.rar ( 942 байт ) Кол-во скачиваний: 16
 
Go to the top of the page
 
+Quote Post
314
сообщение Oct 6 2009, 20:02
Сообщение #24


Частый гость
**

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



Попробовал Ваш пример на отладчике в AVR Studio, только под мегу168 сменил таргет в makefile и порты К и Е заменил на В и С (новый WinAVR еще не поставил, нет библиотеки под м640). В отладчике все идет без проблем, значение пина меняется как и ожидалось.
Go to the top of the page
 
+Quote Post
novlev
сообщение Oct 6 2009, 20:55
Сообщение #25


Частый гость
**

Группа: Участник
Сообщений: 116
Регистрация: 24-09-06
Пользователь №: 20 645



Да, более того, статическая переменная действительно оказалась статической, код генерируется адекватный(на эмуляторе). Никаких допущений и упращений. Я просто думал поначалу, что компилятор упрощенный или что-то такое, все оказалось нормально. По коду при одна инициализация и сохранение, все честно.
Go to the top of the page
 
+Quote Post
singlskv
сообщение Oct 6 2009, 21:41
Сообщение #26


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(novlev @ Oct 6 2009, 17:08) *
CODE

if (PORTK == 255)
PORTK = 0;
else
PORTK++;
А зачем здесь вобще нужен if ? достаточно просто PORTK++;
или Вы думаете что прибавление 1 к unsigned volatile char переменной в которой уже 255 может дать что-нить кроме 0 ?



Цитата(INT1 @ Oct 6 2009, 23:08) *
Насколько помнится операции над портом (если мы говорим про МК) типа инкркемент и т.п. напрямую производить нельзя. Т.е. туда(в регистр порта) можно или писать или читать. Т.е. нужно объявить переменную, сделать с ней что захотеть, а потом значенеие записать в порт.
Это верно только для процов в которых разделены регистры записи/стирания бита (ARM непример),
для AVR здесь все валидно,
PORTK++; <=> PORTK = PORTK + 1;
то есть сначала считать, инкрементировать и затем записать
Go to the top of the page
 
+Quote Post
novlev
сообщение Oct 6 2009, 21:46
Сообщение #27


Частый гость
**

Группа: Участник
Сообщений: 116
Регистрация: 24-09-06
Пользователь №: 20 645



Код
if (PORTK == 255)
PORTK = 0;
else
PORTK++;


Ну если честно, эта конструкция там просто так, чтобы небыло пустого цикла while(1). Предметом обсуждения была многострадальная переменная i, из-за которой
if не давал истину.
Go to the top of the page
 
+Quote Post
314
сообщение Oct 7 2009, 05:49
Сообщение #28


Частый гость
**

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



Как-то это все больше смахивает на какие-то внешние причины. Например: использование альтернативной функции порта, наличие сбросов и перезапусков программы, так что переменная i просто не успевает накопиться и т.д. (кстати, может, когда увеличили частоту переключения, то начало успевать переключаться до сброса). Это можно проверить, вставив в начало программы до начала основного кода сигнал 1 на какой-нибудь безобидный пин. При перезапуске выходы переводятся в состяние входов (можно сказать Z-состояние)где-то на 100мкс-10мс, смотря как задали стартовые задержки, и осциллографом это можно увидеть (подтяжку на -5В 1-5к не забудьте). И наверное есть смысл отключить WDR timer в фусовых битах (галочку на WDTON снимите, если стоит, или впишите в обработчик прерывания wdt_reset () ).

Вот Вам еще довесок из даташита на м640

The Watchdog always on (WDTON) fuse, if programmed, will force the Watchdog Timer to Sys-
tem Reset mode. With the fuse programmed the System Reset mode bit (WDE) and Interrupt

Если не ошибаюсь, то WDTON для м640 из программы не доступен, только с программатора.
Go to the top of the page
 
+Quote Post
novlev
сообщение Oct 7 2009, 06:04
Сообщение #29


Частый гость
**

Группа: Участник
Сообщений: 116
Регистрация: 24-09-06
Пользователь №: 20 645



Цитата(314 @ Oct 7 2009, 08:49) *
И наверное есть смысл отключить WDR timer в фусовых битах (галочку на WDTON снимите, если стоит, или впишите в обработчик прерывания wdt_reset () ).


Да, действительно - сбрасывается. Буду искать причину. Огромное спасибо.
Причина редактирования: Нарушение п.3.4 Правил форума.
Go to the top of the page
 
+Quote Post
dimka76
сообщение Oct 7 2009, 06:13
Сообщение #30


developer
****

Группа: Свой
Сообщений: 902
Регистрация: 12-04-06
Из: Казань
Пользователь №: 16 032



Цитата(novlev @ Oct 7 2009, 01:46) *
Предметом обсуждения была многострадальная переменная i, из-за которой if не давал истину.


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


--------------------
Все может быть и быть все может, и лишь того не может быть-чего уж точно быть не может, хотя..и это может быть.
Go to the top of the page
 
+Quote Post

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

 


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


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