#1 2020-03-20 18:40:59

VLDnepr
Участник
Из г.Днепр
Зарегистрирован: 2020-02-04
Сообщений: 17

Помогите начинающему с ATMega128

Помогите, пожалуйста, разобраться.
Наинаю осваивать программирование контроллеров.
До этого немного покаталсяна меге16, все относительно понятно и получалось
Решил перейти на мега 128 - не могу запустить простое мигание светодиодом через прерывание

Если закоментировать sei(); работает основной цикл.
Но при раскоментировании зажигается PA4 и горит постоянно, а PD5 (основной цикл) не моргает.

Не понимаю почему не работает основной цикл?

#define F_CPU 8000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>

ISR(TIMER0_OVF_vect)
{
    PORTA |= (1<<PA4);
}



int main(void)
{
    //TIMER0 -------------------------------------------------
    TCCR0 |= (1<<CS02)|(1<<CS00); // устанавливаем прескалер - 1024
    TIFR = 1<<TOV0; // очищаем флаг прерывания таймера Т0
    TIMSK |= 1<<TOIE0; // разрешаем прерывание по переполнению
    TCNT0 = 0; // загружаем начальное зн. в счетный регистр

    sei();

        DDRA = 0xFF;
        DDRD = 0xFF;
   
    PORTA |= (1<<PA4); _delay_ms(500);
    PORTD |= (1<<PD5); _delay_ms(500);

    PORTA = 0;
    PORTD = 0;
    while (1)
    {
        PORTD ^= (1<<PD5); _delay_ms(500);
    }
}

Редактировался VLDnepr (2020-03-20 18:41:50)

#2 2020-03-20 19:03:37

Watchdog
Гость

Re: Помогите начинающему с ATMega128

Всё правильно работает. Вы только включаете светодиод, в прерывании, и никогда не выключаете. И видимо так часто, что основной программе не достаётся процессорного времени. А почему догадайтесь сами. wink

#3 2020-03-20 19:18:33

VLDnepr
Участник
Из г.Днепр
Зарегистрирован: 2020-02-04
Сообщений: 17

Re: Помогите начинающему с ATMega128

это понятно, в прерывании просто тестовый код.
Почему перестает работать основной цикл, вот в чем вопрос? PD5 не моргает, просто не горит.

#4 2020-03-20 21:12:14

Watchdog
Гость

Re: Помогите начинающему с ATMega128

VLDnepr пишет:

это понятно, в прерывании просто тестовый код.
Почему перестает работать основной цикл, вот в чем вопрос? PD5 не моргает, просто не горит.

Что то не так. Смотрите примеры и эрраты. Хоть AVR и сбрасыват флаги запросов прерываний автоматически, попробуйте сбрасывать флаг переполнения счетчика, в конце ISR, программно.

#5 2020-03-22 11:13:48

Kaka
Участник
Зарегистрирован: 2018-03-21
Сообщений: 353

Re: Помогите начинающему с ATMega128

Давай разбираться.

1. Внимательно посмотри даташит и исправь вот эту строчку, ты ту явно не 1024 устанавливаешь:

VLDnepr пишет:

TCCR0 |= (1<<CS02)|(1<<CS00); // устанавливаем прескалер - 1024

В остальном так: у меня твой код работает - нормально мигает. Поэтому, смотри на фьюзы, всё ли там в порядке. Далее, убедись, что USART1 выключен (заткни его принудительно), иначе он переопределяет пин PD5 под себя.

И общий совет (в данном коде ни на что не влияет, но может аукнуться в другом). Когда ты впервые инициализируешь таймер (или ещё чего), делай это полностью. Не надейся, что там было что-то разумное до тебя. Вот зачем ты используешь |=, а не присваивание? Тебе важно сохранить то, что было в других битах до тебя? Зачем? Ты знаешь, что там было? При включении питания - умолчательные значения (см. даташит), а вот, например, если будешь делать это в среде той же ардуино, с удивлением обнаружишь, что в настройках таймера уже поковырялись до тебя и сохраняя "старые" биты, ты неправильно настраиваешь таймер. Т.е. при первой настройке - настраиваем все регистры и все биты.

#6 2020-03-22 16:32:11

Watchdog
Гость

Re: Помогите начинающему с ATMega128

Kaka пишет:

... В остальном так: у меня твой код работает - нормально мигает. ...

Значит начинающий, что-то темнит. Если с запрещенными прерываниями работает, а с разрешёнными нет. То вывод очевиден; или бесконечный цикл обработки прерываний (по таинственной причине), или дефективный чип, или что-то темнит, всё-таки.

