Всем привет, написал программу для двойного семисегметика, попытался написать четверного, ну чтоб считал до 9999, но получается какая-та каша, хотя вроде по логике вещей всё делаю правильно, мб кто-нибудь знает как мне надо изменить программу для четрыхсемисегментиков, ( это прога написана для двойного семисегментика). #define F_CPU 4000000l #include #include #include unsigned int i; unsigned char direction; unsigned char R1=0, R2=0;
void ledprint(unsigned int number) { R1 = number%10; // младший разряд R2 = number/10; // старший разпряд } void segchar (unsigned char seg) { switch (seg) { case 1: PORTD = 0b11111001; break; case 2: PORTD = 0b10100100; break; case 3: PORTD = 0b10110000; break; case 4: PORTD = 0b10011001; break; case 5: PORTD = 0b10010010; break; case 6: PORTD = 0b10000010; break; case 7: PORTD = 0b11111000; break; case 8: PORTD = 0b10000000; break; case 9: PORTD = 0b10010000; break; case 0: PORTD = 0b11000000; break; } } unsigned char n_count=0;
ISR (TIMER1_COMPA_vect) {
if (n_count==0) { PORTB &=~(1<<PB0);// отключаем пб0, PORTB |= (1<<PB1);// включаем пб1 segchar(R1); } //--- if (n_count==1) // когда идёт переполнения { PORTB &=~(1<<PB1); PORTB |= (1<1) n_count =0;
Насчет каши - это в передачу "Поедем поедим", в представленном фрагменте ее, на мой взгляд, тоже хватает. Но утверждать уверенно не буду, бо Си для МК не применял. А по существу: для вывода вплоть до 9999 надо: а / подготовить данные, выделив сначала разряды тысяч и сотен, а дальше - как в тексте "R1=... , R2=...". б / последовательно выдать их в порт, для чего: - снять разрешение на выдачу напряжения на анод ( индикаторы с разделенными катодами? мой телепатор в ремонте) ; - подать код символа ( то как сделано - неоптимально через switch, я бы просто написал PORTD = mas_segm[seg] , где mas_segm - массив кодов сегментов во флеш-памяти ; - подать напряжение на анод соотв. знакоместа Похоже, взят откуда-то исходник, не особо вникая, как он работает, и исходник этот - типа задачки "помигать цифрами", я прав ? Иначе появилась бы необходимость найти еще 2 пины для добавившихся разрядов, как минимум. И в представленном фрагменте segchar(R2) где-то испарилось ; СпойлерЕсли заряжено ружье - должно же оно выстрелить .
СпойлерСтранно, вроде лето, а студенты задачками мучаются ...
_________________
Последний раз редактировалось Jack_A Вс авг 20, 2017 19:57:53, всего редактировалось 1 раз.
Насчет каши - это в передачу "Поедем поедим", в представленном фрагменте ее, на мой взгляд, тоже хватает. Но утверждать уверенно не буду, бо Си для МК не применял. А по существу: для вывода вплоть до 9999 надо: а / подготовить данные, выделив сначала разряды тысяч и сотен, а дальше - как в тексте "R1=... , R2=...". б / последовательно выдать их в порт, для чего: - снять разрешение на выдачу напряжения на анод ( индикаторы с разделенными катодами? мой телепатор в ремонте) ; - подать код символа ( то как сделано - неоптимально через switch, я бы просто написал PORTD = mas_segm[seg] ; - подать напряжение на анод соотв. знакоместа Похоже, взят откуда-то исходник, не особо вникая, как он работает, и исходник типа задачки "помигать цифрами", я прав ? Иначе появилась бы необходимость найти еще 2 пины для добавившихся разрядов, как минимум. СпойлерСтранно, вроде лето, а студенты задачками мучаются ...
вроде делал как ты сказал, но там какая-та фигня у меня светилась. Да я сам изучаю программирование, потому что в моей шараге меня ничему не научат.
Мы, эмбеддерщики, начинаем со схемы Куда подевались тысячи и сотни разложенного аргумента? Чем коммутируются аноды сотен и тысяч ? Рассекреть наконец - что за индикатор, желательно с распиновками, чтоб не елозить по поискам. И на конец - приведи твой мудифицированный код для 4 цифр , а то что за муйня у тебя на индикаторе - одному моему Мурзику известно.
А что, не удовлетворившись ответом в теме Помогите с семисегментиком нужно новую тему замутить ? 2- сегментник-то работает ? Нет, конечно, чтобы хотя бы видимость работы была, надо
Код:
if (n_count==0) { PORTB &=~(1<<PB0);// отключаем пб0, PORTB |= (1<<PB1);// включаем пб1 segchar(R1); n_count++ ; } //--- if (n_count==1) // когда идёт переполнения { PORTB &=~(1<<PB1); PORTB |= (1<<PB0) ; n_count =0; segchar(R2); }
Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ очень важен контроль процесса заряда и разряда для избегания воздействия внешнего зарядного напряжения после достижения 100% заряда. Инженеры КОМПЭЛ подготовили список таких решений от разных производителей.
Мы, эмбеддерщики, начинаем со схемы Куда подевались тысячи и сотни разложенного аргумента? Чем коммутируются аноды сотен и тысяч ? Рассекреть наконец - что за индикатор, желательно с распиновками, чтоб не елозить по поискам. И на конец - приведи твой мудифицированный код для 4 цифр , а то что за муйня у тебя на индикаторе - одному моему Мурзику известно.
А что, не удовлетворившись ответом в теме Помогите с семисегментиком нужно новую тему замутить ? 2- сегментник-то работает ? Нет, конечно, чтобы хотя бы видимость работы была, надо
Код:
if (n_count==0) { PORTB &=~(1<<PB0);// отключаем пб0, PORTB |= (1<<PB1);// включаем пб1 segchar(R1); n_count++ ; } //--- if (n_count==1) // когда идёт переполнения { PORTB &=~(1<<PB1); PORTB |= (1<<PB0) ; n_count =0; segchar(R2); }
смотри, вот я переписал, но какая-та фигня получается при симулчяции. #define F_CPU 4000000l #include <avr/io.h> #include <avr/interrupt.h> #include <util/delay.h> unsigned int i; unsigned char direction; unsigned char R1=0, R2=0, R3=0, R4=0;
void ledprint(unsigned int number) { R1 = number%1000; // младший разряд R2 = number/100; // старший разпряд R3 = number%10; // младший разряд R4 = number/10; // старший разпряд } void segchar (unsigned char seg) { switch (seg) { case 1: PORTD = 0b11111001; break; case 2: PORTD = 0b10100100; break; case 3: PORTD = 0b10110000; break; case 4: PORTD = 0b10011001; break; case 5: PORTD = 0b10010010; break; case 6: PORTD = 0b10000010; break; case 7: PORTD = 0b11111000; break; case 8: PORTD = 0b10000000; break; case 9: PORTD = 0b10010000; break; case 0: PORTD = 0b11000000; break; } } unsigned char n_count=0;
ISR (TIMER1_COMPA_vect) {
if (n_count==0) { PORTB &=~(1<<PB0);// ВКЛЮЧАЕМ пб0, PORTB |= (1<<PB1);// откл пб1 PORTB |= (1<<PB2);// откл пб2 PORTB |= (1<<PB3);// откл пб3 segchar(R1); } //--- if (n_count==1) // когда идёт переполнения { PORTB &=~(1<<PB1); PORTB |= (1<<PB0); PORTB |= (1<<PB2);// откл пб2 PORTB |= (1<<PB3);// откл пб3 segchar(R2); } if (n_count==1) // когда идёт переполнения { PORTB |=(1<<PB1); PORTB |= (1<<PB0); PORTB &= ~ (1<<PB2);// откл пб2 PORTB |= (1<<PB3);// откл пб3 segchar(R3); } if (n_count==1) // когда идёт переполнения { PORTB |=(1<<PB1); PORTB |= (1<<PB0); PORTB |= (1<<PB2);// откл пб2 PORTB &= ~(1<<PB3);// откл пб3 segchar(R4); } n_count++;
Компания EVE выпустила новый аккумулятор серии PLM, сочетающий в себе высокую безопасность, длительный срок службы, широкий температурный диапазон и высокую токоотдачу даже при отрицательной температуре.
Эти аккумуляторы поддерживают заряд при температуре от -40/-20°С (сниженным значением тока), безопасны (не воспламеняются и не взрываются) при механическом повреждении (протыкание и сдавливание), устойчивы к вибрации. Они могут применяться как для автотранспорта (трекеры, маячки, сигнализация), так и для промышленных устройств мониторинга, IoT-устройств.
СпойлерНе надо полностью цитировать предыдущее сообщение, а если ответ идет сразу за ним - не надо цитировать вообще. Если бы это было в разделе ПИТАНИЕ, Старичок надрал бы тебе за это жопу крапивой и отправил бы на неделю в баню. Тебе не кажется, что мы с тобой занимаемся бессмысленной работой: ты вносишь исправления, не задумываясь: а как это будет работать ? Например, раздраконивание числа на разряды легко проверить на листочке бумаги даже не прибегая к отладчику, а уж если пройтись отладчиком по точкам, то "дурь каждого сразу бы видна была", как говорил Петр I . Делается это примерно так:
Код:
R1 = number%10; // единицы R2 = (number%100)/10; // десятки R3 = (number%1000)/100; // сотни R4 = number/1000; // тысячи
или вариант
Код:
R4 = number/1000; // тысячи R3 = (number-R4*1000)/100; // сотни R2 = number%100 ; R1 = R2%10 // единицы R2 = R2/10 // десятки
Я не утверждаю, что код оптимальный, на асме это было бы компактнее ;
В третьем и четвертом if (n_count==1) будет ==2 и ==3 соответственно.
if(n_count>1) n_count =0; вместо >1 будет >3 или проще n_count &= 3 ; без всяких if'ов - инкрементируем счетчик и оставляем 2 младших разряда - так он всегда будет 0 - 1 - 2 - 3 - 0 - и т.д.
убери бессмысленный комментарий // когда идёт переполнения - никогда она не идет. ---------- И еще. Не знаю, как компилятор отнесется к передаче параметров в регистре - я не сишник - не затрет ли он их последующим кодом. Вот об этом надо бы спросить спецов в теме Нескольно простых вопросов о программировании AVR на Си, приведя наш самый верхний фрагмент кода . Вот что навскидку на первый взгляд. Дерзай !
СпойлерНе надо полностью цитировать предыдущее сообщение, а если ответ идет сразу за ним - не надо цитировать вообще. Если бы это было в разделе ПИТАНИЕ, Старичок надрал бы тебе за это жопу крапивой и отправил бы на неделю в баню. Тебе не кажется, что мы с тобой занимаемся бессмысленной работой: ты вносишь исправления, не задумываясь: а как это будет работать ? Например, раздраконивание числа на разряды легко проверить на листочке бумаги даже не прибегая к отладчику, а уж если пройтись отладчиком по точкам, то "дурь каждого сразу бы видна была", как говорил Петр I . Делается это примерно так:
Код:
R1 = number%10; // единицы R2 = (number%100)/10; // десятки R3 = (number%1000)/100; // сотни R4 = number/1000; // тысячи
или вариант
Код:
R4 = number/1000; // тысячи R3 = (number-R4*1000)/100; // сотни R2 = number%100 ; R1 = R2%10 // единицы R2 = R2/10 // десятки
Я не утверждаю, что код оптимальный, на асме это было бы компактнее ;
В третьем и четвертом if (n_count==1) будет ==2 и ==3 соответственно.
if(n_count>1) n_count =0; вместо >1 будет >3 или проще n_count &= 3 ; без всяких if'ов - инкрементируем счетчик и оставляем 2 младших разряда - так он всегда будет 0 - 1 - 2 - 3 - 0 - и т.д.
убери бессмысленный комментарий // когда идёт переполнения - никогда она не идет. ---------- И еще. Не знаю, как компилятор отнесется к передаче параметров в регистре - я не сишник - не затрет ли он их последующим кодом. Вот об этом надо бы спросить спецов в теме Нескольно простых вопросов о программировании AVR на Си, приведя наш самый верхний фрагмент кода . Вот что навскидку на первый взгляд. Дерзай !
Я ИСправил с ифами, ноп почему-то считает только до 99. ISR (TIMER1_COMPA_vect) {
нхаю Ты мои посты читаешь по диагонали, пропуская то , что ты считаешь ненужным ? Не надо цитировать предыдущий пост. Исправил вывод, а исправление разбивки числа на разряды - R1...R4 - Пушкин будет делать? То, что у меня в самом верху поста.
_________________
Последний раз редактировалось Jack_A Вт авг 22, 2017 09:42:23, всего редактировалось 1 раз.
нхаю Ты мои посты читаешь по диагонали, пропуская, как ты считаешь, ненужное ? Не надо цитировать предыдущий пост. Исправил вывод, а исправление разбивки числа на разряды - Пушкин будет делать? То, что у меня в самом верху поста.
- а в старших разрядах - ничего или мура какая-нибудь ? Запускаешь в Протеусе ? Ну тогда не знаю, чем тебе помочь. Ни Противнуса, ни Си для МК у меня нет - без надобности. Разбивку числа на разряды я проверил на ПК-шном Си, тут граблей нет. Попробуй вместо segchar(R?) проставить конкретные константы segchar(1); segchar(2); segchar(3); segchar(4); - посмотрим, что будет. И при ответе, нажав ЦИТАТА, очисть полностью окно редактирования. Раньше была кнопка ОТВЕТИТЬ - просто ответ без цитаты, почему-то поменяли. Thanks, musor Точно, надо тискать не ЦИТАТА, а ОТВЕТИТЬ слева внизу страницы
кнопка и ЕСТЬ есть слева снизу кроме того можно нажать редактор в быстром ответе
Добавлено after 30 seconds:
_________________ ZМудрость(Опыт и выдержка) приходит с годами. Все Ваши беды и проблемы, от недостатка знаний. Умный и у дурака научится, а дураку и .. Алберт Ейнштейн не поможет и ВВП не спасет.и МЧС опаздает
Заголовок сообщения: Re: Помогит с четверным семисегментиком
Добавлено: Вт авг 22, 2017 16:06:57
Встал на лапы
Зарегистрирован: Чт мар 22, 2012 20:28:49 Сообщений: 82
Рейтинг сообщения:0
Чувак, я в твой код особо не вникал, как-то не когда. Но могу подкинуть пару рабочих функций для вывода в четырехразрядный семисегментник
Код:
void display( int a, char num, char dp) { PORTD=0; PORTB=0; PORTC|=(1<<0)|(1<<1)|(1<<2)|(1<<3); switch (num) { case 1 : PORTC&=~(1<<0); break; case 2 : PORTC&=~(1<<1); break; case 3 : PORTC&=~(1<<2); break; case 4 : PORTC&=~(1<<3); break; default: break; }
switch (a) { case 1 : PORTD|=(1<<B)|(1<<C); break; case 2 : PORTD|=(1<<A)|(1<<B)|(1<<D)|(1<<E); PORTB|=(1<<G);break; case 3 : PORTD|=(1<<A)|(1<<B)|(1<<C)|(1<<D); PORTB|=(1<<G); break; case 4 : PORTD|=(1<<B)|(1<<C)|(1<<F); PORTB|=(1<<G); break; case 5 : PORTD|=(1<<A)|(1<<C)|(1<<D)|(1<<F); PORTB|=(1<<G); break; case 6 : PORTD|=(1<<A)|(1<<C)|(1<<D)|(1<<F)|(1<<E); PORTB|=(1<<G); break; case 7 : PORTD|=(1<<A)|(1<<B)|(1<<C); break; case 8 : PORTD|=(1<<A)|(1<<B)|(1<<C)|(1<<D)|(1<<E)|(1<<F); PORTB|=(1<<G); break; case 9 : PORTD|=(1<<A)|(1<<B)|(1<<C)|(1<<D)|(1<<F); PORTB|=(1<<G); break; case 0 : PORTD|=(1<<A)|(1<<B)|(1<<C)|(1<<D)|(1<<E)|(1<<F); break; case 100 : PORTD=0; PORTB = 0; break; case 33: PORTB|=(1<<G); break; default: break;
}
Здесь а - цифра (0...9), которую надо вывести, num - разряд (1..4), dp - наличие точки (1 - есть, ноль - нет). Порт, конечно нужно заменить на тот, который используешь
Далее функция выделения разряда
Код:
int razryd (int arg, int razr) { int e, d, s, t;
e = (arg % 10); if (razr==10) return e; d = ((arg-e)/10)%10; if (razr==100) return d; s = ((arg%1000)-e-d*10)/100; if (razr==1000) return s; t=((arg%10000)-e-d*10-s*100)/1000; if (razr==10000) return t; }
arg - число, из которого нужно вытащить разряд, razr - число, обозначающее разряд (10 - десятки, 100- сотни ну и т.д.)
Добавлено after 3 minutes 54 seconds: А вообще, правильно было сказано, схему бы посмотреть. Может в ней что не так...
традиционно забыли что переменные, изменяемые и в прерывании и в основном коде, должны объявляться volatile. Протеус раньше позволял пошаговую отладку - сразу станет ясно на каком этапе затык. В крайнем случае вот моя библиотека для работы с семисегментником. Впрочем, чтобы ей воспользоваться, тоже надо знать Си хотя бы на средненьком уровне.
Чувак, я в твой код особо не вникал, как-то не когда. Но могу подкинуть пару рабочих функций
Чувак, подпрограмма распиливания int на разряды, более компактная, тщательно протестирована. Так что дело не в ней. Вывод в сегменты табличным методом, без всяких кейсов, тоже был бы гораздо компактнее, и дело тоже не в нем. Как указывают знатоки, дело, скорее всего, в пресловутых volatil'ках; слово красивое, мы его не знаем, сами не местные и на Си писамши только на ЕС-1035 и СМ-4
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 45
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения