Вот и я о том же... Где-то кракозябра...Аlex писал(а):На таких частотах индикаторы должны быть "как вкопанные". Что то у Вас не то ...DataLife писал(а):При делителе на 256 (8МГц / 256 = 31,25 кГц) виден дребезг![]()
CodeVision AVR в вопросах и ответах
Только те, кто предпринимают абсурдные попытки, смогут достичь невозможного.
- Реклама
DataLife, Вы, похоже, говорите не о частоте индикации (переполнения таймера), а о частоте его тактирования
31Кгц / 256 (разрешение таймера) / 4 (кол-во индикаторов) = ~30 Гц. Вот это уже похоже на правду
PS: Я в АВРах не силён, поищите там предделитель на 32, тогда у Вас получится примерно 1 Кгц - самое то для индикации.
31Кгц / 256 (разрешение таймера) / 4 (кол-во индикаторов) = ~30 Гц. Вот это уже похоже на правду
PS: Я в АВРах не силён, поищите там предделитель на 32, тогда у Вас получится примерно 1 Кгц - самое то для индикации.
Аlex, да, вы правы ...
На предделителе на 32 хорошо видны эти "непонятные сегменты", вопрос о которых остаётся открытым...
На предделителе на 32 хорошо видны эти "непонятные сегменты", вопрос о которых остаётся открытым...
Только те, кто предпринимают абсурдные попытки, смогут достичь невозможного.
Выложите самый Ваш последний код, при котором есть засветки.
Вот код:
Спойлер
Код: Выделить всё
#include <mega8.h>
#include <delay.h>
//Объявляем переменные
//------------------0-----1-----2-----3-----4-----5-----6-----7-----8------9----dp
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=0x00; // гасим сегменты, для перестраховки
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); PORTD|=(1<<7);}; //включаем точку во втором разряде
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 << CS22); // предделитель таймера2 на 64 (125 kHz)
#asm ("sei") // глобально разрешаем прерывания.
while (1)
{
ADC_result();
data_convert(ADC_volt);
delay_ms(500);
}
}Только те, кто предпринимают абсурдные попытки, смогут достичь невозможного.
- Реклама
Блин, вам же говорили, что гасить индикаторы надо не обнулением сегментов, а отключением общих катодов или анодов!
Погасили все общие, вывели новые сегменты, включили следующий общий...
А у вас после включения что-то ещё с портами делается
Погасили все общие, вывели новые сегменты, включили следующий общий...
А у вас после включения что-то ещё с портами делается
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
У меня этот вольтметр собран "в железе" и все "нововведения" испытываются на работоспособность. Могу убрать всё, что делается с портами после того, как в PORTD записывается значение значение цифры. Правда толку лог.0. Не помогает с засветкой неиспользуемых сегментов. Увы.ARV писал(а):А у вас после включения что-то ещё с портами делается
Только те, кто предпринимают абсурдные попытки, смогут достичь невозможного.
Ну у него, в принципе, перед сегментами гасятся общие. Просто для подстраховки отключает сегменты, хоть и бесполезно это всёARV писал(а):Блин, вам же говорили, что гасить индикаторы надо не обнулением сегментов, а отключением общих катодов или анодов!
DataLife, а схема подключения индикатора можно увидеть ?
Не вижу в коде ничего криминального, ну за исключением всяких мелочей (типа атомарных доступов к массиву), неактуальных на данный момент.
Аlex, даже не знаю, что и рисовать... Проще на словах, ибо тут всё предельно просто. Всё собрано на плате типа PinBoard как от ИзиЭлектроникс. Только Своего производства.
Мк АтМега8А-PU, питание от USB. Частота 8 МГц от внутреннего генератора.
Реферес для АЦП взят с AVCC + LC фильтр.
Индикатор с общим катодом, катоды подключены через транзисторы BC817. Между портом и базой резисторы 10к. (Используются порты PORTB0...3)
Сегменты подключены через резисторы 620 Ом на PORTD.
Вход АЦП на ADC0 (PC0). Использую несколько делителей на плате. Для измерения использую напряжения того же USB.
На этом всё, пожалуй. Ничего сверху, только вольтметр.