#7 2020-03-22 20:49:27

Kaka
Участник
Зарегистрирован: 2018-03-21
Сообщений: 353

Re: Помогите начинающему с ATMega128

Watchdog пишет:

темнит, всё-таки.

Через раз напарываешься на умника, который выкладывает не свой код, а скачанный откуда-нибудь (и схему тоже) и потом говорит, так я там ничего не менял, ну вот только ... но это же ни на что не влияет! Или выкладывает сокращённый код из которого он выбросил то, по его просвещённому мнению "ни на что не влияет".

Один деятель, как-то вылез типа analogRead на тини'85 не работает. Скетч выложил. Вроде, должен работать. И так его пытали и эдак, через полдня вымогли, что это скетч из статьи, и заставили таки выложить именно его скетч, копи-пастом (таки выложил, когда уже "утюгом пытать начали"). При этом невинно так: "да, такой же точно скетч, только с другого пина читаю, какая нахрен разница, мне с того удобнее!". Вот так, полдня потратили, чтобы таки узнать, что поциент пытался на 85-ой тиньке analogRead'ом пин ADC0 читать! Так, сука, хоть бы извинился, что полдня из-за него с левым скетчем трахались - нет, ещё и мудаками обозвал - недостаточно вежливо ему всё объяснили.

Редактировался Kaka (2020-03-22 20:55:41)

#8 2020-03-23 12:15:17

VLDnepr
Участник
Из г.Днепр
Зарегистрирован: 2020-02-04
Сообщений: 17

Re: Помогите начинающему с ATMega128

Ребята, Вы конечно может быть и великие Знайки, но я ничего не темню и не скрываю, мне хочется просто понять что я делаю не так, или где ковырять чтобы разобраться.

Еще раз
1.Полный код приведен ниже, контроллер atmega128a, 8 мг
2.Не суть какой делитель устанавлиывется, суть вопроса в прекращении работы основного цикла
3.Сгенерировал настройки таймера в CodeVisionAVR
4.Фьюзы как по мне тут непричем, ну или подскажите как они влияют.
5.Из подключенный внешних устройств только USBASP на USART0.
6.Только что рассмотрел, что при подаче питания сразу зажигается PA4 и больше ничего не происходит.
7.Если закоментировать TIMSK=...  и ETIMSK=.... - все работает как написано, т.е. код в преравыние не заходит, т.к. перавание таймара не разрешено, основной цикл моргает.


Что то-то не так, не понимаю что именно.
Буду благодарен, если подскажете.

#define F_CPU 8000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>

volatile unsigned char z1;

ISR(TIMER0_OVF_vect)
{
    TCNT0=0xB2;

    z1++;
    if (z1<=250) {return;}
       
    z1=0;   
    PORTA ^= (1<<PA4);
}

int main(void)
{
   
//TIMER0 -------------------------------------------------
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 7,813 kHz
// Mode: Normal top=0xFF
// OC0 output: Disconnected
// Timer Period: 9,984 ms
ASSR=0<<AS0;
TCCR0=(0<<WGM00) | (0<<COM01) | (0<<COM00) | (0<<WGM01) | (1<<CS02) | (1<<CS01) | (1<<CS00);
TCNT0=0xB2;
OCR0=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=(0<<OCIE2) | (0<<TOIE2) | (0<<TICIE1) | (0<<OCIE1A) | (0<<OCIE1B) | (0<<TOIE1) | (0<<OCIE0) | (1<<TOIE0);
ETIMSK=(0<<TICIE3) | (0<<OCIE3A) | (0<<OCIE3B) | (0<<TOIE3) | (0<<OCIE3C) | (0<<OCIE1C);


    DDRA = 0xFF;
    DDRD = 0xFF;
    PORTA = 0;
    PORTD = 0;
    z1=0;
   
    sei();

    PORTA |= (1<<PA4); _delay_ms(1000);
    PORTD |= (1<<PD5); _delay_ms(1000);

    PORTA = 0;
    PORTD = 0;

    while (1)
    {
        PORTD ^= (1<<PD5); _delay_ms(500);
    }
}

#9 2020-03-23 13:18:16

Watchdog
Гость

Re: Помогите начинающему с ATMega128

VLDnepr пишет:

Ребята, Вы конечно может быть и великие Знайки, ...

