Страница 1 из 2

Timer0 не работает ни на одном контроллере

Добавлено: Сб май 23, 2020 13:43:35
Alek_von_German
Доброго времени всем. Сижу осваиваю таймеры на atmega8. Играюсь с разными режимами работы и т.д. Только вот непоняточка вышла одна, timer0 работающий в proteus не работает в железе, хотя параллельно ему работает timer1. Я сначала подумал, что контроллер гавкнул, заменил- результат тот же. Потом решил переключить на timer2, при таких же настройках он заработал на всех камнях, а вот нулевой не хочет. Даже 328-ю мегу взял, и на ней ничего не заработало... Поправте меня, можт это я туплю и его отдельно где включать нужно?
Спойлер

Код: Выделить всё

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

char dig[] = {0b10000001, 0b11110011, 0b01001001, 0b01100001, 0b00110011, 0b00100101, 0b00000101, 0b11110001, 0b00000001, 0b00100001, 0b00000000};
char razr[] = {0b11111110, 0b11111101, 0b11111011, 0b11110111};
unsigned char display[2];
unsigned char  i, a=0;
unsigned int z=0;
unsigned char dig1, dig2, dig3, dig4;

ISR(TIMER0_OVF_vect)
{
    TCNT0=178;
    a++;
    if (a>10)
    {
        z++;
        a=0;
    }
}


void write_display(unsigned char *data)
{
    unsigned char mask,i;
    
    for(i = 0; i < 2; i++)
    {
        mask = 0x80;
        
        for(char k = 0; k < 8; k++)
        {
            // Сравниваем каждый бит с единицей
            if(data[i] & mask)
            {
                PORTB |= (1 << 0); // DATA 1
                PORTB |= (1 << 1); // CLK 1
                PORTB &= ~(1 <<1); // CLK 0
            }
            else
            {
                PORTB &= ~(1 << 0); // DATA 0
                PORTB |= (1 << 1); // CLK 1
                PORTB &= ~(1 << 1); // CLK 0
            }
            mask = mask >> 1; // Сдвигаем биты
        }
    }
    // Защелкиваем регистр
    PORTB |= (1 << 2);
    PORTB &= ~(1 << 2);
}



ISR (TIMER1_COMPA_vect)
{
    
    dig4=dig[z % 10000 / 1000];
    dig3=dig[z % 1000 / 100];
    dig2=dig[z % 100 / 10];
    dig1=dig[z % 10];
    
    display[0] =  razr[3];
    display[1] = ~ dig4;
    write_display(display);
    
    display[0] =  razr[3];
    display[1] =  dig[10];
    write_display(display);
    
    
    display[0] =  razr[2];
    display[1] = ~ dig3;
    write_display(display);
    
    display[0] =  razr[2];
    display[1] =  dig[10];
    write_display(display);
    
    display[0] =  razr[1];
    display[1] =  ~dig2;
    write_display(display);
    
    display[0] =  razr[1];
    display[1] =  dig[10];
    write_display(display);

    display[0] =razr[0];    // в крайний левый символ
    display[1] =~ dig1;        // выводится цифра
    write_display(display);
    
    display[0] =  razr[0];    // в крайний левый символ
    display[1] =  dig[10];        // выводится цифра
    write_display(display); // и посылается на 74hc595
    
}
/*
*/
int main(void)
{
    DDRB = 0xFF;
    PORTB = 0x00;
    DDRC=0xff;
    PORTC=0x03;
    TCCR0A=0;
    TCNT0=178;
    
    TCCR0B=(1<<CS02)|(1<<CS00);
    
    TIMSK0|=1<<TOIE0;
    
    TCCR1A = 0x00;
    TCCR1B = (1<<WGM12) | (1<<CS11)  | (1<<CS10);
    TCNT1H = 0;
    TCNT1L = 0;
    OCR1A=5;
    
    TIMSK1 |= (1<<OCIE1A);
    
    sei();

    while (1)
    {
    }
}

