Страница 1 из 1
Динамическая индикация на ATTiny13
Добавлено: Пн сен 29, 2014 19:59:11
Gisteresis
Мяяяяу!
Бьюсь значит вот с каким шайтаном.
Сделал милливольтиметр на ATTiny13A. Частота 9.4МГц. Хочу вывести на 4значный семисегментный индикатор. Вывод динамический по прерыванию таймера, работает прекрасно. В прерывании АЦП происходит преобразование условных единиц АЦП в число и разбивка на декады, чтобы их потом выводило прерывание таймера. Все рабоает. Проверял выводом регистра АЦП. Выводит значение от 0 до 1023.
Первый вопрос.
Настроил преобразование АЦП на минимум, 73.438кГц. Значения на дисплее дергаются. Как сделать еще меньше? Например 2..3 преобразования в секунду.
Второй вопрос.
Преобразование кода сделал так
Код: Выделить всё
iVolts = 5*adc_data[0]-(24*adc_data[0]/1024)*5;
cDigit[0][0] = ~cSeg[((iVolts/1000)%10)];
cDigit[1][0] = ~cSeg[((iVolts/100 )%10)];
cDigit[2][0] = ~cSeg[((iVolts/10 )%10)];
cDigit[3][0] = ~cSeg[((iVolts/1 )%10)];
Понимаю, что изобрел протез. Как сделать нормально?
Если я просто делаю так
то преобразование упирается в 16ти битовое умножение. Операция 5000*adc_data[0] требует больше чем 16 бит.
Есть ли какой то аналог функции MulDiv?
Как это нормально сделать на ATTiny?
Расшифровывать эту писанину думаю не нужно?
cDigit[0][0] - это массив на 4 декады для того чтобы потом прерывание таймера брало оттуда и выводило.
cSeg - это массив с кодами семисегментного индикатора.
Просьба отослать к существующей ветке, если такая есть.
Re: Динамическая индикация на ATTiny13
Добавлено: Пн сен 29, 2014 20:32:39
ARV
во-первых: извиняюсь, вы применили какие-то схемные решения для подключения 7-сегментного 4-разрядного индикатора к МК с 6-ю доступными ножками? или ошибка и МК у вас другого типа?
во-вторых, преобразование значения АЦП в выводимые символы не надо делать в прерывании! это задача для главного цикла, где можно делать любые задержки, усреднения и т.п. штуки
Re: Динамическая индикация на ATTiny13
Добавлено: Пн сен 29, 2014 20:51:31
shads
Gisteresis писал(а):Первый вопрос.
Настроил преобразование АЦП на минимум, 73.438кГц. Значения на дисплее дергаются. Как сделать еще меньше? Например 2..3 преобразования в секунду.
Сделать усреднение... или просто поставь между обновлениями буфера дисплея _delay_ms (300);
(естественно - при этом динамическая обработка дисплея должна быть реализована в прерывании...)
Gisteresis писал(а):Второй вопрос.
Как сделать нормально?
Просто приведи любое из значений к 32-м разрядам...
Например так: iVolts = (uint32_t)5000*adc_data[0]/1024;
или так: iVolts = 5000UL*adc_data[0]/1024;
или так: iVolts = 5000*(uint32_t)adc_data[0]/1024
Re: Динамическая индикация на ATTiny13
Добавлено: Пн сен 29, 2014 21:03:40
vdavid
shads писал(а):
или так: iVolts = 5000*(uint8_t)adc_data[0]/1024
Ну только не так

.
Re: Динамическая индикация на ATTiny13
Добавлено: Пн сен 29, 2014 21:05:11
shads
vdavid писал(а):shads писал(а):
или так: iVolts = 5000*(uint8_t)adc_data[0]/1024
Ну только не так

.
Хе... по привычке написал... естественно - (uint32_t)... поправлю

...
Re: Динамическая индикация на ATTiny13
Добавлено: Пн сен 29, 2014 21:21:56
oleg110592
расчет можно подсократить, 4 разряд думаю не нужен - разрешение 1мВ вряд ли нормально получится
Код: Выделить всё
//V=(ADC*VAREF)/1024
//V=ADC*500/1024
//V=ADC*125/256
Voltage = (unsigned int)(((unsigned long)read_adc(3)*125)>>8);
binary to bcd:
Код: Выделить всё
void Bin2bcd(unsigned int Value)
{
unsigned char n=0;
while (Value >= 100)
{
Value -= 100;
n++;
}
Led0 = seg7[n];
n = 0;
while (Value >= 10)
{
Value -= 10;
n++;
}
Led1 = seg7[n];
Led2 = seg7[Value];
}
Спойлер