Проверьте все цифры, в определениях TIMER0_OVF_vect, TIMSK, ETIMSK (все те, что используете), а точнее их соответствие реальным. Всякое бывает, опечатки, и.т.п. Выбросите всё лишнее, оставьте ISR пустым, и воспроизведите конфликт. На все вектора неиспользуемых прерываний установите ISR c индикацией их вызовов. Ошибки могут быть где угодно, вплоть до "дохлого" чипа, компилятора и мозгов.

Мы возможно знайки,
Но вы прям скажем зайки!
В этом деле суть и соль
Есть на заднице мозоль.

lol

#10 2020-03-23 14:25:24

VLDnepr
Участник
Из г.Днепр
Зарегистрирован: 2020-02-04
Сообщений: 17

Re: Помогите начинающему с ATMega128

Код в посте выше приводил копипастом, без правки.
Результат тотже, если раскоментировать строки установки TIMSK - сразу после сброса зажигается первый светодиод (в данном коде это PD5) и все. Такое ощущение что программа вешается на
_delay_ms(1000);

потому как если раскоментировать строку
//PORTA |= (1<<PA4); _delay_ms(1000);

записало все после зажигания PA4, это все при том что сейчас обработчик ISR(TIMER0_OVF_vect) пустой

может ли зависать _delay_ms?




#define F_CPU 8000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>

volatile unsigned char z1;

ISR(TIMER0_OVF_vect)
{
}

ISR(INT1_vect){PORTD |= (1<<PA3);}
ISR(INT2_vect){PORTD |= (1<<PA3);}
ISR(INT3_vect){PORTD |= (1<<PA3);}
ISR(INT4_vect){PORTD |= (1<<PA3);}
ISR(INT5_vect){PORTD |= (1<<PA3);}
ISR(INT6_vect){PORTD |= (1<<PA3);}
ISR(INT7_vect){PORTD |= (1<<PA3);}
   
ISR(TIMER0_COMP_vect){PORTD |= (1<<PA5);}

ISR(TIMER1_CAPT_vect){PORTD |= (1<<PA5);}
ISR(TIMER1_COMPA_vect){PORTD |= (1<<PA5);}
ISR(TIMER1_COMPB_vect){PORTD |= (1<<PA5);}
ISR(TIMER1_OVF_vect){PORTD |= (1<<PA5);}
   
ISR(TIMER3_CAPT_vect){PORTD |= (1<<PA6);}
ISR(TIMER3_COMPA_vect){PORTD |= (1<<PA6);}
ISR(TIMER3_COMPB_vect){PORTD |= (1<<PA6);}
ISR(TIMER3_COMPC_vect){PORTD |= (1<<PA6);}
ISR(TIMER3_OVF_vect){PORTD |= (1<<PA6);}
ISR(USART1_RX_vect){PORTD |= (1<<PA6);}
ISR(USART1_UDRE_vect){PORTD |= (1<<PA6);}
ISR(USART1_TX_vect){PORTD |= (1<<PA6);}
ISR(TWI_vect){PORTD |= (1<<PA6);}
ISR(SPM_READY_vect){PORTD |= (1<<PA6);}
   
   
int main(void)
{
   
//TIMER0 -------------------------------------------------
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 7,813 kHz
// Mode: Normal top=0xFF
// OC0 output: Disconnected
// Timer Period: 9,984 ms
ASSR=0<<AS0;
TCCR0=(0<<WGM00) | (0<<COM01) | (0<<COM00) | (0<<WGM01) | (1<<CS02) | (1<<CS01) | (1<<CS00);
TCNT0=0xB2;
OCR0=0x00;


// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=(0<<OCIE2) | (0<<TOIE2) | (0<<TICIE1) | (0<<OCIE1A) | (0<<OCIE1B) | (0<<TOIE1) | (0<<OCIE0) | (1<<TOIE0);
ETIMSK=(0<<TICIE3) | (0<<OCIE3A) | (0<<OCIE3B) | (0<<TOIE3) | (0<<OCIE3C) | (0<<OCIE1C);


    DDRA = 0xFF;
    DDRD = 0xFF;
    PORTA = 0;
    PORTD = 0;
    z1=0;
   
    sei();

    //PORTA |= (1<<PA4); _delay_ms(1000);
    PORTD |= (1<<PD5); _delay_ms(1000);

    PORTA |= (1<<PA3); _delay_ms(1000);
    PORTA |= (1<<PA5); _delay_ms(1000);
    PORTA |= (1<<PA6); _delay_ms(1000);


    PORTA = 0;
    PORTD = 0;
   
   

    while (1)
    {
        PORTD ^= (1<<PD5); _delay_ms(500);
    }
}

