Нескольно простых вопросов о программировании AVR на Си.

Обсуждаем контроллеры компании Atmel.
OKF
Это не хвост, это антенна
Сообщения: 1392
Зарегистрирован: Вт июн 07, 2011 08:03:18

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение OKF »

Ну почему же! Спорт у каждого свой. Как и смысл.)
Реклама
elektronic3452
Родился
Сообщения: 16
Зарегистрирован: Чт сен 12, 2024 21:34:21
Откуда: Москва

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение elektronic3452 »

Добрый вечер! Форумчане!!!
Я начинающий! Можете подсказать что значит строка PORTC = 0x3F & led_buff[0]; в этом коде?



#include <mega8.h>
#include <delay.h>

#define ON 1
#define OFF 0
#define timer_ TCNT0
#define timer_tact TCCR0
#define OUT PORTB.0

#define enable PINB.3
#define up PINB.4
#define down PINB.5
#define pwm__ OCR1AL

#define klapan PORTB.2
#define motor_stop {PORTB.1=0;}
#define motor_tormoz {PORTD.4=1;}
#define motor_tormoz_off {PORTD.4=0;}

bit flags_button=0;
volatile unsigned char sek_;
volatile unsigned char timer_button, timer_butt;
volatile unsigned char timer_shou;
volatile unsigned char timer_stop;
volatile unsigned char eep_timer;
volatile unsigned char sek;
volatile unsigned char timer;
volatile unsigned char y,jamp2=0;
volatile unsigned int pwm, start_;



volatile unsigned char pwm_, data0, data1, data2, led_buff[3];
//--------------- 0-9 10 ........... 18 символов
//Символы для LED (0-9, ,-,t,L,A,r,d,b,DP)
flash unsigned char led_table[26]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0xbf,0x87,0xC7,0x88,0xAF,0xA1,0x83,0x7F,0x8C,0xC6,0xC1,0x86,0x89,0x8E,0x9C};
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
// [] - t L A r d b Dp P C U E H F град.

//volatile unsigned char y, jamp2=0;
volatile unsigned char start=180;

eeprom unsigned char eep_power, eep_jamp, eep_pwm, eep_sek;

// External Interrupt 0 service routine
interrupt [EXT_INT0] void ext_int0_isr(void) // прерывание для захвата перехода через ноль.
{
// Place your code here Процедура обслуживания внешнего прерывания 0

OUT=OFF;
timer_=start;

}

// Timer 0 overflow interrupt service routine Процедура обслуживания прерывания переполнения таймера 0
interrupt [TIM0_OVF] void timer0_ovf_isr(void) // прерывание для выхода управления тиристорами
{
// Place your code here Разместите свой код здесь
timer_=start;
OUT=ON;
}

