Как прикрутить перебор цифр в часах

Обсуждаем контроллеры компании Atmel.
Ответить
Родился
Сообщения: 16
Зарегистрирован: Пн дек 15, 2008 01:49:43

Сообщение Alikq »

Доброго времени суток, Коты!
На форуме я давно. Пишу, пожалуй, впервые.
Решил сделать часики ГРИ на Atmega16 + BU2090+ DS1307. В программировании не силен- только начинаю. Вот и первый мой стопор, сам пока разобраться не смог. Часы тикают, показывают время. Но нравится мне режим прокрутки цифр при их смене. Все никак не могу его осилить. прошу наставить на путь истинный. Ниже предоставляю мой код. буду очень признателен за совет по теме, да и за критику по поводу моего кода... Заранее всем большое человеческое :)
P.S. обманул, это второй мой пост, первый не помню)

Код: Выделить всё

#define  F_CPU 8000000
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include "TWI.h"
#include "ds1307.h"


#define DAT  0
#define CLK 1
#define POR PORTD
#define pif asm("nop");


struct Time Dio, set;   //структура с переменными для часов
unsigned char counter = 0;


unsigned int num [] =
{0x01,0x200,0x100,0x80,0x40,0x20,0x10,0x08,0x04,0x02}; //массив чисел от 0 до 9
	
unsigned int dat[]= {0x00,0x00,0x00,0x00,0x00,0x00}; //массив динамической индикации

	

	void init_timer (void)
	{
		TIMSK = (1<<TOIE0);                     //прерывание
		TCCR0 = (0<<CS00)|(1<<CS01)|(0<<CS02); // prescaller = /1
		
	}
 
void convert_hours (unsigned int hour)  //раскладываем на десятки-единицы часы и пишем в массив
{
	unsigned int te,r;
	te = hour;
	r = te/10;
	dat[0] = num[r];
	te = te-r*10;
	
	dat[1] = num[te];
	
}


void convert_minutes (unsigned int minute)  //пишем в массив минуты
{
	unsigned int tem,re;
	tem = minute;
	re = tem/10;
	dat[2] = num[re];
	tem = tem-re*10;
	
	dat[3] = num[tem];
	
}

void convert_seconds(unsigned int second)   //пишем в массив секунды
{
	unsigned int temp,res;
	temp = second;
	res = temp/10;
	dat[4] = num[res];
	temp = temp-res*10;
	
	dat[5] = num[temp];
	
}

void send_data (unsigned int data)  //работа с bu2090
{
	for (int i=0; i<12; i++)
	{
		if  ((data&0x800)==0x00)  
		{
		    POR&= ~(1<<CLK);     
		    pif;
			 PORTD|=_BV(DAT);
			
		    pif;
			POR|= 1<<CLK;
			POR&= ~(1<<DAT);
			
			
			data = (data<<1);
		} 
		else
		{
			POR&= ~(1<<CLK);
			pif;
			PORTD&=~_BV(DAT);
			
			pif;
			POR|= 1<<CLK;
			
			
			data = (data<<1);
			
		}
			
	}
	
	POR|= 1<<DAT;           //защелкиваем данные
	pif;
	POR&= ~ (1<<CLK);
	pif;	
}

void presets()      //настраиваем порты, включаем прерывания, включаем часы
{
	DDRB = 0xFF;    //port_b output
	PORTB = 0x00;   //port_b set pins 0
	DDRD = 0xff;    //port_d output
	PORTD = 0x00;   //port_d set pins 0
	_delay_ms(1);
	init_timer();   //init timer
	sei();          //enable interrupt
	I2C_Init();
}

ISR (TIMER0_OVF_vect)  // прерывание сработало
{ 
 
	send_data(dat[counter]);        //грузим в сдвиговый регистр циферки из массива
	PORTB = _BV(counter);           //включаем соотв. лампу
	counter = (counter+1)%6;        // плюсуем счетчик на следующую лампу и цифру из массива
	TCNT0 = 0x00;
	
}