Re: Timer0 не работает ни на одном контроллере

Добавлено: Сб май 23, 2020 14:21:08
Самсусамыч
Тестовая прошивка для мега328П… фьюзы заводская установка (1 МГц).
На выводе РВ5 подключается светодиод. Светик переключается по переполнению таймера0. При замыкании вывода РD2 на общий (GND), светик начнёт мигать значительно медленней.

пробуй
прошивка:
Test Timer_0.hex

Re: Timer0 не работает ни на одном контроллере

Добавлено: Сб май 23, 2020 14:42:15
Alek_von_German
[uquote="Самсусамыч",url="/forum/viewtopic.php?p=3845119#p3845119"]пробуй[/uquote]

Спасибо. Так-то работает. Мне интересно где я ошибся. Ведь Т1 и Т2 работают сообща, а Т0 и Т1 не хотят...

Re: Timer0 не работает ни на одном контроллере

Добавлено: Сб май 23, 2020 15:03:52
Самсусамыч
Я не пишу на Си… потому твою программу понять не могу. Просто ты теперь уверен, что МК тут не причём. Ошибка в программе… :)

Так ты пробуешь настроить счёт по внешнему выводу Т0? А от чего такты на него поступают?

Добавлено after 5 minutes 29 seconds:
[uquote="Alek_von_German",url="/forum/viewtopic.php?p=3845129#p3845129"]Ведь Т1 и Т2 работают сообща, а Т0 и Т1 не хотят...[/uquote]
Входа Т2 у меги8 и 328 нет. :) Вывод Т0 относится к таймеру0, а вывод Т1 к таймеру1. У таймера2 нет входа для внешнего тактирования.

Re: Timer0 не работает ни на одном контроллере

Добавлено: Сб май 23, 2020 15:07:14
Alek_von_German
Самсусамыч, Не-не, то я так таймеры обозвал. Я просто не пойму одного, три таймера, в моей программе использую два, один из них управляет ч-х разрядным индикатором, друго просто инкрементирует переменную. Так вот в связке таймер0, таймер1- работает таймер1, в связке таймер2, таймер1 работают оба, при том что таймер0 и таймер2 настроены идентично по переполнению, а таймер1 всегда по совпадению.
Интересно, что в обеих случаях всё это работает в протеусе...

Re: Timer0 не работает ни на одном контроллере

Добавлено: Сб май 23, 2020 15:34:07
Самсусамыч
Я не смогу тебе помочь, так как не понимаю Си… имей просто ввиду, что у меги8 и меги238 таймера не одинаковые… то есть настройки для 8_й не подойдут для 328_й.

Re: Timer0 не работает ни на одном контроллере

Добавлено: Сб май 23, 2020 15:37:45
Alek_von_German
[uquote="Самсусамыч",url="/forum/viewtopic.php?p=3845149#p3845149"]Я не смогу тебе помочь, так как не понимаю Си… имей просто ввиду, что у меги8 и меги238 таймера не одинаковые… то есть настройки для 8_й не подойдут для 328_й.[/uquote]
Это я вкурсе, даташит под рукой, я просто сат8 портировал на ат328 чтоб убедиться, что программа не работает, а не контроллер сдох.

Re: Timer0 не работает ни на одном контроллере

Добавлено: Сб май 23, 2020 15:48:06
Самсусамыч
Могу только тестовую прошивку тебе написать для проверки твоего МК с данными таймерами по твоему описанию, а ты уже прикидывай что к чему. Только меги8 у меня нет... есть только шильд ардуино нано на меге 328П... :)

Re: Timer0 не работает ни на одном контроллере

Добавлено: Сб май 23, 2020 16:09:21
Alek_von_German
Самсусамыч, Спасибо большое, я думаю пока не стОит))

Re: Timer0 не работает ни на одном контроллере

