24 февраля 2022 года в 5 утра, без объявления войны, россия напала на Украину.

Они пришли "освобождать народ от нацистов и националистов".
С этого момента наша жизнь изменилась на "до" и "после".
Нас освобождают от наших домов, от наших любимых, от наших родителей и от наших детей....
Тут я не буду никого агитировать или переубеждать, разумный человек найдёт всю информацию
в интернете, а для зомби никакие доводы и факты не послужат аргументом.

Я не умею много писать, да и без мата тут сложно что-то написать.
Поэтому выражу все мои чувства одним фото.

«Спасибо дедушка путин за счастливое детство и мое освобождение». ©

Дополню словами уважаемого человека, широко известного в узких кругах:
тут путин не виноват, не он нажал на кнопку сброса,
- виноват пилот, который нажал на кнопку сброса, мог промахнуться. виноваты жена/мать/брат/друг пилота, которые не позвонили ему, и не сказали "нет войне",
- виноват тот, кто отдал приказ, и виноваты его жена/мать/брат/друг,
- виноват тот, кто цеплял бомбу, потому что он мог её обезвредить, "ну бывает, не сработала",
- виноват кладовщик, виноват водитель, который перевозил эту бомбу. виноваты жена...и т.д., потому что не позвонили и не сказали "нет войне, не вези бомбы",
- виноваты все журналисты оркостана, потому что они врут,
- виноваты недограждане, потому что не сказали журналистам "не врите",
- виноваты все... все 160 миллионов,
- а те 2, 3, 5 тысяч, которые вышли, и которых запаковали, это даже не десятая процента, это погрешность... случайно оказавшиеся в мордоре люди. ©

PS: За несколько часов до вторжения был атакован и взломан крупный интернет хостинг в Киеве, где и размещался мой сайт. Только 16 марта отважным админам удалось частично восстановить работу хостинга. Далеко не все сайты выжили, т.к. были повреждены даже бэкапы.
Нет, нет, я не жалуюсь, нет. В цифровом мире нет ничего ценного, материального...


Due to periodic DDoS attacks, the forum may not be available.

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

Обсуждение проектов, не вошедших в предыдущие категории
Post Reply
Denis_K
Частенько бываю
Posts: 82
Joined: 16 Jun 2017 13:48
Location: Краснодарский край

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

Post by Denis_K »

Пытаюсь написать код для таймера под свои нужды, но никак не выходит с индикацией... Разряды не перебираются по одному, а меняются сразу три цифры...
Например: пишу на вывод число 123, а выводится сначала 1, затем 2 и потом 3 на трех разрядах(111 >> 222 >> 333), все это зациклено. Хотя по задумке :) должно быть 1 в первом разряде, 2 во втором и 3 в третьем с числом на выходе 123. Что я делаю не так?

Добавлено спустя 3 часа 16 минут 17 секунд:
Вот код без скачивания...

Code: Select all


#define F_CPU 8000000L 

#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>

unsigned int i;
unsigned int R1=0, R2=0, R3=0;

void segchar (unsigned int seg)
{
	switch(seg)
	{
		case 1: PORTC = 0b11011111;                                       //PC1
		        PORTB = 0b11110111;
		break;
		case 2: PORTC = 0b11011101;
		        PORTB = 0b11011100;
		break;                                           //PC2                           //PC5
		case 3: PORTC = 0b11011101;
		        PORTB = 0b11010101;
		break;
		case 4: PORTC = 0b11011011;
		        PORTB = 0b11010111;
		break;                                                         //PB5
		case 5: PORTC = 0b11111001;
		        PORTB = 0b11010101;
		break;
		case 6: PORTC = 0b11111001;
		        PORTB = 0b11010100;
		break;                                        //PB0                           //PB3
		case 7: PORTC = 0b11011101;
		        PORTB = 0b11110111;
		break;
		case 8: PORTC = 0b11011001;
		        PORTB = 0b11010100;
		break;                                                      //PB1
		case 9: PORTC = 0b11011001;
		        PORTB = 0b11010101;
		break;
		case 0: PORTC = 0b11011001;
		        PORTB = 0b11110101;
		break;
	}	
}

void timer_ini(void)
{	
	TCCR1B |= (1<<WGM12); 
	TIMSK1 |= (1<<OCIE1A);	
	OCR1AH = 0b00001111; 
	OCR1AL = 0b00001010;
	TCCR1B |= (1<<CS12);
}

unsigned int n_count=0;

ISR (TIMER1_COMPA_vect)
{	
    if(n_count==0) {PORTC|=(1<<PORTC0);PORTC&=~(1<<PORTC3);PORTC&=~(1<<PORTC4);segchar(R1);}		 
	if(n_count==1) {PORTC|=(1<<PORTC3);PORTC&=~(1<<PORTC4);PORTC&=~(1<<PORTC0);segchar(R2);}		 
	if(n_count==2) {PORTC|=(1<<PORTC4);PORTC&=~(1<<PORTC0);PORTC&=~(1<<PORTC3);segchar(R3);}
		
	n_count++;
	if (n_count>2) n_count=0;
}

void ledprint(unsigned int number)
{	
	R1=number/100;          
	R2=(number%100)/10;     
	R3=(number%100)%10; 	
}

int main(void)
{
	unsigned int butcount=0, butstate=0;
	timer_ini();
	DDRD = 0b00010000;
	DDRB = 0b11111111;
	DDRC = 0b11111111;
	PORTD = 0b00100000;
	PORTC = 0b11100110;
	PORTB = 0b11111111;
	i=0;
	sei();
	ledprint(123);
	
	while(1)
	{		
	}
	}
Attachments
main.rar
(935 Bytes) Downloaded 241 times
IYra
Живу тут
Posts: 712
Joined: 01 Feb 2012 18:36
Location: Санкт-Петербург

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

Post by IYra »

Denis_K wrote: Вот код без скачивания...
1. В коде желательно больше комментариев. Особенно там где настраивается таймер.

2. Еще хорошо бы нарисовать модель в Протеусе и пройтись с отладчиком
Denis_K
Частенько бываю
Posts: 82
Joined: 16 Jun 2017 13:48
Location: Краснодарский край

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

Post by Denis_K »

IYra, здравствуйте. Я бы с радостью воспользовался отладчиком, но к сожалению еще не научился им пользоваться :) А модель нарисованная есть...
Вот прокомментировал код:

Code: Select all


#define F_CPU 8000000L 

#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>

unsigned int i;
unsigned int R1=0, R2=0, R3=0;  // переменные разрядов

void segchar (unsigned int seg) // формирование цифры
{
	switch(seg) // сегменты находятся на портС и портВ
	{
		case 1: PORTC = 0b11011111;      //1                                 
		        PORTB = 0b11110111;
		break;
		case 2: PORTC = 0b11011101;      //2
		        PORTB = 0b11011100;
		break;                                           
		case 3: PORTC = 0b11011101;      //3
		        PORTB = 0b11010101;
		break;
		case 4: PORTC = 0b11011011;      //4
		        PORTB = 0b11010111;
		break;                                                         
		case 5: PORTC = 0b11111001;      //5
		        PORTB = 0b11010101;
		break;
		case 6: PORTC = 0b11111001;      //6
		        PORTB = 0b11010100;
		break;                                        
		case 7: PORTC = 0b11011101;      //7
		        PORTB = 0b11110111;
		break;
		case 8: PORTC = 0b11011001;      //8
		        PORTB = 0b11010100;
		break;                                                      
		case 9: PORTC = 0b11011001;      //9
		        PORTB = 0b11010101;
		break;
		case 0: PORTC = 0b11011001;      //0
		        PORTB = 0b11110101;
		break;
	}
}

void timer_ini(void)
{	
	TCCR1B |= (1<<WGM12);   // устанавливаем режим СТС 
	TIMSK1 |= (1<<OCIE1A);  // разрешаем прерывания Т1	
	OCR1AH = 0b00001111;    // число для сравнения
	OCR1AL = 0b01000010;
	TCCR1B |= (1<<CS12);    // устанавливаем делитель
}

unsigned int n_count=0;

ISR (TIMER1_COMPA_vect) // вход в прерывание Т1
{	
    if(n_count==0) {PORTC|=(1<<PORTC0);PORTC&=~(1 <<PORTC3);PORTC&=~(1<<PORTC4);segchar(R1);}	 // включаем первый разряд
	if(n_count==1) {PORTC|=(1<<PORTC3);PORTC&=~(1<<PORTC4);PORTC&=~(1<<PORTC0);segchar(R2);}	 // включаем второй разряд	 
	if(n_count==2) {PORTC|=(1<<PORTC4);PORTC&=~(1<<PORTC0);PORTC&=~(1<<PORTC3);segchar(R3);} // включаем третий разряд
		
	n_count++;
	if (n_count>2) n_count=0; // переключаем разряды 0,1,2
}

void ledprint(unsigned int number)
{	
	R1=number/100;          // сотни
	R2=(number%100)/10;     // десятки
	R3=(number%100)%10; 	   // единицы
}

int main(void)
{
	timer_ini();         // инициализация таймера
	DDRD = 0b00010000;   // установка портов на выход
	DDRB = 0b11111111;
	DDRC = 0b11111111;
	PORTD = 0b00100000;
	PORTC = 0b11100110;
	PORTB = 0b11111111;
	i=0;
	sei();               // разрешение прерываний
	ledprint(123);       // вывод числа 123
	
	while(1)
	 {	
		
       }
	}
IYra
Живу тут
Posts: 712
Joined: 01 Feb 2012 18:36
Location: Санкт-Петербург

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

Post by IYra »

