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

Динамическая индикация

Приветствую всех! Стал с недавнего времени учиться программированию МК.

Но споткнулся на следующей проблеме - добрался до сегментных индикаторов.

При выводе цифр в ручную или из массива, все выводится хорошо.

Но при попытке применить динамическую индикацию, создаю функцию, и если я вызываю эту функцию в while1, то сегменты тупо ничего не отображают, но стоит закомментировать ее и сразу все работает.

Микроконтроллер Использую atmega 128a, тактирование от внешнего резонатора 16mhz. Отладочная плата waveshare OpenM128a и их же индикатор. Прошиваюсь через usb asp

#define F_CPU 16000000UL
#include <avr/io.h>
#include <util/delay.h>
/*#define seg1 PORTA= 0xF1;
#define seg2 PORTA= 0xF2;
#define seg3 PORTA= 0xF4;
#define seg4 PORTA= 0xF8;*/
#define  SEG7_DDR DDRC
#define  SEG7_PORT PORTC


unsigned int numbers[10]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};

int razr1 =0;
int razr2 =0;
int razr3 =0;
int razr4 =0;


void chislo (unsigned int rabivka_chisla)
{
	
	razr1 = rabivka_chisla/1000;            // тысячи
	razr2 = rabivka_chisla%1000/100;  // сотни
	razr3 = rabivka_chisla%100/10;          // десятки
	razr4 = rabivka_chisla%10;              // единицы
}


int main(void)
{

	DDRA  |=(1<<PINA0) | (1<<PINA1) | (0<<PINA2) | (0<<PINA3);
	PORTA |=(1<<PINA0) | (0<<PINA1) | (0<<PINA2) | (0<<PINA3);
	SEG7_DDR = 0xFF;
	SEG7_PORT = 0x00;
	

	
	while(1)
	{
		//chislo(1987);
		SEG7_PORT = numbers[1];
		//chislo(1000);
		//vivod = 0xF9;
		/*seg1;
		vivod = dat[4];
		_delay_ms(2);
		
		seg2;
		vivod = dat[7];
		_delay_ms(2);
		
		seg3;
		vivod = dat[5];
		_delay_ms(2);
		
		seg4;
		vivod = dat[2];
		_delay_ms(2);*/
		
		
	}
}

 

Схема индикатора.png

фьюзы.png

Поделиться сообщением


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

On 8/6/2023 at 10:27 PM, Devil Byte said:

Приветствую всех! Стал с недавнего времени учиться программированию МК.

 

Схема плохая. Даже ужасная.

Может они хотели сделать двойную динамическую индикацию ? Перебирать не только знакоместа, но и сегменты тоже.

Но она даже в таком случае будет работать враскоряку.

DDRA  |=(1<<PINA0) | (1<<PINA1) | (0<<PINA2) | (0<<PINA3);

PINA2 и PINA3 у вас настроены на вход, а не на выход.

В ваших закомментированных строках, что за переменные vivod и dat[4] ? Где они объявлены ?

Переменные razr вообще нигде не используются, да и вычисляются не понятно как.

Поделиться сообщением


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

14 минут назад, dimka76 сказал:

Схема плохая. Даже ужасная.

Может они хотели сделать двойную динамическую индикацию ? Перебирать не только знакоместа, но и сегменты тоже.

Но она даже в таком случае будет работать враскоряку.

DDRA  |=(1<<PINA0) | (1<<PINA1) | (0<<PINA2) | (0<<PINA3);

 

Привет! Да забыл уже поменять.. Ок, оставим только pin0. Если я его включаю и вывожу какой-то элемент из массива number, руками, или через задержку с помощью какого нибудь цикла, индикатор отлично переключается.  Vivod это seg7_port,  а dat это массив number. 

Допустим я я хочу вывести на 4 сегмента чилсо 1987. Для этого мне его нужно разбить на разряды. Это и происходит в функции void chislo. 