int main(void)
{
	presets(); //настраиваемся на работу
	

 /*//установка времени и даты
set.seconds=40; //секунды
set.minutes=20; //минуты
set.hours=20; //часы
set.day=0; //день недели
set.date=7; //число
set.month=3; //месяц
set.year=14; //год
 
//преобр в удобный вид
ds1307_Conv_for_ds(&set);
//устанавливаем время
ds1307_SetTime(&set);
*/

 while(1)
    { 
		
    ds1307_GetTime( &Dio );  //берем время из часов
    ds1307_Conv_for_me(&Dio); //перевод из двично-десятичной в удобный вид
 
    convert_seconds(Dio.seconds); //записываем в массив секунды
    convert_minutes(Dio.minutes); //пишем в массив минуты
	convert_hours(Dio.hours);     //пишем секунды
	
  }

}
Контактная информация:
Реклама
Друг Кота
Аватара пользователя
Сообщения: 7016
Зарегистрирован: Вс июл 12, 2009 19:15:29
Откуда: Ижевск

Сообщение pyzhman »

режим прокрутки цифр при их смене
Как выглядит?
Docendo discimus
Контактная информация:
Реклама
Родился
Сообщения: 16
Зарегистрирован: Пн дек 15, 2008 01:49:43

Сообщение Alikq »

Например, между сменой цифры с 1 на 2-ку индикатор прокручивает все значения(0-9). У SLvik в "простеньких с 6 режимами индикации" есть такой режим, да и во многих есть.
Контактная информация:
Поставщик валерьянки для Кота
Сообщения: 2222
Зарегистрирован: Вт ноя 27, 2007 11:32:06
Откуда: Tashkent

Сообщение uk8amk »

Примерно так:

Код: Выделить всё

if(d_new != d_old) // эта цифра не равна
{
 for( i=0; i<=9; i++ ) // прокрутить цифру 
 {
  show_dig( i );
 };
 d_old = d_new;
 show_dig( d_new ); // показ новой цифры
}
// повторить тоже самое для остальных цифр
Реклама
Эиком - электронные компоненты и радиодетали
Родился
Сообщения: 16
Зарегистрирован: Пн дек 15, 2008 01:49:43

Сообщение Alikq »

Это вроде понятно. Я только не понимаю куда это вписать.
Создам я массив для сравнения, в какой части мне туда записывать цифры, вытянутые из 1307? И как мне это для всех цифр в обработчик прерываний вписать? И у Вас строчка принудительно ровняет старую цифру с новой, это будет верно?
или у меня код написан так, что осложняет эту задачу. запутался..
Контактная информация:
Реклама
Идёт направо - песнь заводит, Налево - сказку говорит.
Аватара пользователя
Сообщения: 5000
Зарегистрирован: Чт апр 21, 2011 17:55:50
Откуда: Иркутск

Сообщение СКАЗОЧНИК »

А я не понял что за режим прокрутки... Вот сижу и пытаюсь представить, как это. Может видео есть?
Станислав
Реклама
Родился
Сообщения: 16
Зарегистрирован: Пн дек 15, 2008 01:49:43

Сообщение Alikq »

Контактная информация:
Идёт направо - песнь заводит, Налево - сказку говорит.
Аватара пользователя
Сообщения: 5000
Зарегистрирован: Чт апр 21, 2011 17:55:50
Откуда: Иркутск

Сообщение СКАЗОЧНИК »

Спасибо. Но меня не впечатлило.. :dont_know: Точка бегает прикольнее. :)))
Станислав
Родился
Сообщения: 16
Зарегистрирован: Пн дек 15, 2008 01:49:43

Сообщение Alikq »

Да не за что) На вкус и цвет)))
Я вот не перевариваю подсветки в них...
Контактная информация:
Идёт направо - песнь заводит, Налево - сказку говорит.
Аватара пользователя
Сообщения: 5000
Зарегистрирован: Чт апр 21, 2011 17:55:50
Откуда: Иркутск