Re: Динамическая индикация на ATTiny13
Добавлено: Вт сен 30, 2014 08:05:03
Gisteresis
ARV писал(а):какие-то схемные решения для подключения 7-сегментного 4-разрядного индикатора
Извиняюсь что не написал, но вроде это и ненужно было. Эта часть работает хорошо. Стоят 2 регистра 595х в первый пишется код цифры, второй зажигает нужную декаду через транзистор. В прерывании таймера зажигается одна декада, следующее прерывание зажигает следующую декаду. И так по кругу прерывание обновляет декады. Тут собственно проблем нет.
ARV писал(а):преобразование значения АЦП в выводимые символы не надо делать в прерывании!
Те в главном цикле ждать завершения прерывания?
А чем плохо если я это сделаю сразу в прерывании АЦП? Там код небольшой.
shads писал(а):Сделать усреднение...
Да, начал догадываться до этого. Спасибо.
shads писал(а):Просто приведи любое из значений к 32-м разрядам...
А вот просто привести к 32битам не получается. Вначале компилер говорит что РАМ не хватает. Ну ладно, расширил. Потом он говорит что это действие невозможно так как в ATTiny13 MUL 16ти битный. Там хоть к long long приводи, он все равно результат отрежет значением 65535. Вот в том то и вопрос был. Как с этим ограничением преобразовать данные с АЦП в миливольты и разбить на декады. Я поэтому и вспомнил MULDIV но не знаю какой ее аналог есть в CV. Код искал, пока безрезультатно.
oleg110592 писал(а):расчет можно подсократить, 4 разряд думаю не нужен - разрешение 1мВ вряд ли нормально получится
Ну оно собственно и не получается, там скорее шум какой то. Вопрос был скорее по математике преобразования.
Насчет подсократить подумаю, хорошее решение, сам не догадался.
....
Эта операция не пройдет. Максимальное значение АЦП 1024 его максимум можно умножить на 64, получится максимум 65536.
Всем спасибо за подсказки.
Re: Динамическая индикация на ATTiny13
Добавлено: Вт сен 30, 2014 08:07:29
Dr. Alex
Gisteresis писал(а):... Частота 9.4МГц...
КАК????

Частота Тини13 9.6!!!!!
Re: Динамическая индикация на ATTiny13
Добавлено: Вт сен 30, 2014 08:13:28
Gisteresis
Dr. Alex писал(а):Частота Тини13 9.6!!!!!
Да, 9.6мГц, вы правы.
Re: Динамическая индикация на ATTiny13
Добавлено: Вт сен 30, 2014 08:18:43
oleg110592
приведение типов - (unsigned long)read_adc(3) теперь можно умножать на 125
Re: Динамическая индикация на ATTiny13
Добавлено: Вт сен 30, 2014 08:23:27
Gisteresis
В ATTiny13 сама операция умножения 16ти битная. Привести к 32м битам можно, но само умножение не получается. Все, что выше 16го бита отрезается. Фирштейн. Тоесть максимальное число, которым может манипулировать тини 65535.
АЦП = 1024
1024*125=128000 что больше 65535.
Re: Динамическая индикация на ATTiny13
Добавлено: Вт сен 30, 2014 08:26:50
oleg110592
все нормально работает (картинку приводил), причем тут тини - компилятор сделает всю работу
Re: Динамическая индикация на ATTiny13
Добавлено: Вт сен 30, 2014 08:33:01
Gisteresis
Попробую ваш код вечером.
Но у меня уже было написано 5000*adc_data[0], и тут мне компилятор заявлял что команда MUL 16 битная, повторяю уже 4й раз. То есть числа подаем 32х битные, но в 16битные регистры с отрезанием всего лишнего. И результат выходит 16ти битный.
Оно собирается в исполняемый файл и после прошивки я вижу что работает только 2 последних разряда и там шлак. Что собственно и ожидалось от такого умножения.
ПС: Чтобы не устраивать пустой холивар, ждем до вечера. Опробую, скажу результат.
Re: Динамическая индикация на ATTiny13
Добавлено: Вт сен 30, 2014 08:39:45
oleg110592
уже было написано 5000*adc_data[0]
если так, как выше товарищ
shads говорил:
Код: Выделить всё
unsigned long V;
V=5000UL*(unsigned long)adc_data[0];
компилятор не заявлял бы

Re: Динамическая индикация на ATTiny13
Добавлено: Вт сен 30, 2014 15:33:46
ARV
Gisteresis писал(а):ARV писал(а):преобразование значения АЦП в выводимые символы не надо делать в прерывании!
Те в главном цикле ждать завершения прерывания?А чем плохо если я это сделаю сразу в прерывании АЦП? Там код небольшой.
не надо ничего ждать. если вам так ужасно хочется, молотите прерываниями АЦП, и в обработчике прерываний помещайте результат в переменную, которую затем в главном цикле по мере необходимости обсчитывайте и выводите изредка. только учтите, что для работы с 2-байтной переменной нужно обеспечить атомарность доступа, т.е. как минимум делайте так:
Код: Выделить всё
volatile int result_adc; // сюда в прерывании помещается результат
int main(void){
// где-то в главном цикле делаете так
int tmp;
cli(); // запрет прерываний
tmp = result_adc;
sei(); // разрешение прерываний
// дальше обрабатываете переменную tmp
}
только все это бессмысленно. я бы делал именно так, как вы сказали мне в ответ: в главном цикле ждал бы окончания преобразования и дальше его обрабатывал бы...
Re: Динамическая индикация на ATTiny13
Добавлено: Вт сен 30, 2014 17:18:12
slavokhire5
Dr. Alex писал(а):Gisteresis писал(а):... Частота 9.4МГц...
КАК????

Частота Тини13 9.6!!!!!
В тини13 можно калибровать частоту =) так что 9.4 от внутреннего сделать не проблема
Re: Динамическая индикация на ATTiny13
Добавлено: Ср окт 01, 2014 08:03:00
Gisteresis
Модификатор UL решил проблему. Остальные множители не пришлось приводить к этому типу.
Сделал усреднение. В общем все заработало как надо. Даже пытается что то вроде 4го разряда показывать, очень грубо.
Всем спасибо.