Перейти к содержанию

Вопросы от начинающих по МК


Рекомендуемые сообщения

Когда присваиваешь znachenie[] там же пропускай его через digit[], пусть в том массиве лежит уже готовая к выводу маска цифры. Зачем лишнюю работу делать? Значение у тебя там меняется реже чем выводится при динамической индикации.

Учение - изучение правил. Опыт - изучение исключений.

Ссылка на комментарий
Поделиться на другие сайты

Реклама: ООО ТД Промэлектроника, ИНН: 6659197470, Тел: 8 (800) 1000-321

  • Ответов
  • Создана
  • Последний ответ

Топ авторов темы

Изменил, но опять ничего не изменилось. Выводится что попало. Опять при изменении на i на цифру, всё выводится как надо.

interrupt [PCINT1] void pin_change_isr1(void) 
{
    if(flag==1){		   
					 rtc_get_time(&hour,&min,&sec);
					 hour_b=hour; min_b=min;
					 r1=0;r2=0;r3=0;r4=0;
					 while(hour_b>=10)  
					 {
					 hour_b-=10;
					 r1++;
					 }
					 r2=hour_b;

					 while(min_b>=10)
					 {
					 min_b-=10;
					 r3++;
					 }
					 r4=min_b;


					 }


	 if(flag==0){   
					 rtc_get_date(&date,&month,&year);
					 date_b=date; month_b=month;
					 r1=0;r2=0;r3=0;r4=0;
					 while(date_b>=10)
					 {
					 date_b-=10;
					 r1++;
					 }
					 r2=date_b;

					 while(month_b>=10)
					 {
					 month_b-=10;
					 r3++;
					 }
					 r4=month_b;

					 }									 
znachenie[0]=digit[r1];znachenie[1]=digit[r2];znachenie[2]=digit[r3];znachenie[3]=digit[r4];	   
step++;										  
}
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
#asm ("cli")
i++;
if(i==4) i=0;
PORTD= znachenie[i];
PORTB=0b00000000|razryad[i];
#asm("sei")	   
}

Ссылка на комментарий
Поделиться на другие сайты

20% скидка на весь каталог электронных компонентов в ТМ Электроникс!

Акция "Лето ближе - цены ниже", успей сделать выгодные покупки!

Плюс весь апрель действует скидка 10% по промокоду APREL24 + 15% кэшбэк и бесплатная доставка!

Перейти на страницу акции

Реклама: ООО ТМ ЭЛЕКТРОНИКС, ИНН: 7806548420, info@tmelectronics.ru, +7(812)4094849

А что будет, если при входе в прерывание по переполнению таймера i==8? Нигде не увидел ее начальной инициализации. Может условие поправить - if(i>=4) i=0; (чтобы в рамках держаться). И еще, cli и sei в прерываниях выставляются аппаратно и не требуется это делать программно.

Ссылка на комментарий
Поделиться на другие сайты

Выбираем схему BMS для корректной работы литий-железофосфатных (LiFePO4) аккумуляторов

 Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ, также как и для других, очень важен контроль процесса заряда и разряда, а специализированных микросхем для этого вида аккумуляторов не так много. Инженеры КОМПЭЛ подготовили список имеющихся микросхем и возможных решений от разных производителей. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

Отладчиком пройдись, научись наконец пользоваться отладкой.

Чтобы удобней было отлаживать, сделай тестовую программу в которой до бесконечности будет крутится то что у тебя сейчас внутри прерываний, а массив znachenie заполнить до этого. Можно даже точку прерывания поставить на выводе в порт, и выписывать пары состояний порта сегментов и разрядов.

Учение - изучение правил. Опыт - изучение исключений.

Ссылка на комментарий
Поделиться на другие сайты

Условие менял- не работает. Да и с переменной i все в порядке, так как разряды переключаются как надо. cli sei поставил уже от безысходности, думал мало ли приоритет у кого выше будет, если это делается аппаратно- уберу.

Пошёл изучать отладчики.

Ссылка на комментарий
Поделиться на другие сайты

static flash unsigned char digit [] = //ìàññèâ êîäîâ öèôð äëÿ âûâîäà íà èíäèêàòîð
 {
 (0b00000100), //0
 (0b00011111), //1
 (0b01001000), //2
 (0b00001010), //3
 (0b00010011), //4
 (0b00100010), //5
 (0b00100000), //6
 (0b00001111), //7
 (0b00000000), //8
 (0b00000010), //9
 (0b01111111) //off
 };

unsigned char znachenie [4];

static flash unsigned char razryad [4]=
 {
 (0b11110111),
 (0b11111011),
 (0b11111101),
 (0b11111110)
 };