Denis_K wrote: А модель нарисованная есть...
Ну так выкладывай - посмотрим
Denis_K
Частенько бываю
Posts: 82
Joined: 16 Jun 2017 13:48
Location: Краснодарский край

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

Post by Denis_K »

Вот модель

Добавлено спустя 2 часа 14 минут 9 секунд:
Попробовал так:

Code: Select all

ISR (TIMER1_COMPA_vect)
{	
	
	
    if(n_count==0) {PORTC|=(1<<PORTC0);PORTC&=~(1<<PORTC3);PORTC&=~(1<<PORTC4);segchar(ledprint(R1));}		 
	if(n_count==1) {PORTC|=(1<<PORTC3);PORTC&=~(1<<PORTC4);PORTC&=~(1<<PORTC0);segchar(ledprint(R2));}		 
	if(n_count==2) {PORTC|=(1<<PORTC4);PORTC&=~(1<<PORTC0);PORTC&=~(1<<PORTC3);segchar(ledprint(R3));}
		
	n_count++;
	if (n_count>2) n_count=0;
}

Теперь переключаются разряды, но как то раз через два... может тут лучше применить switch? я уже запутался...
Attachments
TOO_48.rar
(55.63 KiB) Downloaded 246 times
IYra
Живу тут
Posts: 712
Joined: 01 Feb 2012 18:36
Location: Санкт-Петербург

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

Post by IYra »

Denis_K wrote:

Code: Select all

ISR (TIMER1_COMPA_vect)
{	
    if(n_count==0) {PORTC|=(1<<PORTC0);PORTC&=~(1<<PORTC3);PORTC&=~(1<<PORTC4);segchar(ledprint(R1));}		 
	if(n_count==1) {PORTC|=(1<<PORTC3);PORTC&=~(1<<PORTC4);PORTC&=~(1<<PORTC0);segchar(ledprint(R2));}		 
	if(n_count==2) {PORTC|=(1<<PORTC4);PORTC&=~(1<<PORTC0);PORTC&=~(1<<PORTC3);segchar(ledprint(R3));}
		
	n_count++;
	if (n_count>2) n_count=0;
}
1. Что-то с таймером. Прерывание срабатывает каждые 130 мс. А должно максимум 10 мс. Надо уменьшать
2. Собери без оптимизации. В файле с расширением elf(отладочный) прочерки
Denis_K
Частенько бываю
Posts: 82
Joined: 16 Jun 2017 13:48
Location: Краснодарский край

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

Post by Denis_K »

1) Делитель в настройке таймера я умышленно увеличил, что бы визуально наблюдать смену разрядов, т.к. таймер уже полностью собранный :) .
При уменьшении времени все три цифры сливаются в "8".
2)Собрал без оптимизации, все тоже самое, только размер вырос с 2кб до 4кб...

Добавлено спустя 28 минут 16 секунд:
Почему-то вот здесь if(n_count==0) {PORTC|=(1<<PORTC0);PORTC&=~(1<<PORTC3);PORTC&=~(1<<PORTC4);segchar(ledprint(R1));} не тухнут РС3 и РС4... все три разряда постоянно включены.

Добавлено спустя 14 часов 22 минуты 17 секунд:
Выяснилось, что при использовании одного портВ для вывода цифр - все работает, только комбинирую с портС, то разряды не переключаются...
Применил маску для портС:

Code: Select all

switch(seg)
	{
		case 1: PORTC ^= 0b00100000;                                       
		           PORTB = 0b11110111;
		break;
		case 2: PORTC ^= 0b00100010;
		           PORTB = 0b11011100;
		break;                                                                    
		case 3: PORTC ^= 0b00100010;
		           PORTB = 0b11010101;
		break;
		case 4: PORTC ^= 0b00100100;
		           PORTB = 0b11010111;
		break;                                                        
		case 5: PORTC ^= 0b00000110;
		           PORTB = 0b11010101;
		break;
		case 6: PORTC ^= 0b00000110;
		           PORTB = 0b11010100;
		break;                                                                   
		case 7: PORTC ^= 0b00100010;
		           PORTB = 0b11110111;
		break;
		case 8: PORTC ^= 0b00100110;
		           PORTB = 0b11010100;
		break;                                                      
		case 9: PORTC ^= 0b00100110;
		           PORTB = 0b11010101;
		break;
		case 0: PORTC ^= 0b00100110;
		           PORTB = 0b11110101;
		break;
	}
