Страница 316 из 421
Re: CodeVision AVR в вопросах и ответах
Добавлено: Пн авг 04, 2014 22:19:36
DataLife
Аlex писал(а):DataLife писал(а):При делителе на 256 (8МГц / 256 = 31,25 кГц) виден дребезг
На таких частотах индикаторы должны быть "как вкопанные". Что то у Вас не то ...
Вот и я о том же... Где-то кракозябра...

Но, за два хоть как-то код стал работать. Не без вашей помощи, конечно

Re: CodeVision AVR в вопросах и ответах
Добавлено: Пн авг 04, 2014 22:26:14
Аlex
DataLife, Вы, похоже, говорите не о частоте индикации (переполнения таймера), а о частоте его тактирования
31Кгц / 256 (разрешение таймера) / 4 (кол-во индикаторов) = ~30 Гц. Вот это уже похоже на правду
PS: Я в АВРах не силён, поищите там предделитель на 32, тогда у Вас получится примерно 1 Кгц - самое то для индикации.
Re: CodeVision AVR в вопросах и ответах
Добавлено: Пн авг 04, 2014 22:37:39
DataLife
Аlex, да, вы правы ...
На предделителе на 32 хорошо видны эти "непонятные сегменты", вопрос о которых остаётся открытым...
Re: CodeVision AVR в вопросах и ответах
Добавлено: Пн авг 04, 2014 22:39:47
Аlex
Выложите самый Ваш последний код, при котором есть засветки.
Re: CodeVision AVR в вопросах и ответах
Добавлено: Пн авг 04, 2014 22:43:19
DataLife
Вот код:
Спойлер
Код: Выделить всё
#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);
}
}
Re: CodeVision AVR в вопросах и ответах
Добавлено: Пн авг 04, 2014 22:56:34
ARV
Блин, вам же говорили, что гасить индикаторы надо не обнулением сегментов, а отключением общих катодов или анодов!
Погасили все общие, вывели новые сегменты, включили следующий общий...
А у вас после включения что-то ещё с портами делается
Re: CodeVision AVR в вопросах и ответах
Добавлено: Пн авг 04, 2014 23:07:32
DataLife
ARV писал(а):А у вас после включения что-то ещё с портами делается
У меня этот вольтметр собран "в железе" и все "нововведения" испытываются на работоспособность. Могу убрать всё, что делается с портами после того, как в PORTD записывается значение значение цифры. Правда толку лог.0. Не помогает с засветкой неиспользуемых сегментов. Увы.
Re: CodeVision AVR в вопросах и ответах
Добавлено: Пн авг 04, 2014 23:12:35
Аlex
ARV писал(а):Блин, вам же говорили, что гасить индикаторы надо не обнулением сегментов, а отключением общих катодов или анодов!
Ну у него, в принципе, перед сегментами гасятся общие. Просто для подстраховки отключает сегменты, хоть и бесполезно это всё
DataLife, а схема подключения индикатора можно увидеть ?
Не вижу в коде ничего криминального, ну за исключением всяких мелочей (типа атомарных доступов к массиву), неактуальных на данный момент.
Re: CodeVision AVR в вопросах и ответах
Добавлено: Вт авг 05, 2014 00:05:51
DataLife
Аlex, даже не знаю, что и рисовать... Проще на словах, ибо тут всё предельно просто. Всё собрано на плате типа PinBoard как от ИзиЭлектроникс. Только Своего производства.
Мк АтМега8А-PU, питание от USB. Частота 8 МГц от внутреннего генератора.
Реферес для АЦП взят с AVCC + LC фильтр.
Индикатор с общим катодом, катоды подключены через транзисторы BC817. Между портом и базой резисторы 10к. (Используются порты PORTB0...3)
Сегменты подключены через резисторы 620 Ом на PORTD.
Вход АЦП на ADC0 (PC0). Использую несколько делителей на плате. Для измерения использую напряжения того же USB.
На этом всё, пожалуй. Ничего сверху, только вольтметр.