Сообщение СКАЗОЧНИК »

Я думал там реализовано, как в одометрах или счетчиках кВатт/ч. Когда сверху вниз прокручиваются все цифры. На матричном дисплее можно было бы реализовать. На семисегментных может тоже, но не знаю как будет смотреться. А на вакуумных... Раньше у меня их штук 30 валялось на чердаке, но переехал, все бросил. Потом уже увидел, что на них часы собирают и это модно. :dont_know:
Станислав
Модератор
Аватара пользователя
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля

Сообщение Аlex »

Alikq писал(а):Это вроде понятно. Я только не понимаю куда это вписать.
C трудом представляю себе, как можно не знать свой код. Как же Вы тогда его писали ? :)
Родился
Сообщения: 16
Зарегистрирован: Пн дек 15, 2008 01:49:43

Сообщение Alikq »

Свой код я то знаю. Писал то его я(он постепенно рождался в муках непонимания, зато теперь я знаю что делает каждая строчка)) Я не понимал как именно перебор цифр реализовать. Мне скинули кусок кода с перебором. Я то понимал как перебор считать. Я не мог понять как функцию с перебором правильно составить. Но вроде уже разобрался, позже скину то что у меня получилось.
Контактная информация:
Родился
Сообщения: 16
Зарегистрирован: Пн дек 15, 2008 01:49:43

Сообщение Alikq »

Сделал эффект перебора цифр. Работает, но есть одно но. Единицы секунд прокручивает как положено. А вот начиная с десятков секунд и левее(единицы минут, десятки минут и т.д.) новая цифра показывается с небольшим "торможением". Выглядит так- показало цифру-начинает прокручивать все. Прокручивает до 8-ки(потому что в коде переменная j плюсуется 0 до 8, ), полом небольшая задержка и показывает новую, и так по кругу. Без тормозов показывает только единицы секунд. Наверное, это связано с тем что я пишу Цифры в массив перед функцией прокрутки. Но по другому не работает((Вот код с функцией.

Код: Выделить всё

#define  F_CPU 8000000
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include "TWI.h"
#include "ds1307.h"


#define DAT  0
#define CLK 1
#define POR PORTD
#define pif asm("nop");


struct Time Dio, set;   //структура с переменными для часов
unsigned char counter = 0;
unsigned int hour;
unsigned int minute;
unsigned int second;

unsigned int num [] =
{0x01,0x200,0x100,0x80,0x40,0x20,0x10,0x08,0x04,0x02}; //массив чисел от 0 до 9
	
unsigned int dat[]= {0x00,0x00,0x00,0x00,0x00,0x00}; //массив динамической индикации
unsigned int cmp[]= {0x00,0x00,0x00,0x00,0x00,0x00}; //массив для сравнения для эффектов


	void init_timer (void)
	{
		TIMSK = (1<<TOIE0);                     //прерывание
		TCCR0 = (0<<CS00)|(1<<CS01)|(0<<CS02); // prescaller = /1
		
	}
 
void convert_hours (unsigned int hour)  //раскладываем на десятки-единицы часы и пишем в массив
{
	unsigned int te,r;
	te = hour;
	r = te/10;
	dat[0] = num[r];
	te = te-r*10;
	
	dat[1] = num[te];
	
}

void convert_hours_fl (unsigned int hour)  //раскладываем на десятки-единицы часы и пишем в массив для сравнения
{
	unsigned int te,r;
	te = hour;
	r = te/10;
	cmp[0] = num[r];
	te = te-r*10;
	
	cmp[1] = num[te];
	
}

void convert_minutes (unsigned int minute)  //пишем в массив минуты
{
	unsigned int tem,re;
	tem = minute;
	re = tem/10;
	dat[2] = num[re];
	tem = tem-re*10;
	
	dat[3] = num[tem];
	
}
void convert_minutes_fl (unsigned int minute)  //пишем в массив минуты для срвнения
{
	unsigned int tem,re;
	tem = minute;
	re = tem/10;
	cmp[2] = num[re];
	tem = tem-re*10;
	
	cmp[3] = num[tem];
	
}
void convert_seconds(unsigned int second)   //пишем в массив секунды
{
	unsigned int temp,res;
	temp = second;
	res = temp/10;
	dat[4] = num[res];
	temp = temp-res*10;
	
	dat[5] = num[temp];
	
}


void convert_seconds_fl (unsigned int second) //пишем секунды для сравнения 
  
{
	unsigned int temp,res;
	temp = second;
	res = temp/10;
	cmp[4] = num[res];
	temp = temp-res*10;
	
	cmp[5] = num[temp];
	
}

void sprint (int minute, int hour, int second)
{
	int i, j ;
	 
	for (i=0;i<6;i++)   //в этой функции сравниваем новую и стару цифру 
	{
		if (dat[i]!=cmp[i])  // и если новая не равна старой
		{
			for (j=0;j<9;j++)
			{
				dat[i]=num[j];  //меняем ее на цифру из массива цифр 9 раз
				_delay_ms(3);
			}
	    } 
		
 	}
        convert_seconds_fl(Dio.seconds); //пишем в массив для сравнения
		convert_minutes_fl(Dio.minutes);
		convert_hours_fl(Dio.hours);
	 
	   
}
void send_data (unsigned int data)  //работа с bu2090
{
	for (int i=0; i<12; i++)
	{
		if  ((data&0x800)==0x00)  
		{
		    POR&= ~(1<<CLK);     
		    pif;
			 PORTD|=_BV(DAT);
			
		    pif;
			POR|= 1<<CLK;
			POR&= ~(1<<DAT);
			
			
			data = (data<<1);
		} 
		else
		{
			POR&= ~(1<<CLK);
			pif;
			PORTD&=~_BV(DAT);
			
			pif;
			POR|= 1<<CLK;
			
			
			data = (data<<1);
			
		}
			
	}
	
	POR|= 1<<DAT;           //защелкиваем данные
	pif;
	POR&= ~ (1<<CLK);
	
}

void presets()      //настраиваем порты, включаем прерывания, включаем часы
{
	DDRB = 0xFF;    //port_b output
	PORTB = 0x00;   //port_b set pins 0
	DDRD = 0xff;    //port_d output
	PORTD = 0x00;   //port_d set pins 0
	_delay_ms(1);
	init_timer();   //init timer
	sei();          //enable interrupt
	I2C_Init();
}

ISR (TIMER0_OVF_vect)  // прерывание сработало
{ 
 
	send_data(dat[counter]);        //грузим в сдвиговый регистр циферки из массива
	PORTB = _BV(counter);           //включаем соотв. лампу
	counter = (counter+1)%6;        // плюсуем счетчик на следующую лампу и цифру из массива
	TCNT0 = 0x00;
	
}

int main(void)
{
	presets(); //настраиваемся на работу
	

 /*//установка времени и даты
set.seconds=40; //секунды
set.minutes=20; //минуты
set.hours=20; //часы
set.day=0; //день недели
set.date=7; //число
set.month=3; //месяц
set.year=14; //год
 
//преобр в удобный вид
ds1307_Conv_for_ds(&set);
//устанавливаем время
ds1307_SetTime(&set);
*/

 while(1)
    { 
	
    ds1307_GetTime( &Dio );  //берем время из часов
    ds1307_Conv_for_me(&Dio);	
   
	convert_seconds(Dio.seconds); //записываем в массив секунды
    convert_minutes(Dio.minutes); //пишем в массив минуты
	convert_hours(Dio.hours);
 
    sprint(Dio.seconds,Dio.minutes,Dio.hours); //вызываем функцию прокрутки
	
 
  }

}
Контактная информация:
Ответить

Вернуться в «AVR»