но теперь не правильно загораются сегменты... :(
IYra
Живу тут
Posts: 712
Joined: 01 Feb 2012 18:36
Location: Санкт-Петербург

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

Post by IYra »

Denis_K wrote: Почему-то вот здесь if(n_count==0) {PORTC|=(1<<PORTC0);PORTC&=~(1<<PORTC3);PORTC&=~(1<<PORTC4);segchar(ledprint(R1));} не тухнут РС3 и РС4... все три разряда постоянно включены.
Функция segchar() устанавливает все в 1
case 1: PORTC = 0b11011111; //1
PORTB = 0b11110111;
поэтому 0 нужно устанавливать побитово
PORTC&=~(1<<PORTC5);
Denis_K
Частенько бываю
Posts: 82
Joined: 16 Jun 2017 13:48
Location: Краснодарский край

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

Post by Denis_K »

Спасибо, IYra. Я поздно до этого дошел :) ...
Сделал так:

Code: Select all

switch(seg)
	{
		case 1: PORTC&=~(1<<PORTC5);                                       
		        PORTB&=~(1<<PORTB3);
		break;
		case 2: PORTC&=~(1<<PORTC1);
		        PORTC&=~(1<<PORTC5);
				PORTB&=~(1<<PORTB0);
				PORTB&=~(1<<PORTB1);
		        PORTB&=~(1<<PORTB5);
		break;                                                                    
		case 3: PORTC&=~(1<<PORTC1);
		        PORTC&=~(1<<PORTC5);
				PORTB&=~(1<<PORTB1);
				PORTB&=~(1<<PORTB3);
				PORTB&=~(1<<PORTB5);
		break;
		case 4: PORTC&=~(1<<PORTC2);
		        PORTC&=~(1<<PORTC5);
		        PORTB&=~(1<<PORTB3);
		        PORTB&=~(1<<PORTB5);
		break;                                                        
		case 5: PORTC&=~(1<<PORTC1);
		        PORTC&=~(1<<PORTC2);
		        PORTB&=~(1<<PORTB1);
		        PORTB&=~(1<<PORTB3);
		        PORTB&=~(1<<PORTB5);
		break;
		case 6: PORTC&=~(1<<PORTC1);
		        PORTC&=~(1<<PORTC2);
		        PORTB&=~(1<<PORTB0);
		        PORTB&=~(1<<PORTB1);
		        PORTB&=~(1<<PORTB3);
				PORTB&=~(1<<PORTB5);
		break;                                                           
		case 7: PORTC&=~(1<<PORTC1);
		        PORTC&=~(1<<PORTC5);
		        PORTB&=~(1<<PORTB3);
		break;
		case 8: PORTC&=~(1<<PORTC1); 
		        PORTC&=~(1<<PORTC2); 
		        PORTC&=~(1<<PORTC5);
		        PORTB&=~(1<<PORTB0);
		        PORTB&=~(1<<PORTB1);
		        PORTB&=~(1<<PORTB3);
		        PORTB&=~(1<<PORTB5);
		break;                                                    
		case 9: PORTC&=~(1<<PORTC1);
		        PORTC&=~(1<<PORTC2);
		        PORTC&=~(1<<PORTC5);
		        PORTB&=~(1<<PORTB1);
		        PORTB&=~(1<<PORTB3);
		        PORTB&=~(1<<PORTB5);
		break;
		case 0: PORTC&=~(1<<PORTC1);
		        PORTC&=~(1<<PORTC2);
		        PORTC&=~(1<<PORTC5);
		        PORTB&=~(1<<PORTB0);
		        PORTB&=~(1<<PORTB1);
		        PORTB&=~(1<<PORTB3);
		break;
	}
Но теперь если в ledprint(111) или ledprint(555) и т.д., то индикация работает нормально, а если ledprint(123), то первую цифру выводит, а последующие - каша из сегментов...

Добавлено спустя 46 минут 32 секунды:
Файл .elf
Attachments
TOOmega48_2.rar
(3.93 KiB) Downloaded 239 times
IYra
Живу тут
Posts: 712
Joined: 01 Feb 2012 18:36
Location: Санкт-Петербург

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

Post by IYra »

Denis_K wrote: Но теперь если в ledprint(111) или ledprint(555) и т.д., то индикация работает нормально, а если ledprint(123), то первую цифру выводит, а последующие - каша из сегментов...
Перед тем как устанавливать сегменты их нужно все очистить(то есть установить еденичку)
PORTC|=(1<<PORTC1);
PORTB|=(1<<PORTB3); и т.д.

И для отладки нужен main.c и .elf
Denis_K
Частенько бываю
Posts: 82
Joined: 16 Jun 2017 13:48
Location: Краснодарский край

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

Post by Denis_K »

Добавлено спустя 5 минут 3 секунды:
Вот настройки портов:

Code: Select all

DDRD = 0b00010000;
	DDRB = 0b111111;
	DDRC = 0b1111111;
	PORTD = 0b00100000;
	PORTC = 0b1111111;
	PORTB = 0b111111;
Вроде бы все соответствует... на разрядах не стал выставлять "0" из- за обратного напряжения на сегментах...
Attachments
TOO.rar
(4.75 KiB) Downloaded 237 times
IYra
Живу тут
Posts: 712
Joined: 01 Feb 2012 18:36
Location: Санкт-Петербург

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