Но как как только я пытаюсь записать в массив значение razr1(оно должно быть один.. Так как деление 1987/1000даст один из за того что остаток отбрасывает я). То индикатор вообще гаснет. Хотя по идее на pin должна быть еденица

Или же надо как то по другому делить чилсо на разряды и записывать в сегменты? 

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

Поделиться сообщением


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

On 8/6/2023 at 11:28 PM, Devil Byte said:

Но как как только я пытаюсь записать в массив значение razr1(оно должно быть один..

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

On 8/6/2023 at 11:28 PM, Devil Byte said:

То индикатор вообще гаснет.

Посмотрите вольтметром, что вы выводах микроконтроллера, что на выводах индикатора.

Поделиться сообщением


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

4 минуты назад, dimka76 сказал:

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

Посмотрите вольтметром, что вы выводах микроконтроллера, что на выводах индикатора.

Вот смысл в том что переменная razr1 содержит в себе единицу. И если я вместо номера элемента в массиве пишу rarzr1, то я из массива должен получить еденицу на сегменте, а он тухнет. 

А если например сделать запись razr1= 1/1;  и сунуть её  в numbers[rarzr1];  то пкоцно отобразится нужная цифра из массива 

Поделиться сообщением


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

On 8/6/2023 at 11:52 PM, Devil Byte said:

Вот смысл в том что переменная razr1 содержит в себе единицу. И если я вместо номера элемента в массиве пишу rarzr1, то я из массива должен получить еденицу на сегменте, а он тухнет. 

А если например сделать запись razr1= 1/1;  и сунуть её  в numbers[rarzr1];  то пкоцно отобразится нужная цифра из массива 

Кстати, у вас каша с типами.

Порт у вас восьмибитный, а массив numbers, из которого вы берете значения для вывода в порт - int.
Функция chislo принимает аргумент беззнаковый - unsigned int, а оперирует со знаковыми числами razr1.

Поделиться сообщением


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

5 часов назад, dimka76 сказал:

Кстати, у вас каша с типами.

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

#define F_CPU 16000000UL
#include <avr/io.h>
#include <util/delay.h>
#define  SEG7_DDR DDRC   //устанавливаю на регистр С дефайн SEG7_DDR (подключены индикаторы сегментные)
#define  SEG7_PORT PORTC //устанавливаю на порт С дефайн SEG7_PORT   (подключены индикаторы сегментные)


unsigned int numbers[10]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90}; // массив чисел от 0 до 9 (по порядку)

// Инициализация переменных для разбивки числа на разряды
unsigned int razr1 =0;
unsigned int razr2 =0;
unsigned int razr3 =0;
unsigned int razr4 =0;

// Создаю функцию деления числа на разряды
void chislo (unsigned int razbivka_chisla)
{
	razr1 = razbivka_chisla/1000;            // тысячи
	razr2 = razbivka_chisla%1000/100;		// сотни
	razr3 = razbivka_chisla%100/10;          // десятки
	razr4 = razbivka_chisla%10;              // единицы
}



int main(void)
{

	DDRA  |=(1<<PINA0) | (1<<PINA1); // Инициализирую пины порта А на выход (для управления индикаторами, стоит общий анод)
	PORTA |=(1<<PINA0) | (1<<PINA1); // Инициализирую пины порта А на включение (для управления индикаторами, стоит общий анод)
	SEG7_DDR = 0xFF;                 // Инициализирую пины порта С на выход
	SEG7_PORT = 0x00;                // Инициализирую на низкий уровень для того что бы зажечь весь индикатор
	

	
	while(1)
	{

		//chislo(1987);             //ввожу в функцию число
		razr1 = 1987/1000;          //но если сделать руками операцию, то еденичка выводится нормально
		SEG7_PORT = numbers[razr1]; //вывожу первый разряд на индикатор (должна быть единичка, но индикатор отключается)
	}
}

 

Поделиться сообщением


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

On 8/7/2023 at 6:14 AM, Devil Byte said:

Вот так сказать без каши. 

numbers должен быть unsigned char