// Timer2 overflow interrupt service routine Процедура обслуживания прерывания переполнения Таймера 2
interrupt [TIM2_OVF] void timer2_ovf_isr(void) // прерывание для дисплея
{
// Reinitialize Timer2 value Повторно инициализировать значение Таймера2
TCNT2=0xCB;

if (jamp2==0)
{
PORTD.5=PORTD.6=PORTD.7=0; // выключаем все разряды

switch (y) // общий анод
{

case 0:

PORTC = 0x3F & led_buff[0];
PORTD.0 = 0x40 & led_buff[0];
PORTD.1 = 0x80 & led_buff[0];
Реклама
OKF
Это не хвост, это антенна
Сообщения: 1392
Зарегистрирован: Вт июн 07, 2011 08:03:18

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение OKF »

Вы бы, прежде чем постить, посмотрели бы как люди код вставляют в сообщение.
metan
Вымогатель припоя
Сообщения: 593
Зарегистрирован: Ср янв 06, 2010 10:01:46

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение metan »

elektronic3452 писал(а):что значит строка PORTC = 0x3F & led_buff[0]; в этом коде
вывод в PORTC значения из нулевого элемента массива led_buff c обнулением двух старших битов
Последний раз редактировалось metan Пт сен 13, 2024 09:13:18, всего редактировалось 1 раз.
Реклама
Эиком - электронные компоненты и радиодетали
Аватара пользователя
Z_h_e
Собутыльник Кота
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение Z_h_e »

Не путайте. В массиве ничего не обнулиться.
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Реклама
metan
Вымогатель припоя
Сообщения: 593
Зарегистрирован: Ср янв 06, 2010 10:01:46

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение metan »

[uquote="Z_h_e",url="/forum/viewtopic.php?p=4624861#p4624861"]Не путайте.[/uquote]извиняюсь, неверно выразил свою мысль, поправил
Реклама
elektronic3452
Родился
Сообщения: 16
Зарегистрирован: Чт сен 12, 2024 21:34:21
Откуда: Москва

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение elektronic3452 »

Спасибо!!! "metan" и "Z_h_e"!
watchmaker
Поставщик валерьянки для Кота
Сообщения: 2183
Зарегистрирован: Вс ноя 15, 2009 23:13:59
Откуда: Харьков
Контактная информация:

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение watchmaker »

Немного нубский вопрос, но всё же. ATtiny85. Чип просыпается по внешнему прерыванию на пине PB2, затем сразу же в обработчике прерывания это самое прерывание отключается (PCMSK = 0), а включается обратно (PCMSK = 0b100) существенно позже, перед уходом в спящий режим. Делаю это для того, чтобы постоянно меняющийся уровень на пине (а там летит извне меандр 4 кГц) не вызывал сотни прерываний в секунду при работе основной программы, от них программа тормозит (чип работает на 128 кГц). Контроллер зависает намертво в спящем режиме второй раз за неделю, реагирует только на ресет. Безопасно ли отключать прерывание в обработчике этого же прерывания? И может ли быть такое, что при установке бита в PCMSK прерывание не включается или включается не сразу?
Иногда мой питомец уходит в такую спячку, что разбудить его можно только щелчком по первой ноге...
Аватара пользователя
Ivanoff-iv
Друг Кота
Сообщения: 7077
Зарегистрирован: Пт ноя 11, 2016 05:48:09
Откуда: Сердце Пармы

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение Ivanoff-iv »

Внутри прерывания ничего отключать не надо - т.к. пока ты в прерывании сбрасывается регистр "I" (глобальное разрешение прерываний)
а вот флаг прерывания в конце прерывания очистить наверно не повредит (зависит от решаемой задачи), это исключит повторный вызов прерывания сразу после его завершения если события, вызывающие прерывание, происходили во время прерывания. (флаг прерывания очищается записью в него "1")
Для тех, кто не учил магию мир полон физики :)
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Аватара пользователя
VNS
Говорящий с текстолитом
Сообщения: 1624
Зарегистрирован: Пт дек 10, 2021 12:48:46
Откуда: Тюмень

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение VNS »

[uquote="watchmaker",url="/forum/viewtopic.php?p=4706302#p4706302"]ATtiny85. Чип просыпается по внешнему прерыванию на пине PB2,[/uquote]
Уточните, от какого прерывания просыпается МК, от INT0 или от PCIE0?
Делаю это для того, чтобы постоянно меняющийся уровень на пине (а там летит извне меандр 4 кГц) не вызывал сотни прерываний в секунду
То есть, этот меандр будит ваш МК?
Контроллер зависает намертво в спящем режиме второй раз за неделю,
Контроллер в спящем режиме (Power-down) и так всегда «весит», то есть "спит и ничего не делает", экономит энергию… :) вы наверное хотите сказать, что не могли его разбудить два раза за неделю? Дело в том, что для пробуждения МК необходимо удерживать низкий уровень на пине достаточное время, чтобы МК включил питание и запустил тактовый генератор (завершил полностью пробуждение). Если продолжительности уровня на пине не достаточно, то МК может и проснуться, но прерывание не будет сгенерировано. Обратите внимание в даташите какое время необходимо МК для полного пробуждения.
akl
Друг Кота
Сообщения: 4445
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение akl »

watchmaker писал(а):Безопасно ли отключать прерывание в обработчике этого же прерывания?
Отключайте безопасно.
Последний раз редактировалось akl Сб апр 19, 2025 04:34:16, всего редактировалось 1 раз.
watchmaker
Поставщик валерьянки для Кота
Сообщения: 2183
Зарегистрирован: Вс ноя 15, 2009 23:13:59
Откуда: Харьков
Контактная информация:

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение watchmaker »

Уточните, от какого прерывания просыпается МК, от INT0 или от PCIE0?
ISR(PCINT0_vect)
То есть, этот меандр будит ваш МК?
Да, МК подключён к выходу пищалки в электронных часах и просыпается от такого сигнала.
Контроллер в спящем режиме (Power-down) и так всегда «весит», то есть "спит и ничего не делает", экономит энергию… :) вы наверное хотите сказать, что не могли его разбудить два раза за неделю?
Виснет так, что не разбудишь даже подачей постоянного уровня на пин, как будто прерывание не включилось при уходе в слип. Если конечно это вообще не аппаратные проблемы типа помех по питанию.
Иногда мой питомец уходит в такую спячку, что разбудить его можно только щелчком по первой ноге...
OKF
Это не хвост, это антенна
Сообщения: 1392
Зарегистрирован: Вт июн 07, 2011 08:03:18

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение OKF »

