CodeVision AVR в вопросах и ответах

Обсуждаем контроллеры компании Atmel.
Аватара пользователя
oleg110592
Друг Кота
Сообщения: 3832
Зарегистрирован: Сб сен 10, 2011 17:46:25

Re: CodeVision AVR в вопросах и ответах

Сообщение oleg110592 »

ADIF - флаг прерывания АЦП. Этот бит устанавливается в 1 когда АЦП завершено преобразование и в регистрах ADCL и ADCH находятся актуальные данные. Этот флаг устанавливается даже в том случае, если прерывания запрещены. Это необходимо для случая программного опроса АЦП. Если используются прерывания, то флаг сбрасывается автоматически. Если используется программный опрос, то флаг может быть сброшен записью лог.1 в этот бит.
ADIE - Если в этом бите установлена единица, и прерывания разрешены глобально, то при окончании преобразования будет выполнен переход по вектору прерывания от АЦП.

upd: чуть опоздал с ответом
Аватара пользователя
WiseLord
Друг Кота
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск
Контактная информация:

Re: CodeVision AVR в вопросах и ответах

Сообщение WiseLord »

Да, был неправ в этом плане
• Bit 4 – ADIF: ADC Interrupt Flag
This bit is set when an ADC conversion completes and the Data Registers are updated. The ADC Conversion Complete Interrupt is executed if the ADIE bit and the I-bit in SREG are set. ADIF is cleared by hardware when executing the corresponding interrupt Handling Vector. Alternatively, ADIF is cleared by writing a logical one to the flag. Beware that if doing a Read-Modify-Write on ADCSRA, a pending interrupt can be disabled. This also applies if the SBI and CBI instructions are used.

Странный подход, но не нам судить.

Но, на мой взгляд, лучше забыть про этот бит, и факт окончания измерений определять по ADSC, ушедшему в ноль.
Аватара пользователя
oleg110592
Друг Кота
Сообщения: 3832
Зарегистрирован: Сб сен 10, 2011 17:46:25

Re: CodeVision AVR в вопросах и ответах

Сообщение oleg110592 »

имхо лучше следовать рекомендациям производителя:
Application Note Atmel AVR126
Изображение
для STM8 тоже применял подобный подход для формирования микросекундных задержек на таймере - удобно следить за флагом прерываний без разрешения самих прерываний:

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

void delay_us(uint8_t us)
{
    TIM4->SR1 &= ~TIM4_SR1_UIF;
    TIM4->CNTR = 256-us; //
    TIM4->CR1 |= TIM4_CR1_CEN; // Разрешаем счет.
    while((TIM4->SR1 & TIM4_SR1_UIF)==0);
}

тут, правда, флаг как положено сбрасывается нулем
Аватара пользователя
DataLife
Вымогатель припоя
Сообщения: 601
Зарегистрирован: Пт фев 13, 2009 20:58:13
Откуда: Донецк

Re: CodeVision AVR в вопросах и ответах

Сообщение DataLife »

Ребят, помогите, пожалуйста... Который день не могу найти ошибку... Кто не в теме - это просто вольтметр... Идея построения кода взята тут: ТЫЦ
Спойлер#include <mega8.h>
#include <delay.h>

//Объявляем переменные

//----------
char SEGMENTE[] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F, 0x80};

unsigned int adc_data[4];
unsigned int ADC_volt;


/** ФУНКЦИЯ ПРЕОБРАЗОВАНИЯ **/

void data_convert(unsigned int value)
{
unsigned char tmp; // переменная для временного хранения данных преобразования

tmp = value / 1000;
adc_data[0] = SEGMENTE[tmp];
tmp = value % 1000 / 100;
adc_data[1] = SEGMENTE[tmp];
tmp = value % 100 / 10;
adc_data[2] = SEGMENTE[tmp];
tmp = value % 10;
adc_data[3] = SEGMENTE[tmp];
}

void ind_update (void)
{
static unsigned char count = 0;
PORTD = 0x00; // гасим все разряды
PORTD = adc_data[count]; // выводим в порт код цифры
if (count == 0) PORTB |= (1<<0);
if (count == 1) PORTB |= (1<<1); // перечисляем выводимые разряды
if (count == 2) PORTB |= (1<<2);
if (count == 3) PORTB |= (1<<3);
count++; // включаем следующий разряд
if (count == 4) count = 0;
}