Добавлено: Сб май 23, 2020 16:11:42
Самсусамыч
:) Ладно.

Re: Timer0 не работает ни на одном контроллере

Добавлено: Сб май 23, 2020 16:59:30
Alek_von_German
написал тестовую прошивку для таймера0, чтоб диодом помигать... Работает. Выходит, что два таймера мешают друг-другу, почему-то...

Re: Timer0 не работает ни на одном контроллере

Добавлено: Сб май 23, 2020 17:23:52
Самсусамыч
Если в прерывании какого либо таймера выполнение программы будет превышать время отсчёта другого таймера то да будут мешать. Если всё нормально, то не будут. Какое время по переполнению одного и другого?

Re: Timer0 не работает ни на одном контроллере

Добавлено: Сб май 23, 2020 17:30:07
Reflector
[uquote="Alek_von_German",url="/forum/viewtopic.php?p=3845175#p3845175"]Выходит, что два таймера мешают друг-другу, почему-то...[/uquote]
Для начала не помешало бы про volatile почитать и добавить куда следует...

Re: Timer0 не работает ни на одном контроллере

Добавлено: Сб май 23, 2020 17:35:59
Alek_von_German
[uquote="Reflector",url="/forum/viewtopic.php?p=3845190#p3845190"][uquote="Alek_von_German",url="/forum/viewtopic.php?p=3845175#p3845175"]Выходит, что два таймера мешают друг-другу, почему-то...[/uquote]
Для начала не помешало бы про volatile почитать и добавить куда следует...[/uquote]
Читал, добавлял. Безрезультатно. Но ведь другой таймер с той же настройкой работает ..

Re: Timer0 не работает ни на одном контроллере

Добавлено: Сб май 23, 2020 22:19:17
NStorm
a и z обязательно как volatile объявлять. Что в другом месте якобы работает - ничего не показывает. Вам правильно сказали, что надо читать про volatile. Всё, что меняется в переменных обязано быть volatile, компилятор не знает о прерываниях толком и может выкинуть код манипуляций над переменной.
Если не поможет, попоробуйте на время убрать изменение TCNT0 в прерывании. Если и это не поможет - пишите, гляну детальнее.

Re: Timer0 не работает ни на одном контроллере

Добавлено: Сб май 23, 2020 22:25:22
Alek_von_German
NStorm, Здравствуйте. Поправил код под атмега8 с использованием volatile, но ничего не изменилось. TCNT0 не изменяется, там величина постоянная.
Спойлер

Код: Выделить всё

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

const char dig[] = {
    0b10000001, //0
    0b11110011, //1
    0b01001001, //2
    0b01100001, //3
    0b00110011, //4
    0b00100101, //5
    0b00000101, //6
    0b11110001, //7
    0b00000001, //8
    0b00100001, //9
    0b00000000};//пусто

const char razr[] = {
    0b11111110,
    0b11111101,
    0b11111011,
    0b11110111};

unsigned char display[2];
volatile unsigned char i, a=0;
volatile unsigned int  z=0;
unsigned char dig1, dig2, dig3, dig4;


void init_timer0()
{
    TCCR0 =(1<<CS02)|(1<<CS00);
    TCNT0  =255;
    
    TIMSK|=1<<TOIE0;
    sei();
}

void init_timer1()
{
    TCCR1A = 0x00;
    TCCR1B = (1<<WGM12) | (1<<CS11)  | (1<<CS10);
    TCNT1H = 0;
    TCNT1L = 0;
    OCR1A  =1;
    TIMSK |= (1<<OCIE1A);
    sei();
}

void counter0(void)
{
    a++;
    
}

ISR(TIMER0_OVF_vect)
{
    TCNT0=255;
    counter0();
}