[uquote="watchmaker",url="/forum/viewtopic.php?p=4706384#p4706384"]Виснет так, что не разбудишь даже подачей постоянного уровня на пин, как будто прерывание не включилось при уходе в слип. Если конечно это вообще не аппаратные проблемы типа помех по питанию.[/uquote]
На пьезо какое напряжение? Бывает их раскачивают...
watchmaker
Поставщик валерьянки для Кота
Сообщения: 2183
Зарегистрирован: Вс ноя 15, 2009 23:13:59
Откуда: Харьков
Контактная информация:

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение watchmaker »

Пьезо там уже нет, сигнал запуска с часового чипа идёт прямо на МК, а с МК совсем другой сигнал идёт через мосфет на 32 Ом динамик.
Иногда мой питомец уходит в такую спячку, что разбудить его можно только щелчком по первой ноге...
OKF
Это не хвост, это антенна
Сообщения: 1392
Зарегистрирован: Вт июн 07, 2011 08:03:18

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение OKF »

Я имею ввиду входное напряжение. И пофигу ваши динамики.
Аватара пользователя
VNS
Говорящий с текстолитом
Сообщения: 1624
Зарегистрирован: Пт дек 10, 2021 12:48:46
Откуда: Тюмень

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение VNS »

[uquote="watchmaker",url="/forum/viewtopic.php?p=4706384#p4706384"]ISR(PCINT0_vect)[/uquote]
Тогда (ИМХО) правильней использовать не регистр PCMSK в вашем случае, а регистр GIMSK (бит PCIE) для разрешения или запрета прерывания по маске пинов, а выбор пина (PCMSK) не трогать. Ну и не забывать при установке (PCIE), сбрасывать бит прерывания (PCIF).

Ну и сформировать достаточный временной потенциал для полного пробуждения МК.
watchmaker
Поставщик валерьянки для Кота
Сообщения: 2183
Зарегистрирован: Вс ноя 15, 2009 23:13:59
Откуда: Харьков
Контактная информация:

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение watchmaker »

Я имею ввиду входное напряжение. И пофигу ваши динамики.
3 В, как и на МК.
Тогда (ИМХО) правильней использовать не регистр PCMSK в вашем случае, а регистр GIMSK (бит PCIE) для разрешения или запрета прерывания по маске пинов, а выбор пина (PCMSK) не трогать. Ну и не забывать при установке (PCIE), сбрасывать бит прерывания (PCIF).
Попробую.
Кстати, в даташите написано, что этот флаг сбрасывается записью в него единицы. Это не опечатка, надо писать именно единицу?
Иногда мой питомец уходит в такую спячку, что разбудить его можно только щелчком по первой ноге...
Аватара пользователя
VNS
Говорящий с текстолитом
Сообщения: 1624
Зарегистрирован: Пт дек 10, 2021 12:48:46
Откуда: Тюмень

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение VNS »

[uquote="watchmaker",url="/forum/viewtopic.php?p=4706623#p4706623"]Это не опечатка, надо писать именно единицу?[/uquote]
Не опечатка, да "1".
fomkin1912
Открыл глаза
Сообщения: 46
Зарегистрирован: Пт дек 02, 2022 00:37:17

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение fomkin1912 »