void ADC_result(void)
{
unsigned int adc_tmp;

ADCSRA |= 0x40; //начинаем измерение
while((ADCSRA & 0x10)==0); //Ждём флаг окончания измерения
ADCSRA |=0x10;
adc_tmp=ADCW;
ADC_volt=adc_tmp*4.88;
}

// Обработчик прерывания по переполнению таймера2
interrupt [TIM2_OVF] void timer2_ovf_isr(void)
{
ind_update();
}

void main(void)
{
PORTB=0x00;
DDRB|=(1<<0)|(1<<1)|(1<<2)|(1<<3); // настройка на выход. 4 разряда

PORTD=0x00;
DDRD=0xFF; // настройка на выход всего порта

ADCSRA = 0x8E; //0b10001110 - предделитель на 64, прерывания разрешены, ADC включён
ADMUX = 0x40; //0b01000000 - AVCC , ACD0, ADLAR off

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


#asm ("sei") // глобально разрешаем прерывания.
while (1)
{
ADC_result();
data_convert(ADC_volt);
delay_ms(200);
}

}

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

Попробовал отключить прерывания от АЦП - индикатор ожил, но показывает галиматью... Скорее всего дело в выводе данных на индикатор, а это пересчёт в цифры => присвоение переменной из массива adc_data[n] значения из массива SEGMENTE[n] => присвоение значения adc_data[n] = PORTD...
Хотя, визуально, кажется какие-то значения проскакивают в белеберде на индикаторе... Просто горят ненужные сегменты, хотя перед выводом все гасятся (PORTD = 0x00) ... голова кругом... :facepalm:
Только те, кто предпринимают абсурдные попытки, смогут достичь невозможного.
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

Re: CodeVision AVR в вопросах и ответах

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

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

PORTD = 0x00; // гасим все разряды
Это не гашение, а ерунда :facepalm:
Логично предположить, что этой строки нет вообще, т.к. следом за ней сразу же идёт вывод данных в порт.
Аватара пользователя
DataLife
Вымогатель припоя
Сообщения: 601
Зарегистрирован: Пт фев 13, 2009 20:58:13
Откуда: Донецк

Re: CodeVision AVR в вопросах и ответах

Сообщение DataLife »

Аlex, ставить какую-либо задержку? Попробовал сделать задержку аж в 10 us - толку нет...
Да и работало оно, когда программа была по-другому скомпонована... Косяк где-то в другом ... :(
Только те, кто предпринимают абсурдные попытки, смогут достичь невозможного.
Аватара пользователя
Pink-Pank
Опытный кот
Сообщения: 721
Зарегистрирован: Ср июн 11, 2014 09:43:13
Откуда: США
Контактная информация:

Re: CodeVision AVR в вопросах и ответах

Сообщение Pink-Pank »

После того, как отобразили цифру - делайте задержку и выключайте порт В. А так у Вас после первого прогона сразу все цифры горят.
Либо заменяйте модификацию значения порта на обычное присваивание.
Последний раз редактировалось Pink-Pank Пн авг 04, 2014 19:09:19, всего редактировалось 1 раз.
Fucking static initialization order fiasco
Аватара пользователя
WiseLord
Друг Кота
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск
Контактная информация:

Re: CodeVision AVR в вопросах и ответах

Сообщение WiseLord »

ОК, в PORTD вы закинули код цифры. А нужную цифру - не выбрали:
DataLife писал(а):

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

if (count == 0) PORTB |= (1<<0);
if (count == 1) PORTB |= (1<<1); // перечисляем выводимые разряды
if (count == 2) PORTB |= (1<<2);
if (count == 3) PORTB |= (1<<3);

После прохождения count через 0..3 на порту B так и останутся единицы на всех разрядах.
Надо перед этим кодом добавить что-то вроде PORTB &= ~((1<<0) | (1<<1) | (1<<2) | (1<<3)), (погасить все цифры) а уже потом выбирать нужный разряд в зависимости от значения count.
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

Re: CodeVision AVR в вопросах и ответах

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

DataLife писал(а):Аlex, ставить какую-либо задержку? Попробовал сделать задержку аж в 10 us - толку нет...
Причём тут задержка ?
Вот, для примера, код :

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

PORTD=0;
PORTD=1;
Скажите, какой смысл в первой строчке ?
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: CodeVision AVR в вопросах и ответах

Сообщение ARV »

Аlex писал(а):

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

PORTD=0;
PORTD=1;
Скажите, какой смысл в первой строчке ?

строб?! :idea:
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

Re: CodeVision AVR в вопросах и ответах

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

ARV писал(а):строб?!
Я, почему то, именно этот ответ и именно от Вас ожидал :)))
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: CodeVision AVR в вопросах и ответах