Мк АтМега8А-PU, питание от USB. Частота 8 МГц от внутреннего генератора.
Реферес для АЦП взят с AVCC + LC фильтр.
Индикатор с общим катодом, катоды подключены через транзисторы BC817. Между портом и базой резисторы 10к. (Используются порты PORTB0...3)
Сегменты подключены через резисторы 620 Ом на PORTD.
Вход АЦП на ADC0 (PC0). Использую несколько делителей на плате. Для измерения использую напряжения того же USB.
На этом всё, пожалуй. Ничего сверху, только вольтметр.
Только те, кто предпринимают абсурдные попытки, смогут достичь невозможного.
1. засветка сегментов зависит от показаний? т.е. разные сегменты подсвечиваются, если разные показания или всегда одни и те же?
2. если вместо ADC_result() использовать одинаковые цифры в массиве, засветка присутствует или нет?
2. если вместо ADC_result() использовать одинаковые цифры в массиве, засветка присутствует или нет?
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
Добрый день.
Нашел в интернете простую схему простого вольтметра на AVR. http://radioaktiv.ru/publ/lessons/digit ... tmetr.html. Не понятны только два нюанса, откуда там взялся магический коэффициент 4.73 и на основании каких данных был произведен расчет делителя? Можно ли пересчитать данную схему таким образом, чтобы расширить предел измерения напряжения с 10 вольт до 20.
И я прав, что в цепь питания AVCC надо поставить LC фильтр?
Спасибо.
Нашел в интернете простую схему простого вольтметра на AVR. http://radioaktiv.ru/publ/lessons/digit ... tmetr.html. Не понятны только два нюанса, откуда там взялся магический коэффициент 4.73 и на основании каких данных был произведен расчет делителя? Можно ли пересчитать данную схему таким образом, чтобы расширить предел измерения напряжения с 10 вольт до 20.
И я прав, что в цепь питания AVCC надо поставить LC фильтр?
Спасибо.
BenTech, в тексте есть пояснения:
Да, желательно иметь LC фильтр при использовании AVCC, так же посадите AREF через конденсатор 0,1 мФ на землю.
Раз используете AVCC - измените инициализацию АЦП: ADMUX = 0x40; //0b01000000 - AVCC , ACD0, ADLAR off
ЗЫ. ARV, по своей проблеме отпишусь чуть позже. Проверю...
Раз нужен вольтметр до 20 Вольт, то делитель нужен с коэффициентом "3". Например, резисторы 30к и 10к. Тогда при входном 20В на выходе делителя будет 5В....несложными расчетами подбираем наиболее правдоподобные резисторы на 56КОм и 15КОм, тогда наш коэффициент равен 4.73.
Да, желательно иметь LC фильтр при использовании AVCC, так же посадите AREF через конденсатор 0,1 мФ на землю.
Раз используете AVCC - измените инициализацию АЦП: ADMUX = 0x40; //0b01000000 - AVCC , ACD0, ADLAR off
ЗЫ. ARV, по своей проблеме отпишусь чуть позже. Проверю...
Только те, кто предпринимают абсурдные попытки, смогут достичь невозможного.
- Сообщения: 1817
- Зарегистрирован: Пн ноя 29, 2010 15:58:43
Добрый день!
подскажите пож. как проще 16 разрядное значение расписать по регистрам TCNT1H TCNT1L (atmega168p)?
подскажите пож. как проще 16 разрядное значение расписать по регистрам TCNT1H TCNT1L (atmega168p)?
Проще для кого - для Вас, для компилятора, или для читающего Ваш код ?
Способов много - деление с остатком, указатели, объединение (union), ...
Способов много - деление с остатком, указатели, объединение (union), ...
- Сообщения: 1817
- Зарегистрирован: Пн ноя 29, 2010 15:58:43
а зачем расписывать вручную, разве компилятор не поддерживает 16-битный вариант TCNT1?! WinAVR поддерживает однозначно!igor-x писал(а):Добрый день!
подскажите пож. как проще 16 разрядное значение расписать по регистрам TCNT1H TCNT1L (atmega168p)?
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- Сообщения: 1817
- Зарегистрирован: Пн ноя 29, 2010 15:58:43
вот.. никак не перейду на WinAvr ...WinAVR поддерживает однозначно
ARV, стало кое-что поясняться. Сделал обычный "счётчик": на индикатор выводятся каждые две секунды i++;
Постараюсь доходчиво объяснить. Имеем такую картинку: четыре разряда, например выводится значение 2015: [2][0][1][5]. Так вот, "фантомы" из правого разряда переходят на соседний левый! На двоечке силуэт ноля, на ноле (хоть и не видно) есть единичка, на единице - пятёрка. Когда "счётчик" тикает - это хорошо заметно.
Получается косяк теперь скорее ряде операторов if, мне так видится...
Постараюсь доходчиво объяснить. Имеем такую картинку: четыре разряда, например выводится значение 2015: [2][0][1][5]. Так вот, "фантомы" из правого разряда переходят на соседний левый! На двоечке силуэт ноля, на ноле (хоть и не видно) есть единичка, на единице - пятёрка. Когда "счётчик" тикает - это хорошо заметно.
Получается косяк теперь скорее ряде операторов if, мне так видится...
Последний раз редактировалось DataLife Вт авг 05, 2014 16:25:20, всего редактировалось 1 раз.
Только те, кто предпринимают абсурдные попытки, смогут достичь невозможного.
Всё равно не понимаю, почему в примере тогда коэффициент 4.73, если по такой логике должен быть 2, поскольку вольтметр на 10В?Раз нужен вольтметр до 20 Вольт, то делитель нужен с коэффициентом "3". Например, резисторы 30к и 10к. Тогда при входном 20В на выходе делителя будет 5В.
Да, там скорее всего опечатка. Там выбраны резисторы 56к и 15к (56/15 = 3,733).BenTech писал(а):Всё равно не понимаю, почему в примере тогда коэффициент 4.73, если по такой логике должен быть 2, поскольку вольтметр на 10В?Раз нужен вольтметр до 20 Вольт, то делитель нужен с коэффициентом "3". Например, резисторы 30к и 10к. Тогда при входном 20В на выходе делителя будет 5В.
Только те, кто предпринимают абсурдные попытки, смогут достичь невозможного.


