Часы на DS1307 (подправка кода)

Обсуждаем контроллеры компании Atmel.
Ответить
belov.alex1995
Встал на лапы
Сообщения: 91
Зарегистрирован: Сб ноя 30, 2013 01:57:26

Часы на DS1307 (подправка кода)

Сообщение belov.alex1995 »

В общем такое дело, собрал я часы по схеме http://radiokot.ru/forum/viewtopic.php? ... &start=584 схемка простая, часы идут вроде бы точно, но такая проблема, прошивка написана под часовой индикатор с 2-мя точками по середине, а у меня обычный индикатор с общим анодом (часовой с 2-мя точками не нашел в продаже) и по этому мигают 2 крайние точки, а это не очень красиво :( И еще в схеме опрос DS-ки с интервалом приблизительно 2 сек и по этому минуты на индикаторе переключаются с опоздание 1-2 сек :(

Есть исходник прошивки на C.
Кто-нибудь может подкорректировать прошивку?
1. Изменить опрос DS-ки на 200-500 миллисекунд (что бы не было заметно опоздание при переключении секунд, если это возможно).
2. Сделать мигающей 1 точку во втором разряде индикатора.

Собрать схемку я могу, а вот в программировании не силен, если кому-то не составит труда подкорректировать прошивку и компилировать в hex, буду очень благодарен (сам пробовал, даже откомпилировал в hex, но у меня после этого на индикаторе вообще ничего не появилось).

#include <tiny2313.h>
#include <delay.h>
#include <stdio.h>
#include <string.h>

// I2C Bus functions
#asm
.equ __i2c_port=0x1B ;PORTA
.equ __sda_bit=0
.equ __scl_bit=1
#endasm
#include <i2c.h>

// DS1307 Real Time Clock functions
#include <ds1307.h>

// Declare your global variables here
//#define cathode
#define anode
#define segment_1 PORTB.4
#define segment_2 PORTB.3
#define segment_3 PORTB.2
#define segment_4 PORTB.0
#define dp PORTB.1
#define led_delay 250
#define timer_delay 500
#define plus_h PINB.5 //кнопка +
#define plus_m PINB.6 //кнопка -
#define led_status PORTB.7
char display[4];
int timer, show_dp, dp_timer;
unsigned char hour,min,sec,test_sec;

void formating_time(void)
{
display[0] = hour / 10; //!
display[1] = hour % 10; //!
display[2] = min / 10; //!
display[3] = min % 10; //!
}

void show_chars(void)
{
char characters[13] =
{
0x3F, //0
0x06, //1
0x5B, //2
0x4F, //3
0x66, //4
0x6D, //5
0x7D, //6
0x07, //7
0xFF, //8
0x6F, //9
0x73, //P
0x40, //-
0x49 // |||
};
#ifdef cathode
PORTD = characters[display[0]];
segment_1 = 0;
delay_us(led_delay);
segment_1 = 1;


PORTD = characters[display[1]];
segment_2 = 0;
delay_us(led_delay);
segment_2 = 1;

PORTD = characters[display[2]];
dp = show_dp;
segment_3 = 0;
delay_us(led_delay);
segment_3 = 1;


PORTD = characters[display[3]];
segment_4 = 0;
delay_us(led_delay);
segment_4 = 1;
dp = 0;
#endif



#ifdef anode
PORTD = ~characters[display[0]];
segment_1 = 1;
delay_us(led_delay);
segment_1 = 0;


PORTD = ~characters[display[1]];
segment_2 = 1;
delay_us(led_delay);
segment_2 = 0;

PORTD = ~characters[display[2]];
dp = show_dp;
segment_3 = 1;
delay_us(led_delay);
segment_3 = 0;


PORTD = ~characters[display[3]];
segment_4 = 1;
delay_us(led_delay);
segment_4 = 0;
dp = 1;
#endif
}

void read_time(void)
{
rtc_get_time(&hour,&min,&sec);
timer = 0;
if ((min == 0) && (sec < 30)) led_status = 1; else led_status = 0;
// if (min == 0) led_status = 1; else led_status = 0;
}

void coorect_time(void)
{
if (plus_h == 0)
{hour++;
if (hour > 23) hour = 0;
rtc_set_time(hour,min,30);
}
if (plus_m == 0)
{min++;
if (min > 59) min = 0;
rtc_set_time(hour,min,30);
}
}

void dp_timer_show(void)
{
show_dp = ~show_dp;
dp_timer = 0;
}

void start_program(void)
{
led_status = 1;
plus_h = 1;
plus_m = 1;
rtc_get_time(&hour,&min,&sec);

#ifdef anode
dp = 1;
PORTD = ~0x40;
segment_1 = 1;
segment_2 = 0;
segment_3 = 0;
segment_4 = 0;

delay_ms(1000);
segment_2 = 1;
delay_ms(1000);
segment_3 = 1;
delay_ms(1000);
segment_4 = 1;
#endif

#ifdef cathode
dp = 0;
PORTD = 0x40;
segment_1 = 0;
segment_2 = 1;
segment_3 = 1;
segment_4 = 1;

delay_ms(1000);
segment_2 = 0;
delay_ms(1000);
segment_3 = 0;
delay_ms(1000);
segment_4 = 0;
#endif

delay_ms(1000);
rtc_get_time(&hour,&min,&test_sec);
if (sec == test_sec) {hour = 16; min = 23; sec = 0; rtc_set_time(hour,min,sec); rtc_set_date(1, 1, 11);}
led_status = 0;
}