Post by IYra »

IYra wrote:
Denis_K wrote: Но теперь если в ledprint(111) или ledprint(555) и т.д., то индикация работает нормально, а если ledprint(123), то первую цифру выводит, а последующие - каша из сегментов...
Перед тем как устанавливать сегменты их нужно все очистить(то есть установить еденичку)
PORTC|=(1<<PORTC1);
PORTB|=(1<<PORTB3); и т.д.
Не точно выразился. Каждый раз !!!
То есть в начале функции segchar() надо чистить все сегменты
PORTC|=(1<<PORTC1);
PORTB|=(1<<PORTB3); и т.д.
а уж потом рисовать новое.
Или для каждой цифры чистить только свое (так будет быстрее выполняться)
Denis_K
Частенько бываю
Posts: 82
Joined: 16 Jun 2017 13:48
Location: Краснодарский край

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

Post by Denis_K »

IYra, спасибо! Получилось!
Написал так:

Code: Select all

switch(seg)
	{
		case 1: PORTC&=~(1<<PORTC5);                                       
		        PORTB&=~(1<<PORTB3);
			
				PORTC|=(1<<PORTC1);
				PORTC|=(1<<PORTC2);
				PORTB|=(1<<PORTB5);
				PORTB|=(1<<PORTB0);
				PORTB|=(1<<PORTB1);
				PORTB|=(1<<PORTB2);
				
				
		break;
		case 2: PORTC&=~(1<<PORTC1);
		        PORTC&=~(1<<PORTC5);
				PORTB&=~(1<<PORTB0);
				PORTB&=~(1<<PORTB1);
		        PORTB&=~(1<<PORTB5);
				
				PORTC|=(1<<PORTC2);
				PORTB|=(1<<PORTB3);
				
		break;                                                                    
		case 3: PORTC&=~(1<<PORTC1);
		        PORTC&=~(1<<PORTC5);
				PORTB&=~(1<<PORTB1);
				PORTB&=~(1<<PORTB3);
				PORTB&=~(1<<PORTB5);
				
				PORTC|=(1<<PORTC2);
				PORTB|=(1<<PORTB0);
				
		break;
		case 4: PORTC&=~(1<<PORTC2);
		        PORTC&=~(1<<PORTC5);
		        PORTB&=~(1<<PORTB3);
		        PORTB&=~(1<<PORTB5);
				
				PORTC|=(1<<PORTC1);
				PORTB|=(1<<PORTB0);
				PORTB|=(1<<PORTB1);
				
		break;                                                        
		case 5: PORTC&=~(1<<PORTC1);
		        PORTC&=~(1<<PORTC2);
		        PORTB&=~(1<<PORTB1);
		        PORTB&=~(1<<PORTB3);
		        PORTB&=~(1<<PORTB5);
				
				PORTC|=(1<<PORTC5);
				PORTB|=(1<<PORTB0);
				
		break;
		case 6: PORTC&=~(1<<PORTC1);
		        PORTC&=~(1<<PORTC2);
		        PORTB&=~(1<<PORTB0);
		        PORTB&=~(1<<PORTB1);
		        PORTB&=~(1<<PORTB3);
				PORTB&=~(1<<PORTB5);
				
				PORTC|=(1<<PORTC5);
				
		break;                                                           
		case 7: PORTC&=~(1<<PORTC1);
		        PORTC&=~(1<<PORTC5);
		        PORTB&=~(1<<PORTB3);
				
				PORTC|=(1<<PORTC2);
				PORTB|=(1<<PORTB5);
				PORTB|=(1<<PORTB2);
				PORTB|=(1<<PORTB0);
				PORTB|=(1<<PORTB1);
				
		break;
		case 8: PORTC&=~(1<<PORTC1); 
		        PORTC&=~(1<<PORTC2); 
		        PORTC&=~(1<<PORTC5);
		        PORTB&=~(1<<PORTB0);
		        PORTB&=~(1<<PORTB1);
		        PORTB&=~(1<<PORTB3);
		        PORTB&=~(1<<PORTB5);
				
		break;                                                    
		case 9: PORTC&=~(1<<PORTC1);
		        PORTC&=~(1<<PORTC2);
		        PORTC&=~(1<<PORTC5);
		        PORTB&=~(1<<PORTB1);
		        PORTB&=~(1<<PORTB3);
		        PORTB&=~(1<<PORTB5);

				PORTB|=(1<<PORTB0);
				
		break;
		case 0: PORTC&=~(1<<PORTC1);
		        PORTC&=~(1<<PORTC2);
		        PORTC&=~(1<<PORTC5);
		        PORTB&=~(1<<PORTB0);
		        PORTB&=~(1<<PORTB1);
		        PORTB&=~(1<<PORTB3);
				
				PORTB|=(1<<PORTB5);

		break;
	}