Сообщение ARV »

Аlex писал(а):Я, почему то, именно этот ответ и именно от Вас ожидал :)))
почему, почему... умный человек потому что :))) ну и с юмором, похоже
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
DataLife
Вымогатель припоя
Сообщения: 601
Зарегистрирован: Пт фев 13, 2009 20:58:13
Откуда: Донецк

Re: CodeVision AVR в вопросах и ответах

Сообщение DataLife »

Ребята, памятник вам! :beer: Работает!
Честно говоря, стыдно ... Забыл гасить разряд перед выводом нового. :facepalm:
Правда теперь на высоких частотах работы таймера2 (250 кГц и выше) видны сегменты, которые вообще не должны гореть! То есть, благодаря задержке в сборе значений АЦП, картинка на индикаторе практически статична (например выводится значение напряжения питания МК: 4,75В), но горят и сегменты, которые "и рядом не стояли с этими цифрами"

Спойлер

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

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

//Объявляем переменные

//----------
char SEGMENTE[] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F, 0x80};

char adc_data[4];
volatile unsigned int ADC_volt;
                                       
   
/** ФУНКЦИЯ ПРЕОБРАЗОВАНИЯ **/
   
void data_convert(unsigned int value)
    {
     unsigned char tmp;   // переменная для временного хранения данных преобразования
     
     tmp = value / 1000;
     adc_data[0] = SEGMENTE[tmp];
     tmp = value % 1000 / 100;
     adc_data[1] = SEGMENTE[tmp];
     tmp = value % 100 / 10;
     adc_data[2] = SEGMENTE[tmp];
     tmp = value % 10;
     adc_data[3] = SEGMENTE[tmp];
    }

void ind_update (void)
    {
     static unsigned char count = 0;
     PORTD = 0;                          // гасим все сегменты
     PORTB &= ~((1<<0) | (1<<1) | (1<<2) | (1<<3));   // гасим все разряды

     PORTD = adc_data[count];           // выводим в порт код цифры
     if ((count == 0)&&(!(PORTD == 0x3F))) PORTB |= (1<<0);             // перечисляем выводимые разряды, не выводим "ноль" в первом разряде
     if (count == 1) PORTB |= (1<<1);   
     if (count == 2) PORTB |= (1<<2);
     if (count == 3) PORTB |= (1<<3);
     count++;                           // включаем следующий разряд
     if (count == 4) count = 0;
     
     
    }


void ADC_result(void)
{
        unsigned int adc_tmp;

        ADCSRA |= 0x40; //начинаем измерение
        while((ADCSRA & 0x10)==0); //Ждём флаг окончания измерения
        ADCSRA |=0x10;
        adc_tmp=ADCW;
        ADC_volt=(float)adc_tmp*4645/10000;     // не задумываемся над вычислениями
}

// Обработчик прерывания по переполнению таймера2
interrupt [TIM2_OVF] void timer2_ovf_isr(void)
{
  ind_update();           
}

void main(void)
{
 PORTB=0x00;
 DDRB|=(1<<0)|(1<<1)|(1<<2)|(1<<3); // настройка на выход. 4 разряда

 PORTD=0x00;
 DDRD=0xFF;                         // настройка на выход всего порта
 
 ADCSRA = 0x86; //0b10000110 - предделитель на 64, прерывания запрещены, ADC включён
 ADMUX = 0x40; //0b01000000 - AVCC , ACD0, ADLAR off

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

 
#asm ("sei") // глобально разрешаем прерывания.
while (1)
      {
      ADC_result();
      data_convert(ADC_volt);
      delay_ms(500);
      }

}


Аlex, прошу простить мою неграмотность в языке...
Что же, смею предположить, что PORTD=1; и PORTD=0x00; и PORTD=0b00000000; мне казалось, что одно и тоже в разных системах (десятичная, шестнадцатиричная, бинарная) ... Раз стал вопрос, то я ошибаюсь, скорее всего ...
Только те, кто предпринимают абсурдные попытки, смогут достичь невозможного.
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

Re: CodeVision AVR в вопросах и ответах

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