void main(void)
{
// Declare your local variables here

// Crystal Oscillator division factor: 1
#pragma optsize-
CLKPR=0x80;
CLKPR=0x00;
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif

// Input/Output Ports initialization
// Port A initialization
// Func2=In Func1=In Func0=In
// State2=T State1=T State0=T
PORTA=0x00;
DDRA=0x00;

// Port B initialization
// Func7=Out Func6=In Func5=In Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out
// State7=0 State6=T State5=T State4=0 State3=0 State2=0 State1=0 State0=0
PORTB=0x00;
DDRB=0x9F;

// Port D initialization
// Func6=Out Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out
// State6=0 State5=0 State4=0 State3=0 State2=0 State1=0 State0=0
PORTD=0x00;
DDRD=0x7F;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
// Mode: Normal top=FFh
// OC0A output: Disconnected
// OC0B output: Disconnected
TCCR0A=0x00;
TCCR0B=0x00;
TCNT0=0x00;
OCR0A=0x00;
OCR0B=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer1 Stopped
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
// Interrupt on any change on pins PCINT0-7: Off
GIMSK=0x00;
MCUCR=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x00;

// Universal Serial Interface initialization
// Mode: Disabled
// Clock source: Register & Counter=no clk.
// USI Counter Overflow Interrupt: Off
USICR=0x00;

// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;

// I2C Bus initialization
i2c_init();

// DS1307 Real Time Clock initialization
// Square wave output on pin SQW/OUT: On
// Square wave frequency: 1Hz
rtc_init(0,1,0);

start_program();

while (1)
{
// Place your code here
delay_us(timer_delay);

timer++;
if (timer >= 2000) read_time();

dp_timer++;
if (dp_timer >= 500) {dp_timer_show(); coorect_time();}

formating_time();
show_chars();
};
}

Вряд ли кто нибудь с этим будет возится, но все же попытаю удачу :))
Вложения
main.c
Исходник на C
(6.29 КБ) 168 скачиваний
Реклама
vAv
Прорезались зубы
Сообщения: 221
Зарегистрирован: Пн июн 13, 2011 20:04:59
Откуда: Новочебоксарск
Контактная информация:

Re: Часы на DS1307 (подправка кода)

Сообщение vAv »

Для более частого опроса измени 2000 на 1000 или 500:
if (timer >= 2000) read_time();

И вот отсюда

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

PORTD = ~characters[display[2]];
dp = show_dp;
строчку dp = show_dp; удали и перенеси ее сюда

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

PORTD = ~characters[display[3]];
dp = show_dp;
segment_4 = 1;
Будет моргать только последняя точка.
Чтобы моргала между второй и третьей цифрой, то надо сделать так:

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

PORTD = ~characters[display[1]];
segment_4 = 1;
delay_us(led_delay);
segment_4 = 0; 
dp = 1;
И удалить так же отсюда dp = show_dp;

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

PORTD = ~characters[display[3]];
dp = show_dp;
segment_4 = 1;
Реклама
belov.alex1995
Встал на лапы
Сообщения: 91
Зарегистрирован: Сб ноя 30, 2013 01:57:26

Re: Часы на DS1307 (подправка кода)

Сообщение belov.alex1995 »

Спасибо, сейчас попробую.
Аватара пользователя
Serhz
Родился
Сообщения: 16
Зарегистрирован: Сб фев 16, 2013 00:30:28
Откуда: Украина

Re: Часы на DS1307 (подправка кода)

Сообщение Serhz »

На 45 странице по Вашей ссылке есть прошивка с точкой после 2 разряда, как ОК так и ОА.
Мы увидимся в другой жизни. Когда станем котами.
Реклама
Эиком - электронные компоненты и радиодетали
belov.alex1995
Встал на лапы
Сообщения: 91
Зарегистрирован: Сб ноя 30, 2013 01:57:26

Re: Часы на DS1307 (подправка кода)

Сообщение belov.alex1995 »

Есть но там не уменьшено время опроса DS-ки.
Реклама
belov.alex1995
Встал на лапы
Сообщения: 91
Зарегистрирован: Сб ноя 30, 2013 01:57:26

Re: Часы на DS1307 (подправка кода)

Сообщение belov.alex1995 »

vAv писал(а):Для более частого опроса измени 2000 на 1000 или 500...;[/code]
Спасибо, подправил все работает, вот только точность часов немного страдает. Пробовал с 4-мя кварцами, с одними спешат на 3-5 секунд в сутки, с другими отстают.

Может кто-то подсказать как сделать корректировку точности? Например вычисляем погрешность часов за сутки и прибавляем это значение к последней минуте в сутках или отнимаем..
Реклама
Ответить

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