Denis_K
Частенько бываю
Posts: 82
Joined: 16 Jun 2017 13:48
Location: Краснодарский край

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

Post by Denis_K »

Дошел до такого кода

Code: Select all

#define F_CPU 8000000L

#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>

unsigned char R1=0, R2=0, R3=0;
unsigned int number = 0;
char dr = 0;
volatile unsigned char napravlenie;
char dubllpush = 0;
unsigned int min = 0;
unsigned char sec = 0;
unsigned char n_count=0;

void segchar (unsigned int seg)    //цифры для индикации
{
	switch(seg)
	{
		case 0:
		PORTC&=~(1<<PORTC1);
		PORTC&=~(1<<PORTC2);
		PORTC&=~(1<<PORTC5);
		PORTB&=~(1<<PORTB0);
		PORTB&=~(1<<PORTB1);
		PORTB&=~(1<<PORTB3);
		
		PORTB|=(1<<PORTB5);
		break;
		
		case 1:
		PORTC&=~(1<<PORTC5);
		PORTB&=~(1<<PORTB3);
		
		PORTC|=(1<<PORTC1);
		PORTC|=(1<<PORTC2);
		PORTB|=(1<<PORTB5);
		PORTB|=(1<<PORTB0);
		PORTB|=(1<<PORTB1);
		PORTB|=(1<<PORTB2);
		break;
		
		case 2:
		PORTC&=~(1<<PORTC1);
		PORTC&=~(1<<PORTC5);
		PORTB&=~(1<<PORTB0);
		PORTB&=~(1<<PORTB1);
		PORTB&=~(1<<PORTB5);
		
		PORTC|=(1<<PORTC2);
		PORTB|=(1<<PORTB3);
		break;
		
		case 3:
		PORTC&=~(1<<PORTC1);
		PORTC&=~(1<<PORTC5);
		PORTB&=~(1<<PORTB1);
		PORTB&=~(1<<PORTB3);
		PORTB&=~(1<<PORTB5);
		
		PORTC|=(1<<PORTC2);
		PORTB|=(1<<PORTB0);
		break;
		
		case 4:
		PORTC&=~(1<<PORTC2);
		PORTC&=~(1<<PORTC5);
		PORTB&=~(1<<PORTB3);
		PORTB&=~(1<<PORTB5);
		
		PORTC|=(1<<PORTC1);
		PORTB|=(1<<PORTB0);
		PORTB|=(1<<PORTB1);
		break;
		
		case 5:
		PORTC&=~(1<<PORTC1);
		PORTC&=~(1<<PORTC2);
		PORTB&=~(1<<PORTB1);
		PORTB&=~(1<<PORTB3);
		PORTB&=~(1<<PORTB5);
		
		PORTC|=(1<<PORTC5);
		PORTB|=(1<<PORTB0);
		break;
		
		case 6:
		PORTC&=~(1<<PORTC1);
		PORTC&=~(1<<PORTC2);
		PORTB&=~(1<<PORTB0);
		PORTB&=~(1<<PORTB1);
		PORTB&=~(1<<PORTB3);
		PORTB&=~(1<<PORTB5);
		
		PORTC|=(1<<PORTC5);
		break;
		
		case 7:
		PORTC&=~(1<<PORTC1);
		PORTC&=~(1<<PORTC5);
		PORTB&=~(1<<PORTB3);
		
		PORTC|=(1<<PORTC2);
		PORTB|=(1<<PORTB5);
		PORTB|=(1<<PORTB2);
		PORTB|=(1<<PORTB0);
		PORTB|=(1<<PORTB1);
		break;
		
		case 8:
		PORTC&=~(1<<PORTC1);
		PORTC&=~(1<<PORTC2);
		PORTC&=~(1<<PORTC5);
		PORTB&=~(1<<PORTB0);
		PORTB&=~(1<<PORTB1);
		PORTB&=~(1<<PORTB3);
		PORTB&=~(1<<PORTB5);
		break;
		
		case 9:
		PORTC&=~(1<<PORTC1);
		PORTC&=~(1<<PORTC2);
		PORTC&=~(1<<PORTC5);
		PORTB&=~(1<<PORTB1);
		PORTB&=~(1<<PORTB3);
		PORTB&=~(1<<PORTB5);

		PORTB|=(1<<PORTB0);
		break;
		
		case 10:
		PORTC&=~(1<<PORTC5);
		PORTB|=(1<<PORTB3);
		PORTC|=(1<<PORTC1);
		PORTC|=(1<<PORTC2);
		PORTB|=(1<<PORTB5);
		PORTB|=(1<<PORTB0);
		PORTB|=(1<<PORTB1);
		PORTB|=(1<<PORTB2);

		break;
		case 11:
		PORTC|=(1<<PORTC5);
		PORTB|=(1<<PORTB3);
		PORTC|=(1<<PORTC1);
		PORTC|=(1<<PORTC2);
		PORTB|=(1<<PORTB5);
		PORTB|=(1<<PORTB0);
		PORTB|=(1<<PORTB1);
		PORTB|=(1<<PORTB2);
	}
}