Памагите! Вопрос тупой, но все извилины заплел.
Запрограммировал секундомер на Атмеге8 по учебному примеру, и все заработало. Но как?? как он работает???
В счетчике времени (переменная "display") установлена задержка 10мс - это 1/100 секунды (это точно, верьте - я уже на калькуляторе проверял). То есть счетчик увеличивается на единицу каждую сотую секунды, а на индикатор выводятся десятые! Почему???
Вот программа:
// Подключение семисегментных индикаторов к AVR. Динамическая индикация
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>

//---------------------------0-----1-----2-----3-----4-----5-----6-----7-----8------9
unsigned char SEGMENTE[] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F};

unsigned char segcounter = 0;
unsigned int display = 0;

// Обработчик прерывания по переполнению таймера 2
ISR(TIMER2_OVF_vect)
{
PORTD = 0xFF; // Гасим все разряды
PORTB = (1 << segcounter); // Выбираем следующий разряд

switch(segcounter)
{
case 0:
PORTD = ~(SEGMENTE[display % 10000 / 1000]); // Раскладываем число на разряды
break;
case 1:
PORTD = ~(SEGMENTE[display % 1000 / 100]);
break;
case 2:
PORTD = ~(SEGMENTE[display % 100 / 10]);
break;
case 3:
PORTD = ~(SEGMENTE[display % 10]);
break;
}
if(segcounter++ > 2) segcounter = 0;
}
// Главная функция
int main(void)
{
DDRB = 0xFF; // Порт B - выход
PORTB = 0x00;
DDRD = 0xFF; // Порт D - выход
PORTD = 0x00;

TCCR2 |= (1 << CS21); // Предделитель на 8
TIMSK |= (1 << TOIE2); // Разрешение прерывания по таймеру 2

sei(); // Глобально разрешаем прерывания

while(1)
{
display++; // Увеличиваем счет от 0 до 9999
if(display > 9999) display = 0;
_delay_ms(10); // Задержка
}
}
Последний раз редактировалось Аlex Чт ноя 06, 2025 16:23:49, всего редактировалось 1 раз.
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение Аlex »

Выведите, для начала, константу. И посмотрите, что выводится. Если не то, что нужно, - пошаговая отладка спасёт.
И, блин, ну что за форматирование ? Глаз дёргается.
Минута в интернете и всё красиво :
Спойлер

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

// Подключение семисегментных индикаторов к AVR. Динамическая индикация
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>

// Массив кодов для семисегментного индикатора (цифры 0-9)
unsigned char SEGMENTE[] = {
    0x3F, // 0
    0x06, // 1
    0x5B, // 2
    0x4F, // 3
    0x66, // 4
    0x6D, // 5
    0x7D, // 6
    0x07, // 7
    0x7F, // 8
    0x6F  // 9
};

unsigned char segcounter = 0;
unsigned int display = 0;

// Обработчик прерывания по переполнению таймера 2
ISR(TIMER2_OVF_vect)
{
    PORTD = 0xFF; // Гасим все разряды
    PORTB = (1 << segcounter); // Выбираем следующий разряд
    
    switch(segcounter)
    {
        case 0:
            PORTD = ~(SEGMENTE[display % 10000 / 1000]); // Тысячи
            break;
        case 1:
            PORTD = ~(SEGMENTE[display % 1000 / 100]); // Сотни
            break;
        case 2:
            PORTD = ~(SEGMENTE[display % 100 / 10]); // Десятки
            break;
        case 3:
            PORTD = ~(SEGMENTE[display % 10]); // Единицы
            break;
    }
    
    if(segcounter++ > 2)
        segcounter = 0;
}

// Главная функция
int main(void)
{
    // Настройка портов
    DDRB = 0xFF;  // Порт B - выход (выбор разряда)
    PORTB = 0x00;
    DDRD = 0xFF;  // Порт D - выход (сегменты)
    PORTD = 0x00;
    
    // Настройка таймера 2
    TCCR2 |= (1 << CS21);  // Предделитель на 8
    TIMSK |= (1 << TOIE2); // Разрешение прерывания по таймеру 2
    
    sei(); // Глобально разрешаем прерывания
    
    // Основной цикл
    while(1)
    {
        display++; // Увеличиваем счет от 0 до 9999
        
        if(display > 9999)
            display = 0;
            
        _delay_ms(10); // Задержка
    }
}
Ответить

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