#11 2020-03-23 15:03:15

Watchdog
Гость

Re: Помогите начинающему с ATMega128

А как вы указываете компилятору на тип микроконтроллера? Все может быть, если где-то хотя бы один бит испорчен. Напишите свою delay, если подозреваете. И что? Есть паразитные вызовы прерываний? Заниматься отладкой и тестированием, по испорченному телефону, дело неблагодарное. За текстом, вашей программы, скрыта целая технология компиляции. А дара ясновидения у меня нет.

#12 2020-03-23 15:28:16

VLDnepr
Участник
Из г.Днепр
Зарегистрирован: 2020-02-04
Сообщений: 17

Re: Помогите начинающему с ATMega128

Что не ясновидец - понятно.

AtmelStudio menu Project\Device\CurrentDevice: ATmega128

#13 2020-03-23 15:49:54

Watchdog
Гость

Re: Помогите начинающему с ATMega128

VLDnepr пишет:

Что не ясновидец - понятно.

AtmelStudio menu Project\Device\CurrentDevice: ATmega128

Я бубен использую в таких случах. smile Что-то вы напутали, или ваш микроконтроллер негоден.

#14 2020-03-23 16:22:12

Kaka
Участник
Зарегистрирован: 2018-03-21
Сообщений: 353

Re: Помогите начинающему с ATMega128

VLDnepr пишет:

что я делаю не так

Не читаешь, что тебе пишут. Я ж тебе уже написал, что у меня твой код работает, значит, дело не в коде.

VLDnepr пишет:

Не суть какой делитель устанавлиывется

С точки зрения работоспособности кода, не влияет, а вот с точки зрения "общей аккуратности" ... если ты говоришь, что делитель такой, а он совсем другой, какие у меня основания доверять, что у тебя там в вправду 128-ая на 8МГц, а не 32U на 20?

VLDnepr пишет:

Фьюзы как по мне тут непричем

Ну, тебе виднее. Раз ты всё и сам знаешь - что причём, а что - нет, зачем было сюда обращаться?

#15 2020-03-23 16:31:59

VLDnepr
Участник
Из г.Днепр
Зарегистрирован: 2020-02-04
Сообщений: 17

Re: Помогите начинающему с ATMega128

Kaka пишет:
VLDnepr пишет:

что я делаю не так

Не читаешь, что тебе пишут. Я ж тебе уже написал, что у меня твой код работает, значит, дело не в коде.

VLDnepr пишет:

Не суть какой делитель устанавлиывется

С точки зрения работоспособности кода, не влияет, а вот с точки зрения "общей аккуратности" ... если ты говоришь, что делитель такой, а он совсем другой, какие у меня основания доверять, что у тебя там в вправду 128-ая на 8МГц, а не 32U на 20?

VLDnepr пишет:

Фьюзы как по мне тут непричем

Ну, тебе виднее. Раз ты всё и сам знаешь - что причём, а что - нет, зачем было сюда обращаться?

Мне не видно, потому и обратился.
Но и надпись типа "... Поэтому, смотри на фьюзы, всё ли там в порядке. ..." - тоже очень информативна, конкретна и после нее сразу понятно куда смотреть и что делать.

#16 2020-03-23 23:23:06

Kaka
Участник
Зарегистрирован: 2018-03-21
Сообщений: 353

Re: Помогите начинающему с ATMega128

VLDnepr пишет:

тоже очень информативна, конкретна

Ты выбрал хороший путь повысить информативность :-)

#17 2020-03-24 13:14:20

VLDnepr
Участник
Из г.Днепр
Зарегистрирован: 2020-02-04
Сообщений: 17

Re: Помогите начинающему с ATMega128

Дабы разобраться не в среде ли дело, не согласится ли кто-то скомпилить код и переслать мне бинарный файл для заливки.
Atmega125a 8мг

#define F_CPU 8000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>

volatile unsigned char z1;

ISR(TIMER0_OVF_vect)
{
    z1++;
    if (z1<=250) {return;}
       
    z1=0;   
    PORTA ^= (1<<PA4);
}
   