Вы каким компилятором и какой IDE пользуетесь ?

 

 

On 8/7/2023 at 6:14 AM, Devil Byte said:
int main(void)
{

	DDRA  |=(1<<PINA0) | (1<<PINA1); // Инициализирую пины порта А на выход (для управления индикаторами, стоит общий анод)
	PORTA |=(1<<PINA0) | (1<<PINA1); // Инициализирую пины порта А на включение (для управления индикаторами, стоит общий анод)
  
   .....................
}

В вашем укороченном примере надо оставить только одно включенное знакоместо, сейчас у вас сразу два знакоместа включается

PORTA |=(1<<PINA0);

 

Поделиться сообщением


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

48 минут назад, dimka76 сказал:

numbers должен быть unsigned char

 

Так а какая разница? чар просто имеет меньшую вместительность. Ну попировал ради прикола, ничего не поменялось

 

50 минут назад, dimka76 сказал:

В вашем укороченном примере надо оставить только одно включенное знакоместо, сейчас у вас сразу два знакоместа включается

PORTA |=(1<<PINA0);

Ну это тоже не важно просто он тогда выведет число на все подключенные индикаторы. Но даже если оставлю один, то получаю тот же результат

Поделиться сообщением


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

9 часов назад, dimka76 сказал:

Перебирать не только знакоместа, но и сегменты тоже

Нет, только сегменты, 1:8, по 30 мА на вывод МК.

Поделиться сообщением


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

On 8/7/2023 at 8:52 AM, Devil Byte said:

...

Так каким компилятором вы пользуетесь ?

Я вчера ради любопытства попробовал ваш кода на MPLAB X IDE с компилятором AVR-GCC.

В симуляторе все правильно работает. В порт пишутся верные значения. 

Поделиться сообщением


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

1 час назад, dimka76 сказал:

Так каким компилятором вы пользуетесь ?

Я вчера ради любопытства попробовал ваш кода на MPLAN X IDE с компилятором AVR-GCC.

В симуляторе все правильно работает. В порт пишутся верные значения. 

Я пишу microchip studio,  а вот как компилятор посмотреть даже не знаю, так как еще не изучал вообще эту тему.

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

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

Поделиться сообщением


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

On 8/7/2023 at 10:15 AM, Devil Byte said:

может надо менять уровень оптимизации?

У меня все по умолчанию стояло.

Вы свой проект запустите в симуляцию и пошагайте по программе, одновременно следя за переменными и регистрами порта.

Поделиться сообщением


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

2 часа назад, dimka76 сказал:

У меня все по умолчанию стояло.

Вы свой проект запустите в симуляцию и пошагайте по программе, одновременно следя за переменными и регистрами порта.

В общем, убрал оптимизацию кода на минимум.

Да, razr1 получает значение 1, после того как функция chislo получает на вход 1987.

Может это фьюзы, но я боюсь менять их, а какие по умолчанию не знаю

РАЗРЯД.png

фьюзы.png

Поделиться сообщением


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

On 8/7/2023 at 12:19 PM, Devil Byte said:

Может это фьюзы, но я боюсь менять их, а какие по умолчанию не знаю

WDTON лучше выключить.

Какие по умолчанию описано в документации на микроконтроллер.

On 8/7/2023 at 12:19 PM, Devil Byte said:

Да, razr1 получает значение 1, после того как функция chislo получает на вход 1987.

А вы посмотрели что в итоге оказывается в регистре SEG7_PORT ?

Заодно можно посмотреть не портятся ли при этом регистры 

DDRA, PORTA, SEG7_DDR

Так же можно проверить регистр указатель стека (SP), в нем должно быть значение близкое к вершине ОЗУ.

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

Все это можно сделать в симуляторе.

А не пишите сразу в два знакоместа (оставьте только одно  PORTA |=(1<<PINA0); ) У ножек микроконтроллера тока может не хватить.

Поделиться сообщением


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

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

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

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

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

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

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

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

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