DataLife писал(а):Раз стал вопрос, то я ошибаюсь, скорее всего ...
Вопрос встал не об этом.
Команда PORTD=0x00; - бессмысленна, т.к. сразу же после неё идёт запись значения в порт. Соответственно, это не назовёшь гашением.

DataLife писал(а):на высоких частотах работы таймера2 (250 кГц и выше)
Не многовато ли для индикации ? :roll:
Аватара пользователя
WiseLord
Друг Кота
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск
Контактная информация:

Re: CodeVision AVR в вопросах и ответах

Сообщение WiseLord »

Видимо, инерционность светодиодов сказывается. Либо прерывания настолько часто идут, что не успевает обработчик выполниться.
Разбираться лень, но навскидку тут около 20 тактов процессора (не считая вызов подпрограммы из обработчика прерывания) так что при 250кГц развёртке это вполне может быть, особенно если частота тактовая ниже 8МГц. Так что лучше, как минимум, содержимое ind_update лучше прямо в обработчик поместить.

Попробуйте задержку после отключения разрядов добавить. Не знаю, как в CodeVision NOP реализуется, но что-то вроде:
Спойлер

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

{
   static unsigned char count = 0;

   PORTB &= ~((1<<0) | (1<<1) | (1<<2) | (1<<3));
   asm("nop");

   PORTD = adc_data[count];

   if (count == 0 && adc_data[0] != 0x3F) PORTB |= (1<<0);
   if (count == 1) PORTB |= (1<<1);   
   if (count == 2) PORTB |= (1<<2);
   if (count == 3) PORTB |= (1<<3);

   count = (count + 1) & 0x03;
}
Последний раз редактировалось WiseLord Пн авг 04, 2014 21:29:33, всего редактировалось 1 раз.
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: CodeVision AVR в вопросах и ответах

Сообщение ARV »

WiseLord писал(а):Видимо, инерционность светодиодов сказывается.
да вы чо?! :shock:
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
WiseLord
Друг Кота
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск
Контактная информация:

Re: CodeVision AVR в вопросах и ответах

Сообщение WiseLord »

ARV писал(а):да вы чо?! :shock:

Думаете? Мало ли там на каких проводах это всё подключено.. Хотя частота на светодиоде 250/4 кГц кажется и не сильно большой.

P.S. Порылся в закромах - у меня при тактовой 8МГц вполне работало и при делителе 8 (на 1МГц, делим на 3 сегмента => 330кГц на цифру). Так что, наверное, я и правда слишком плохо подумал о частоте светодиодов. Правда, у меня и обработчик прерывания был попроще:
Спойлер

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

#define SEG_PORT   PORTB
#define DIG_PORT   PORTD

#define DIG_UN      (1<<PD6) /* Units */
#define DIG_TE      (1<<PD5) /* Tens */
#define DIG_HU      (1<<PD4) /* Hundreds */
#define DIGITS      (DIG_UN | DIG_TE | DIG_HU)

static const uint8_t dig[3] = {DIG_UN, DIG_TE, DIG_HU};
static volatile uint8_t ind[3] = {0, 0, 0};

ISR (TIMER0_OVF_vect)
{
   static uint8_t pos = 0;

   DIG_PORT |= DIGITS;                           /* Switch off digits */
   SEG_PORT = ind[pos];                        /* Set data on segments */
   DIG_PORT &= ~dig[pos];                        /* Switch on current digit */

   pos++;
   if (pos > 2)
      pos = 0;

   return;
}
Последний раз редактировалось WiseLord Пн авг 04, 2014 21:40:06, всего редактировалось 5 раз.
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

Re: CodeVision AVR в вопросах и ответах

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

Да всё понятно что у DataLife'а происходит.
Судя по коду, индикатор с общим анодом.
Кодом

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

PORTD = 0;                          // гасим все сегменты
он не то что не гасит индикаторы, а наоборот "портит всю малину". Нули на катодах, наоборот - зажигают сегменты.
Вот и происходит подсветка, пока программа выполняет

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

PORTB &= ~((1<<0) | (1<<1) | (1<<2) | (1<<3));   // гасим все разряды
.
На небольших частотах, это было бы не так заметно, а на 250Кгц и выше, даже десятые доли микросекунд будут хорошо засвечивать светодиоды.

Если только, конечно, индикатор не с ОК и стоят ключи на разрядах.
В любом случае, последовательность такая - выключаем разряды, выставляем данные на сегменты, включаем соответствующий разряд. Тогда засветки никакой не будет.