int main(void)
{
   
//TIMER0 -------------------------------------------------
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 7,813 kHz
// Mode: Normal top=0xFF
// OC0 output: Disconnected
// Timer Period: 9,984 ms
ASSR=0<<AS0;
TCCR0=(0<<WGM00) | (0<<COM01) | (0<<COM00) | (0<<WGM01) | (1<<CS02) | (1<<CS01) | (1<<CS00);
TCNT0=0xB2;
OCR0=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=(0<<OCIE2) | (0<<TOIE2) | (0<<TICIE1) | (0<<OCIE1A) | (0<<OCIE1B) | (0<<TOIE1) | (0<<OCIE0) | (1<<TOIE0);
ETIMSK=(0<<TICIE3) | (0<<OCIE3A) | (0<<OCIE3B) | (0<<TOIE3) | (0<<OCIE3C) | (0<<OCIE1C);

    DDRA = 0xFF;
    DDRD = 0xFF;
    PORTA = 0;
    PORTD = 0;
    z1=0;
   
    sei();

    PORTA |= (1<<PA4); _delay_ms(1000);
    PORTD |= (1<<PD5); _delay_ms(1000);

    PORTA |= (1<<PA3); _delay_ms(1000);
    PORTA |= (1<<PA5); _delay_ms(1000);
    PORTA |= (1<<PA6); _delay_ms(1000);

    PORTA = 0;
    PORTD = 0;

    while (1)
    {
        PORTD ^= (1<<PD5); _delay_ms(500);
    }
}

#18 2020-03-24 15:46:55

Вячеслав Азаров
Участник
Зарегистрирован: 2017-05-25
Сообщений: 1,732

Re: Помогите начинающему с ATMega128

VLDnepr пишет:

Дабы разобраться не в среде ли дело, не согласится ли кто-то скомпилить код и переслать мне бинарный файл для заливки.
Atmega125a 8мг

Для вставки программ есть специальный фрейм, с подсветкой.  Нужно на кнопку нажать, всего лишь.

#define F_CPU 8000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>

volatile unsigned char z1;

ISR(TIMER0_OVF_vect)
{
	z1++;
	if (z1<=250) {return;}
		
	z1=0;	
	PORTA ^= (1<<PA4);
}
	
int main(void)
{
	
//TIMER0 -------------------------------------------------
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 7,813 kHz
// Mode: Normal top=0xFF
// OC0 output: Disconnected
// Timer Period: 9,984 ms
ASSR=0<<AS0;
TCCR0=(0<<WGM00) | (0<<COM01) | (0<<COM00) | (0<<WGM01) | (1<<CS02) | (1<<CS01) | (1<<CS00);
TCNT0=0xB2;
OCR0=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=(0<<OCIE2) | (0<<TOIE2) | (0<<TICIE1) | (0<<OCIE1A) | (0<<OCIE1B) | (0<<TOIE1) | (0<<OCIE0) | (1<<TOIE0);
ETIMSK=(0<<TICIE3) | (0<<OCIE3A) | (0<<OCIE3B) | (0<<TOIE3) | (0<<OCIE3C) | (0<<OCIE1C);

    DDRA = 0xFF;
    DDRD = 0xFF;
	PORTA = 0;
	PORTD = 0;
	z1=0;
	
	sei();

	PORTA |= (1<<PA4); _delay_ms(1000);
	PORTD |= (1<<PD5); _delay_ms(1000);

	PORTA |= (1<<PA3); _delay_ms(1000);
	PORTA |= (1<<PA5); _delay_ms(1000);
	PORTA |= (1<<PA6); _delay_ms(1000);

	PORTA = 0;
	PORTD = 0;

    while (1) 
    {
		PORTD ^= (1<<PD5); _delay_ms(500);
    }
}

https://forum.arduino.ua/img/members/1550/test-m128.zip
Пробуйте. Скомпилировано из коммандной строки (avr-gcc (AVR_8_bit_GNU_Toolchain_3.5.4_1709) 4.9.2).

#19 2020-03-25 14:22:07

VLDnepr
Участник
Из г.Днепр
Зарегистрирован: 2020-02-04
Сообщений: 17

Re: Помогите начинающему с ATMega128

Не помогло. Тогда остается причина - чтото с самим контролером?

#20 2020-03-25 15:05:42

Kino
Участник
Зарегистрирован: 2019-02-28
Сообщений: 31

Re: Помогите начинающему с ATMega128

#21 2020-03-25 15:07:42

Вячеслав Азаров
Участник
Зарегистрирован: 2017-05-25
Сообщений: 1,732

Re: Помогите начинающему с ATMega128

VLDnepr пишет:

Не помогло. Тогда остается причина - чтото с самим контролером?

Вы просили скомпилировать, я скомпилировал. Всё может быть, попробуйте на другом.

Быстрое сообщение

Введите сообщение и нажмите Отправить

Подвал раздела