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

Обсуждаем контроллеры компании Atmel.
Ответить
Встал на лапы
Аватара пользователя
Сообщения: 118
Зарегистрирован: Вт апр 21, 2020 07:44:24
Откуда: Сумы, Украина

Сообщение 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)
    {
    }
}
Хочется всё и сразу, а получаешь нихрена и постепенно...
Реклама
Самсусамыч

Сообщение Самсусамыч »

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

пробуй
прошивка:
Test Timer_0.hex
Реклама
Встал на лапы
Аватара пользователя
Сообщения: 118
Зарегистрирован: Вт апр 21, 2020 07:44:24
Откуда: Сумы, Украина

Сообщение Alek_von_German »

[uquote="Самсусамыч",url="/forum/viewtopic.php?p=3845119#p3845119"]пробуй[/uquote]

Спасибо. Так-то работает. Мне интересно где я ошибся. Ведь Т1 и Т2 работают сообща, а Т0 и Т1 не хотят...
Хочется всё и сразу, а получаешь нихрена и постепенно...
Самсусамыч

Сообщение Самсусамыч »

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

Так ты пробуешь настроить счёт по внешнему выводу Т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 нет входа для внешнего тактирования.
Реклама
Эиком - электронные компоненты и радиодетали
Встал на лапы
Аватара пользователя
Сообщения: 118
Зарегистрирован: Вт апр 21, 2020 07:44:24
Откуда: Сумы, Украина

Сообщение Alek_von_German »

Самсусамыч, Не-не, то я так таймеры обозвал. Я просто не пойму одного, три таймера, в моей программе использую два, один из них управляет ч-х разрядным индикатором, друго просто инкрементирует переменную. Так вот в связке таймер0, таймер1- работает таймер1, в связке таймер2, таймер1 работают оба, при том что таймер0 и таймер2 настроены идентично по переполнению, а таймер1 всегда по совпадению.
Интересно, что в обеих случаях всё это работает в протеусе...
Хочется всё и сразу, а получаешь нихрена и постепенно...
Реклама
Самсусамыч

Сообщение Самсусамыч »

Я не смогу тебе помочь, так как не понимаю Си… имей просто ввиду, что у меги8 и меги238 таймера не одинаковые… то есть настройки для 8_й не подойдут для 328_й.
Реклама
Встал на лапы
Аватара пользователя
Сообщения: 118
Зарегистрирован: Вт апр 21, 2020 07:44:24
Откуда: Сумы, Украина

Сообщение Alek_von_German »

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

Сообщение Самсусамыч »

Могу только тестовую прошивку тебе написать для проверки твоего МК с данными таймерами по твоему описанию, а ты уже прикидывай что к чему. Только меги8 у меня нет... есть только шильд ардуино нано на меге 328П... :)
Встал на лапы
Аватара пользователя
Сообщения: 118
Зарегистрирован: Вт апр 21, 2020 07:44:24
Откуда: Сумы, Украина

Сообщение Alek_von_German »

Самсусамыч, Спасибо большое, я думаю пока не стОит))
Хочется всё и сразу, а получаешь нихрена и постепенно...
Встал на лапы
Аватара пользователя
Сообщения: 118
Зарегистрирован: Вт апр 21, 2020 07:44:24
Откуда: Сумы, Украина

Сообщение Alek_von_German »

написал тестовую прошивку для таймера0, чтоб диодом помигать... Работает. Выходит, что два таймера мешают друг-другу, почему-то...
Хочется всё и сразу, а получаешь нихрена и постепенно...
Самсусамыч

Сообщение Самсусамыч »

Если в прерывании какого либо таймера выполнение программы будет превышать время отсчёта другого таймера то да будут мешать. Если всё нормально, то не будут. Какое время по переполнению одного и другого?
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Сообщение Reflector »

[uquote="Alek_von_German",url="/forum/viewtopic.php?p=3845175#p3845175"]Выходит, что два таймера мешают друг-другу, почему-то...[/uquote]
Для начала не помешало бы про volatile почитать и добавить куда следует...
Встал на лапы
Аватара пользователя
Сообщения: 118
Зарегистрирован: Вт апр 21, 2020 07:44:24
Откуда: Сумы, Украина

Сообщение 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]
Читал, добавлял. Безрезультатно. Но ведь другой таймер с той же настройкой работает ..
Хочется всё и сразу, а получаешь нихрена и постепенно...
Поставщик валерьянки для Кота
Сообщения: 1978
Зарегистрирован: Ср июл 17, 2013 13:55:57

Сообщение NStorm »

a и z обязательно как volatile объявлять. Что в другом месте якобы работает - ничего не показывает. Вам правильно сказали, что надо читать про volatile. Всё, что меняется в переменных обязано быть volatile, компилятор не знает о прерываниях толком и может выкинуть код манипуляций над переменной.
Если не поможет, попоробуйте на время убрать изменение TCNT0 в прерывании. Если и это не поможет - пишите, гляну детальнее.
Встал на лапы
Аватара пользователя
Сообщения: 118
Зарегистрирован: Вт апр 21, 2020 07:44:24
Откуда: Сумы, Украина

Сообщение 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;
        }
    }
}
Хочется всё и сразу, а получаешь нихрена и постепенно...
Поставщик валерьянки для Кота
Сообщения: 1978
Зарегистрирован: Ср июл 17, 2013 13:55:57

Сообщение NStorm »

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

А теперь вообще на 255 ставить - вот это плохая идея точно. У вас так из прерывания может никогда не вылезти МК, если прескейлер недостаточно большой будет.
Вымогатель припоя
Сообщения: 615
Зарегистрирован: Вс дек 28, 2014 21:54:05

Сообщение dgrett »

Если не изменяется TCNT, значит, счётчик остановлен.
Я всё-всё узнAю и стану профессором.
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

Сообщение 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 Гц).
Встал на лапы
Аватара пользователя
Сообщения: 118
Зарегистрирован: Вт апр 21, 2020 07:44:24
Откуда: Сумы, Украина

Сообщение Alek_von_German »

Так. Это уже интересно. Значит выходит, что я таймером1 забираю всё время у таймера0? Грубо говоря. Мне нужно уменьшить значение таймера1?
Хочется всё и сразу, а получаешь нихрена и постепенно...
Ответить

Вернуться в «AVR»