ЗЫ: 2000-ное сообщение, пойду валерьянки 50 дёрну :beer: :))
Последний раз редактировалось ibiza11 Вт авг 05, 2014 10:13:11, всего редактировалось 2 раза.
Причина: -
Аватара пользователя
DataLife
Вымогатель припоя
Сообщения: 601
Зарегистрирован: Пт фев 13, 2009 20:58:13
Откуда: Донецк

Re: CodeVision AVR в вопросах и ответах

Сообщение DataLife »

Аlex писал(а):
DataLife писал(а):Раз стал вопрос, то я ошибаюсь, скорее всего ...
Вопрос встал не об этом.
Команда PORTD=0x00; - бессмысленна, т.к. сразу же после неё идёт запись значения в порт. Соответственно, это не назовёшь гашением.
А, теперь понял. Спасибо, буду учитывать с будущем :beer:

Аlex писал(а):
DataLife писал(а):на высоких частотах работы таймера2 (250 кГц и выше)
Не многовато ли для индикации ? :roll:
Просто "сам факт". При делителе на 256 (8МГц / 256 = 31,25 кГц) виден дребезг. На частоте 62,5 кГц нормально, но всё-равно очень тускло можно увидеть другие сегменты...

Аlex, ну не напрямую же у меня мой общий катод подключён. NPN транзистор присутствует, как положено :tea:

Ниже приведу код программы, того же вольтметра, но реализация "неверная". Делал на двух таймерах: один для АЦП, другой для индикации. Таймер индикации работает по переполнению и с частотой 1 Мгц (делитель на 8 ). Дело в том, что лишних сегментов нет! Выводится только то, что должно.

Спойлер

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

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

//наши переменные

//----------
char SEGMENTE[] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F, 0x80};

volatile unsigned char segcounter = 0;
volatile unsigned int adc_data = 0;
volatile unsigned int ADC_res=0;

void ADC_init(void)
    {
        ADCSRA = 0x8E; //0b10001110 - предделитель на 64, прерывания разрешены, ADC включён
        ADMUX = 0x40; //0b01000000 - AVCC , ACD0, ADLAR off
    }


// Обработчик прерывания по переполнению таймера0
interrupt [TIM1_OVF] void timer1_ovf_isr(void)
{
        ADCSRA |= 0x40; //начинаем измерение
        while((ADCSRA & 0x10)==0); //Ждём флаг окончания измерения
        ADCSRA |=0x10;
        adc_data=ADCW;
        ADC_res=adc_data*0.00488*100;

}

// Обработчик прерывания по переполнению таймера2
interrupt [TIM2_OVF] void timer2_ovf_isr(void)
{             
PORTD = 0x00; // гасим все сегменты
PORTB = (1<< segcounter); //выбираем следующий разряд
switch (segcounter)
{
case 0:
PORTD = (SEGMENTE[ADC_res % 10000 / 1000]); // Раскладываем число на разряды. Тысячи.
if (PORTD==0x3F) PORTD=0x00;                // знаю, что не правильно тут.
break;
case 1:
PORTD = (SEGMENTE[ADC_res % 1000 / 100])|(1<<7); // Сотни. Ставим точку для точности "до сотых"
break;
case 2:
PORTD = (SEGMENTE[ADC_res % 100 / 10]); // Десятки.
break;
case 3:
PORTD = (SEGMENTE[ADC_res % 10]); // Единицы.
break;
}
if ((segcounter++) > 2) segcounter = 0;
}


void main(void)
{

PORTB=0x00;
DDRB|=(1<<0)|(1<<1)|(1<<2)|(1<<3);

PORTC=0x00;
DDRC=0x00;

PORTD=0x00;
DDRD=0xFF;

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

ADC_init();
 
#asm ("sei") // глобально разрешаем прерывания.
while (1)
      {

      }
   
}
Только те, кто предпринимают абсурдные попытки, смогут достичь невозможного.
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

Re: CodeVision AVR в вопросах и ответах

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

DataLife писал(а):При делителе на 256 (8МГц / 256 = 31,25 кГц) виден дребезг
Что за дребезг ? Мерцание ?
На таких частотах индикаторы должны быть "как вкопанные". Что то у Вас не то ... :roll:
4 индикатора, 1 Кгц переключение (250 Гц на индикатор) - уже мерцание не видно даже когда трясёшь индикатор.
Ответить

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