void off()                         //выключение сегментов
{
	PORTB|=(1<<PORTB5);  //off
	PORTC|=(1<<PORTC5);
	PORTC|=(1<<PORTC1);
	PORTC|=(1<<PORTC2);
	PORTB|=(1<<PORTB3);
	PORTB|=(1<<PORTB0);
	PORTB|=(1<<PORTB1);
	PORTB|=(1<<PORTB2);
}

void TTT()                         //функция для установки прочерков
{
	PORTB&=~(1<<PORTB5);  //-
	PORTC|=(1<<PORTC5);
	PORTC|=(1<<PORTC1);
	PORTC|=(1<<PORTC2);
	PORTB|=(1<<PORTB3);
	PORTB|=(1<<PORTB0);
	PORTB|=(1<<PORTB1);
	PORTB|=(1<<PORTB2);
}

void init_timer_led(void)          //настройка таймера для динамической индикации
{
	TCCR1B |= (1<<WGM12);
	TIMSK1 |= (1<<OCIE1A);
	OCR1AH = 0b00001101;
	OCR1AL = 0b01001100;
	TCCR1B |= (1<<CS11);
}

void init_timer_encoder(void)      //настройка таймера для обработки задержки энкодера
{
	TCCR0B |= (1<<WGM02);
	TIMSK0 |= (1<<OCIE0A);
	OCR0A = 4;
	TCCR0B |= (1<<CS01)|(1<<CS00);
}

void init_timer_OO(void)           //настройка таймера для обратного отсчета и включение асинхронного режима
{
	ASSR |= (1 << AS2);
	TCNT2 = 0;
	TCCR2B |= (1 << CS22)|(1 << CS20);
	OCR2A = 255;
	TIMSK2 |=(1 << OCIE2A);
	TIFR2 = 0;
}

void init_ADC()                    //настройка АЦП для контроля напряжения на АКБ
{
	ADCSRA |= (1<<ADEN)|(1<<ADATE)|(1<<ADIF)|(1<<ADPS1)|(1<<ADPS2);
	ADMUX  |= /*(1<<REFS1)|*/(1<<REFS0)|(0<<ADLAR)|(1<<MUX1)|(1<<MUX2);
	ADCSRA |= (1<<ADSC);
}

void init_port()                   //настройка портов ввода-вывода
{
	DDRD = 0b00010111;
	DDRB = 0b111111;
	DDRC = 0b1111111;
	PORTD = 0b11100000;
	PORTC = 0b1111111;
	PORTB = 0b111111;
}

void enkoder()                     //обработка вращения энкодера
{
	if ( napravlenie & (1<<0)) //определяем было или нет зафексировано направление
	{
		if (PIND & (1<<6)){}
		else
		{
			if (PIND & (1<<7)){}
			else
			napravlenie = 0;
		}
	}
	else
	{
		
		//проверка на правое вращение
		
		if (PIND & (1<<6)) {}        //проверка порта на 0
		else
		{
			if (PIND & (1<<7))      //проверка порта на 1
			{
				napravlenie |=(1<<0);
				if (min < 999)	  //проверка на больше
				{
					min++;
					return;
				}
			}
		}
		
		//проверка на левое вращение
		
		if (PIND & (1<<7)) {}         //проверка порта на 0
		else
		{
			if (PIND & (1<<6))       //проверка порта на 1
			{
				napravlenie |=(1<<0);
				if (min > 0)          //проверка на менше 1
				min--;
			}
		}
	}
}

void ledprint(number)              //вывод значения на индикатор
{
	asm("cli");
	R1=number/100;                 //разбивка по разрядам
	R2=(number%100)/10;
	R3=(number%100)%10;
	
	PORTD&=~(1<<PORTD4);           //выключение зумера
	
	if(number<100) {R1=11;}        //гашение первых разрядов при 0
	if(number<10) {R2=11;}
	if(number==0) {PORTD|=(1<<PORTD4);} //включение зумера при 0 минут
	asm("sei");
}

ISR(TIMER2_COMPA_vect)                          //прерывание по ASSR (здесь отсчет минут и "пип" зумера раз в секунду)
{
	if(dr > 2)
	{
		if(min>0)
		{
			sec++;
			PORTD|=(1<<PORTD4);
		}
		if(sec>59) sec=0, min--;
	}
}

ISR (TIMER1_COMPA_vect)                         //динамическая индикация (меняем разряд с нужной цифрой)
{
	if(n_count==0) {
		PORTC|=(1<<PORTC0);
		PORTC&=~(1<<PORTC3);
		PORTC&=~(1<<PORTC4);
	segchar(R1);}
	if(n_count==1) {
		PORTC|=(1<<PORTC3);
		PORTC&=~(1<<PORTC4);
		PORTC&=~(1<<PORTC0);
	segchar(R2);}
	if(n_count==2) {
		PORTC|=(1<<PORTC4);
		PORTC&=~(1<<PORTC0);
		PORTC&=~(1<<PORTC3);
	segchar(R3);}
	
	n_count ++;
	if (n_count>2) n_count=0;
}