Re: CodeVision AVR в вопросах и ответах
Добавлено: Вт авг 05, 2014 07:18:03
ARV
1. засветка сегментов зависит от показаний? т.е. разные сегменты подсвечиваются, если разные показания или всегда одни и те же?
2. если вместо ADC_result() использовать одинаковые цифры в массиве, засветка присутствует или нет?
Re: CodeVision AVR в вопросах и ответах
Добавлено: Вт авг 05, 2014 10:43:29
BenTech
Добрый день.
Нашел в интернете простую схему простого вольтметра на AVR.
http://radioaktiv.ru/publ/lessons/digit ... tmetr.html. Не понятны только два нюанса, откуда там взялся магический коэффициент 4.73 и на основании каких данных был произведен расчет делителя? Можно ли пересчитать данную схему таким образом, чтобы расширить предел измерения напряжения с 10 вольт до 20.
И я прав, что в цепь питания AVCC надо поставить LC фильтр?
Спасибо.
Re: CodeVision AVR в вопросах и ответах
Добавлено: Вт авг 05, 2014 13:41:23
DataLife
BenTech, в тексте есть пояснения:
...несложными расчетами подбираем наиболее правдоподобные резисторы на 56КОм и 15КОм, тогда наш коэффициент равен 4.73.
Раз нужен вольтметр до 20 Вольт, то делитель нужен с коэффициентом "3". Например, резисторы 30к и 10к. Тогда при входном 20В на выходе делителя будет 5В.
Да, желательно иметь LC фильтр при использовании AVCC, так же посадите AREF через конденсатор 0,1 мФ на землю.
Раз используете AVCC - измените инициализацию
АЦП: ADMUX = 0x40; //0b01000000 - AVCC , ACD0, ADLAR off
ЗЫ.
ARV, по своей проблеме отпишусь чуть позже. Проверю...
Re: CodeVision AVR в вопросах и ответах
Добавлено: Вт авг 05, 2014 14:58:44
igor-x
Добрый день!
подскажите пож. как проще 16 разрядное значение расписать по регистрам TCNT1H TCNT1L (atmega168p)?
Re: CodeVision AVR в вопросах и ответах
Добавлено: Вт авг 05, 2014 15:04:45
Аlex
Проще для кого - для Вас, для компилятора, или для читающего Ваш код ?
Способов много - деление с остатком, указатели, объединение (union), ...
Re: CodeVision AVR в вопросах и ответах
Добавлено: Вт авг 05, 2014 15:09:37
igor-x
объединение (union)
буду признателен за такой вариант!
Re: CodeVision AVR в вопросах и ответах
Добавлено: Вт авг 05, 2014 15:37:51
ARV
igor-x писал(а):Добрый день!
подскажите пож. как проще 16 разрядное значение расписать по регистрам TCNT1H TCNT1L (atmega168p)?
а зачем расписывать вручную, разве компилятор не поддерживает 16-битный вариант TCNT1?! WinAVR поддерживает однозначно!
Re: CodeVision AVR в вопросах и ответах
Добавлено: Вт авг 05, 2014 15:50:26
igor-x
WinAVR поддерживает однозначно
вот.. никак не перейду на WinAvr ...
Re: CodeVision AVR в вопросах и ответах
Добавлено: Вт авг 05, 2014 16:01:19
DataLife
ARV, стало кое-что поясняться. Сделал обычный "счётчик": на индикатор выводятся каждые две секунды i++;
Постараюсь доходчиво объяснить. Имеем такую картинку: четыре разряда, например выводится значение 2015: [2][0][1][5]. Так вот, "фантомы" из правого разряда переходят на соседний левый! На двоечке силуэт ноля, на ноле (хоть и не видно) есть единичка, на единице - пятёрка. Когда "счётчик" тикает - это хорошо заметно.
Получается косяк теперь скорее ряде операторов
if, мне так видится...

Re: CodeVision AVR в вопросах и ответах
Добавлено: Вт авг 05, 2014 16:24:39
BenTech
Раз нужен вольтметр до 20 Вольт, то делитель нужен с коэффициентом "3". Например, резисторы 30к и 10к. Тогда при входном 20В на выходе делителя будет 5В.
Всё равно не понимаю, почему в примере тогда коэффициент 4.73, если по такой логике должен быть 2, поскольку вольтметр на 10В?
Re: CodeVision AVR в вопросах и ответах
Добавлено: Вт авг 05, 2014 16:28:27
DataLife
BenTech писал(а):Раз нужен вольтметр до 20 Вольт, то делитель нужен с коэффициентом "3". Например, резисторы 30к и 10к. Тогда при входном 20В на выходе делителя будет 5В.
Всё равно не понимаю, почему в примере тогда коэффициент 4.73, если по такой логике должен быть 2, поскольку вольтметр на 10В?
Да, там скорее всего опечатка. Там выбраны резисторы 56к и 15к (56/15 = 3,733).