извините что вклиниваюсь, но вот интересно зачем константы описывать как переменные???? :unknw: оперативки много или нравится исполнительный код в надцать раз увеличивать???
Ссылка на комментарий
Поделиться на другие сайты

Так там же все массивы во флэш пишутся. А тот, что не во флэш- постоянно меняется. Или я что-то неправильно понимаю? Какие могут быть извинения, я только рад критике, она помогает развиваться.

Ссылка на комментарий
Поделиться на другие сайты

причем здесь флеш??? вы создали/зарезервировали место в ОЗУ , и указали компилятору занести при инициализации начальные значения.... вопрос зачем создавать массив переменных, если по ходу пьесы значения массива не меняются те используются как константы???? просмотрите листинг во что компилятор превращает казалось бы простой код

i++;

if(i==4) i=0;

PORTD= digit [znachenie[i]]; //проблемная строка, если прописать вместо i 0, 1, 2, или 3, то все нормально отображается

PORTB=0b00000000|razryad[i];

да и переменные

unsignedchar znachenie [4];

и unsigned char i;

стоило бы описать как волентуне, кстати это касается и флагов...

Ссылка на комментарий
Поделиться на другие сайты

А что будет, если при входе в прерывание по переполнению таймера i==8? Нигде не увидел ее начальной инициализации. Может условие поправить - if(i>=4) i=0; (чтобы в рамках держаться). И еще, cli и sei в прерываниях выставляются аппаратно и не требуется это делать программно.

В глобальные переменные по умолчанию пишется 0. С остальным согласен.

На IMXO советую не обращать внимания, человек живет в каком-то своем, воображаемом мире, далеком от реальности.

По программе: с компилятором CV не знаком, на первый взгляд подводных камней не увидел.

Попробуйте объявить переменную i в прерывании со спецификатором static.

Изменено пользователем BerZerKku
Ссылка на комментарий
Поделиться на другие сайты

правильная функция отправки команд?

на 4 шины данных

void lcd_com (unsigned char lcd) //Передача команды ЖКИ
{
unsigned char temp;

temp=(lcd&~(1<<RS))|(1<<E); //RS=0 – это команда
PORTD=temp; //Выводим на portD старшую тетраду команды, сигналы RS, E
asm("nop"); //Небольшая задержка в 1 такт МК, для стабилизации
PORTD=temp&~(1<<E); //Сигнал записи команды

temp=((lcd*16)&~(1<<RS))|(1<<E); //RS=0 – это команда
PORTD=temp; //Выводим на portD младшую тетраду команды, сигналы RS, E
asm("nop"); //Небольшая задержка в 1 такт МК, для стабилизации
PORTD=temp&~(1<<E); //Сигнал записи команды

pause(10*TIME); //Пауза для выполнения команды
}

Ссылка на комментарий
Поделиться на другие сайты

Запусти проверь в протеусе осциллограмму. Попробуй изменять значение LCD от 0 до 255.

И вообще, я уже говорил - 4-битная делается двумя вызовами 8-битной только значение передаваемое разное.

А 8-битная реализуется просто.

И еще сядь посчитай вручную, будет ли у тебя меняться бит E в процессе выполнения этой подпрограммы. Не затрет ли переданное значение 0xFF в процедуру управляющие биты?

Учение - изучение правил. Опыт - изучение исключений.

Ссылка на комментарий
Поделиться на другие сайты

Уже сотый раз меняю инициализации, а ничего не меняется. Инициализация инкремент и сброс переменной i работаю как надо, об этом говорит корректная её работа в строчке:

PORTB=0b00000000|razryad[i];  //сегменты исправно переключаются.

Не работает лишь строка:

PORTD= znachenie[i]; 

Если написать так:

PORTD= znachenie[3];

то на всех разрядах отображается цифра, соответствующая разряду 4, так и должно быть, ведь znachenie[3] это и есть цифра для 4го разряда. Получается не рааботает простейшая строчка, не считывается массив, или считывается неверно и ничего поделать с этим не получается. Можно придумать что- то другое, но почему это- то не работает?

Ссылка на комментарий
Поделиться на другие сайты

Код особо не не смотрел, но чисто ради интереса, поставьте размерность массива (11) в строчке:

static flash unsigned char digit [] =...

Любой, заслуживающий внимания, опыт приобретается себе в убыток...

Ссылка на комментарий
Поделиться на другие сайты

Тогда приложите проект полностью (с моделью если есть) - аж интересно стало )

Любой, заслуживающий внимания, опыт приобретается себе в убыток...

Ссылка на комментарий
Поделиться на другие сайты

Все работает, подправил вывод (индикатор гасить надо перед сменой цифры, а выводить новое значение - после), плюс по мелочи немного - точки убрал лишние и т.д. Научитесь пользоваться отладкой в Протеусе, раз уж пользуетесь таким мощным инструментом:

post-20311-0-98280400-1386707393_thumb.gif

Исправленный проект прилагается, собственно принципиальные изменения коснулись только:

interrupt [TIM0_OVF] void timer0_ovf_isr(void) //прерывание по переполнеению TC0
{
//#asm ("cli")
PORTD=0xff; //off
i++;
if(i>=4) i=0;
PORTB=0b00000000|razryad[i];
PORTD=znachenie[i];
if(i==1) PORTD&=~(1<<7); //point
...

ЗЫ. Честно говоря, код и стиль в проекте немного не того )))

В проекте (Configure) есть волшебнst галочкИ (Register Allocation), снятие которых позволяет видеть в протеусе все переменные. Назад можно поставить перед прошивкой железа.

CVAVR.RAR

Изменено пользователем Goodefine

Любой, заслуживающий внимания, опыт приобретается себе в убыток...

Ссылка на комментарий
Поделиться на другие сайты

Хм, вообще да. Надо сначала погасить все сегменты, потом переключить РАЗРЯД, и только после этого ставить новое значение сегментов. Протеус конечно накладывал эти оба соседние значения друг на друга, а в реальности наложение выглядело бы как небольшая засветка.

Учение - изучение правил. Опыт - изучение исключений.

Ссылка на комментарий
Поделиться на другие сайты

Alexeyslav

я понимаю как это делается, порты на дисплей остаются 4 шины, отправка такая же идет как на 8, но как програмно разделить символ на старшую и младшую я вот понять не могу? допустим взяли символ "H" его делим /255 и 2 действие H%255 так?

Ссылка на комментарий
Поделиться на другие сайты

Научитесь пользоваться отладкой в Протеусе, раз уж пользуетесь таким мощным инструментом:

Исправленный проект прилагается, собственно принципиальные изменения коснулись только:

interrupt [TIM0_OVF] void timer0_ovf_isr(void) //прерывание по переполнеению TC0
{
PORTD=0xff; //off
i++;
if(i>=4) i=0;
PORTB=0b00000000|razryad[i];
PORTD=znachenie[i];
if(i==1) PORTD&=~(1<<7); //point
...

ЗЫ. Честно говоря, код и стиль в проекте немного не того )))

В проекте (Configure) есть волшебнst галочкИ (Register Allocation), снятие которых позволяет видеть в протеусе все переменные. Назад можно поставить перед прошивкой железа.

Спасибо большое за помощь! Несколько дней голову ломаю. А что не так в стиле и коде? Я только начинаю программировать и было бы очень хорошо учиться сразу правильно, чтобы потом не переучиваться.

Изменено пользователем serenbkii
Ссылка на комментарий
Поделиться на другие сайты

но как програмно разделить символ на старшую и младшую

Старшая часть - (data AND 0xF0) младшая - (data AND 0x0F) << 4

Учение - изучение правил. Опыт - изучение исключений.

Ссылка на комментарий
Поделиться на другие сайты

А что не так в стиле и коде? Я только начинаю программировать и было бы очень хорошо учиться сразу правильно, чтобы потом не переучиваться.

Если хотите сразу правильно, то мое мнение (без претензии на истину):

-имена функций и переменных - маленькими буквами, информативно (тогда и комментарии не нужны часто)

-имена макроподстановок, перечислений - большими буквами

-не использовать константы в коде в числовой форме (только через макроподстановки сделанные один раз)

-не использовать компиляторозависимые конструкции, например PORTD.=1;

-каждую функциональную сущность (дисплей, клавиатура и прочее) оформлять в виде модуля. Модуль состоит из двух файлов: xxx.h и xxx.c В хидере описываются макроподстановки, перечисления, ПРОТОТИПЫ функций (но никак не сами функции) в обрамлении исключающем повторное включение файла. Получается аналог с++ класса - в хидере интерфейс, в с-файле - реализация функций. Можно также оформлять и прерывания. В главном модуле только логика работы устройства в целом. В его хидере - настройки в виде констант и прочего.

-главный цикл желательно выполнять в виде автомата состояний

-крайне желательно делать слой hal - для миграции между платформами

-другие моменты, которые придут с опытом )))

В качестве примера (как раз с динамической индикацией на 4-ре цифры) можете посмотреть этот проект. Там, конечно, не все так, как описано выше, но примерно

Любой, заслуживающий внимания, опыт приобретается себе в убыток...

Ссылка на комментарий
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы публикуете как гость. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.
Примечание: Ваш пост будет проверен модератором, прежде чем станет видимым.

Гость
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Ответить в этой теме...

×   Вставлено с форматированием.   Восстановить форматирование

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

Загрузка...
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу

×
×
  • Создать...