ISR (TIMER0_COMPA_vect)                         //обработка энкодера без PD5 (PD5 - центральная кнопка энкодера)
{
	enkoder();
}

int main(void)
{
	/* инициализация всего :) */
	init_port();
	asm("cli");
	init_ADC();
	init_timer_OO();
	init_timer_led();
	init_timer_encoder();
	
	/* мигаем черточками )) */
	off();
	_delay_ms(500);
	TTT();
	_delay_ms(500);
	off();
	_delay_ms(500);
	TTT();
	_delay_ms(500);
	off();
	_delay_ms(500);
	
	sei();
	
	while(1)
	{
		for(char n = 0; n < 5; n++)        //обработка кнопки PD5
		{
			if((PIND&(1 << PD5)) == 0)
			dr++;
		}
		
		ledprint(min);                     //выводим минуты для отсчета
		
		if (ADC>670)                       //показатель заряда АКБ
		{
			PORTD|=(1<<PORTD1); //зеленый
			//PORTD&=~(1<<PORTD0);
			PORTD&=~(1<<PORTD2);
		}
		else
		{
			PORTD|=(1<<PORTD2); //красный
			PORTD&=~(1<<PORTD1);
			//PORTD&=~(1<<PORTD0);
		}
	}
}
и опять я в ступоре :-) ...
Во-первых первый разряд еле заметно подсвечивается цифрой третьего разряда - не знаю как такое возможно...
Во-вторых когда if (min < 999) или if (min > 0) - нет возможности при min-- уходить от нуля к 999, 998 и т.д. пишу так - if (min <= 999) или if (min >= 0), но теперь от нуля значения уходят в никуда, т.е. индикации тупо нет... как тогда нужно зациклить установку минут не только от 0 к 999 в плюс(0,1,2,3 и т.д.), но и от 0 к 999 в минус(0,999,998,997 и т.д.)?

Добавлено спустя 2 минуты 28 секунд:
Вот архив со всей требухой...
Attachments
TOO.rar
(58.17 KiB) Downloaded 237 times
IYra
Живу тут
Posts: 712
Joined: 01 Feb 2012 18:36
Location: Санкт-Петербург

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

Post by IYra »

Denis_K wrote:Дошел до такого кода и опять я в ступоре :-) ...
Во-первых первый разряд еле заметно подсвечивается цифрой третьего разряда - не знаю как такое возможно...
Важен порядок.
1. Гасим все разряды
2. Рисуем цифру
3. Зажигаем нужный разряд

Code: Select all

ISR (TIMER1_COMPA_vect)                         //динамическая индикация (меняем разряд с нужной цифрой)
{
	PORTC&=~(1<<PORTC0);PORTC&=~(1<<PORTC3);PORTC&=~(1<<PORTC4);     // Гасим
	if(n_count==0) {
		segchar(R1);  // Рисуем
		PORTC|=(1<<PORTC0);  // Зажигаем
		
	}
	if(n_count==1) {
		segchar(R2);
		PORTC|=(1<<PORTC3);
		}
	if(n_count==2) {
		segchar(R3);
		PORTC|=(1<<PORTC4);
		}
	
	n_count ++;
	if (n_count>2) n_count=0;
}

И еще в Протеусе в свойствах МК надо установить CLKDIV8 -> (1) Unprogrammed
чтобы не было деления частоты на 8
Denis_K
Частенько бываю
Posts: 82
Joined: 16 Jun 2017 13:48
Location: Краснодарский край

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

Post by Denis_K »

IYra, как всегда спасибо за наставление!
С индикацией теперь понятно... а вот как сделать при вращении энкодера min-- от 0 к 999?
В протеусе так делал для какой-то цели - уже не помню... старею :-) , но моделирую постоянно прошиваясь на реальной плате.
IYra
Живу тут
Posts: 712
Joined: 01 Feb 2012 18:36
Location: Санкт-Петербург

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

Post by IYra »

Denis_K wrote:а вот как сделать при вращении энкодера min-- от 0 к 999?
Надо наверно так

Code: Select all

  if (min < 999)     //проверка на больше
  {
               min++;
               return;
    }
   else min = 0 ;
так как min это unsigned int min = 0;
и меньше нуля быть не может и если от 0 отнять 1 сразу перескакивает на 64т чего то там
Denis_K
Частенько бываю
Posts: 82
Joined: 16 Jun 2017 13:48
Location: Краснодарский край

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

Post by Denis_K »

IYra, спасибо. Понял, исправил, все работает...
Post Reply