void write_display(unsigned char *data)
{
    unsigned char mask,i;
    
    for(i = 0; i < 2; i++)
    {
        mask = 0x80;
        
        for(char k = 0; k < 8; k++)
        {
            // Сравниваем каждый бит с единицей
            if(data[i] & mask)
            {
                PORTB |= (1 << 0); // DATA 1
                PORTB |= (1 << 1); // CLK 1
                PORTB &= ~(1 <<1); // CLK 0
            }
            else
            {
                PORTB &= ~(1 << 0); // DATA 0
                PORTB |= (1 << 1); // CLK 1
                PORTB &= ~(1 << 1); // CLK 0
            }
            mask = mask >> 1; // Сдвигаем биты
        }
    }
    // Защелкиваем регистр
    PORTB |= (1 << 2);
    PORTB &= ~(1 << 2);
}



ISR (TIMER1_COMPA_vect)
{
    
    dig4=dig[z % 10000 / 1000];
    dig3=dig[z % 1000 / 100];
    dig2=dig[z % 100 / 10];
    dig1=dig[z % 10];
    
    display[0] =  razr[3];
    display[1] = ~ dig4;
    write_display(display);
    
    display[0] =  razr[3];
    display[1] =  dig[10];
    write_display(display);
    
    
    display[0] =  razr[2];
    display[1] = ~ dig3;
    write_display(display);
    
    display[0] =  razr[2];
    display[1] =  dig[10];
    write_display(display);
    
    display[0] =  razr[1];
    display[1] =  ~dig2;
    write_display(display);
    
    display[0] =  razr[1];
    display[1] =  dig[10];
    write_display(display);

    display[0] =razr[0];    // в крайний левый символ
    display[1] =~ dig1;        // выводится цифра
    write_display(display);
    
    display[0] =  razr[0];    // в крайний левый символ
    display[1] =  dig[10];        // выводится цифра
    write_display(display); // и посылается на 74hc595
    
}
/*
*/
int main(void)
{
    DDRB  = 0xFF;
    PORTB = 0x00;
    DDRC  = 0xff;
    PORTC = 0x03;
    init_timer0();
    init_timer1();
    

    while (1)
    {
        if (a>10)
        {
            z++;
            PORTC^=1<<5;
            a=0;
        }
    }
}

Re: Timer0 не работает ни на одном контроллере

Добавлено: Пн май 25, 2020 12:23:52
NStorm
TCNT0 не изменяется, там величина постоянная.
Я имел в виду, не менять его в прерывании 1ой операцией. Вы его на 178 ставили. Я в ДШ не лазил чтобы проверить - некогда пока, но где-то встречал такое, что сразу в прерывании таймера нельзя менять его знаечение, иначе могут быть глитчи. Правда это может и вообще не об AVR было или вообще не было ) Но в порядке "почему бы и не проверить" написал.

А теперь вообще на 255 ставить - вот это плохая идея точно. У вас так из прерывания может никогда не вылезти МК, если прескейлер недостаточно большой будет.

Re: Timer0 не работает ни на одном контроллере

Добавлено: Пн май 25, 2020 13:30:42
dgrett
Если не изменяется TCNT, значит, счётчик остановлен.

Re: Timer0 не работает ни на одном контроллере

Добавлено: Пн май 25, 2020 13:32:31
Dimon456
Alek_von_German, вы запрашиваете прерывание

Код: Выделить всё

   #define F_CPU 8000000UL
	TCCR1B = (1<<WGM12) | (1<<CS11)  | (1<<CS10);
	OCR1A  =1;
с частотой 32 мкс (31250 Гц),
а время выполнения вашего кода находящегося в прерывании

Код: Выделить всё

ISR (TIMER1_COMPA_vect)
~335 мкс (2985 Гц).

Re: Timer0 не работает ни на одном контроллере

Добавлено: Пн май 25, 2020 20:27:52
Alek_von_German
Так. Это уже интересно. Значит выходит, что я таймером1 забираю всё время у таймера0? Грубо говоря. Мне нужно уменьшить значение таймера1?