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

stm8s 16mhz и точность часов

Сделал часы на базе контроллера stm8s. Светодиодный семимегментник на 4 разряда, четыре сенсорных кнопки STM8 Touch-Sensing. Все работает вроде но вот часы за день отстают на минуту. Кварц на 16мГц надпись на нем 16,0RG9-3H.

 

инициализация таймера:

void Timer_Init(void)
{
    // Reset ("de-initialise") TIM1.
    TIM1_DeInit();
    // Set TIM1 to:
    // - use an exact prescaler of 1000,
    // - to count up,
    // - to have a period of 1, and
    // - to have a repetition counter of 0.
    TIM1_TimeBaseInit(16000, TIM1_COUNTERMODE_DOWN, 1000, 0);//
    // Set TIM1 to generate interrupts every time the counter overflows (every ms).
    TIM1_ITConfig(TIM1_IT_UPDATE, ENABLE);
    // Enable TIM1.
    TIM1_Cmd(ENABLE);
    
    // Enable interrupts (no, really).
    enableInterrupts();
}

 

Таблица векторов прерываный:

struct interrupt_vector const _vectab[] =
  {
    {
      0x82, (interrupt_handler_t)_stext
    }
    , /* reset */
    //{0x82, (interrupt_handler_t)main}, /* reset */
    {0x82, NonHandledInterrupt}, /* trap */
    {0x82, NonHandledInterrupt}, /* irq0 - tli */
    {0x82, NonHandledInterrupt}, /* irq1 - awu */
    {0x82, NonHandledInterrupt}, /* irq2 - clk */
    {0x82, NonHandledInterrupt}, /* irq3 - exti0 */
    {0x82, NonHandledInterrupt}, /* irq4 - exti1 */
    {0x82, (interrupt_handler_t)EXTI_PORTC_IRQHandler}, /* irq5 - exti2 */
    {0x82, NonHandledInterrupt}, /* irq6 - exti3 */
    {0x82, NonHandledInterrupt}, /* irq7 - exti4 */
    {0x82, NonHandledInterrupt}, /* irq8 - can rx */
    {0x82, NonHandledInterrupt}, /* irq9 - can tx */
    {0x82, NonHandledInterrupt}, /* irq10 - spi*/
    {0x82, (interrupt_handler_t)TIM1_UPD_OVF_TRG_BRK_IRQHandler}, /* irq11 - tim1 */
    {0x82, NonHandledInterrupt}, /* irq12 - tim1 */
    {0x82, NonHandledInterrupt}, /* irq13 - tim2 */
    {0x82, NonHandledInterrupt}, /* irq14 - tim2 */
    {0x82, NonHandledInterrupt}, /* irq15 - tim3 */
    {0x82, NonHandledInterrupt}, /* irq16 - tim3 */
    {0x82, NonHandledInterrupt}, /* irq17 - uart1 */
    {0x82, NonHandledInterrupt}, /* irq18 - uart1 */
    {0x82, NonHandledInterrupt}, /* irq19 - i2c */
    {0x82, NonHandledInterrupt}, /* irq20 - uart2/3 */
    {0x82, NonHandledInterrupt}, /* irq21 - uart2/3 */
    {0x82, NonHandledInterrupt}, /* irq22 - adc */
    {0x82, (interrupt_handler_t)TSL_Timer_ISR}, /* irq23 - tim4 */
    {0x82, NonHandledInterrupt}, /* irq24 - flash */
    {0x82, NonHandledInterrupt}, /* irq25 - reserved */
    {0x82, NonHandledInterrupt}, /* irq26 - reserved */
    {0x82, NonHandledInterrupt}, /* irq27 - reserved */
    {0x82, NonHandledInterrupt}, /* irq28 - reserved */
    {0x82, NonHandledInterrupt}  /* irq29 - reserved */
  };

 

Прерывание таймера:

INTERRUPT_HANDLER(TIM1_UPD_OVF_TRG_BRK_IRQHandler, 11)
{
    TIM1_ClearITPendingBit(TIM1_IT_UPDATE);
    

        rtc_service();
        rtc_get_time(&Time);
    
}

 

Функции RTC переделал из библиотеки для AVR:

/********************************************************************************
***********
* Программная реализация часов                                                             *
* Версия 0.1                                                                               *
* Начато 27 августа 2005 года                                                              *
* Окончено 28 октября 2005 года                                                            *
* Автор Якимов Юрий Анатольевич                                                            *
********************************************************************************
***********/

#include "main.h"
#include "stm8s_it.h"
#include <string.h>
#include "Rtc.h"

//#include "service.h"


void cli(void)
{
disableInterrupts();
}

void sei(void)
{
enableInterrupts();
}

unsigned char month_day_table[]={31,28,31,30,31,30,31,31,30,31,30,31};
unsigned char CorectionFlag=0;

rtc_type rtc_time;                                    //системное время

//Инициализация часов
void rtc_init(void)
{
rtc_set_time(0,0,0);                                  //Время считаем с 00:00:00
rtc_set_date(1,1,2012);                               //Дату считаем с 1 января 2000 года
}

//Наращивание часов
void rtc_service(void)
{
  unsigned char day_tmp;

    rtc_time.seconds++;
    if(rtc_time.seconds>59)
        {
        rtc_time.seconds=0;
        rtc_time.minutes++;
        if(rtc_time.minutes>59)
            {
            rtc_time.minutes=0;
            rtc_time.hours++;
            if(rtc_time.hours>23)
                {
                rtc_time.hours=0;
                rtc_time.day++;
                                //если год - високосный и сейчас февраль
                                if(leap_year(rtc_time.year) && (rtc_time.month==2))
                                  day_tmp=29;         //то количество дней - 29
                                else
                                  day_tmp=month_day_table[rtc_time.month-1]; //иначе - как обычно
                if(rtc_time.day > day_tmp)
                    {
                    rtc_time.day=1;
                    rtc_time.month++;
                    if(rtc_time.month>12)
                        {
                        rtc_time.month=1;
                        rtc_time.year++;
                        }
                    }
                }
            }
        }
}

//Устанавливает системное время
void rtc_set_time(unsigned char hours, unsigned char minutes, unsigned char seconds)
{
  cli();
  rtc_time.hours=hours;
  rtc_time.minutes=minutes;
  rtc_time.seconds=seconds;
  sei();
}

//Устанавливает системную дату
void rtc_set_date(unsigned char day, unsigned char month, unsigned int year)
{
  cli();
  rtc_time.day=day;
  rtc_time.month=month;
  rtc_time.year=year;
  sei();
}

//Получает текущее время и размещает в rtc_var
void rtc_get_time(rtc_type *rtc_var)
{
  cli();
  memcpy(rtc_var,&rtc_time,sizeof(rtc_time));
  sei();
}

//Возвращает 1, если год test_year - високосный
unsigned char leap_year(unsigned int test_year)
{
  if(((test_year%4==0) && (test_year%100)) || (test_year%400==0))
    return 1;
  else
    return 0;
}

 

Два таймера заняты сенсорными кнопками

#define TIMACQ           (TIM3)
#define TIMTICK         (TIM4)

 

Незнаю где набегает отставание в одну минуту. сначала грешил на некачественный кварцы, сегодня вернулся к плате дискавери на stm8s но и на ней отставание присутствует. Помогите советом что делаю не так?

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


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

Насколько я помню, делитель учитывается как 'prescaler' + 1.

Попробуйте уменьшить его на единицу.

 

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


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

Всем спасибо проблему решил ответ на этом форуме http://forum.easyelectronics.ru/viewtopic....=33&t=18186

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


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

Добавляйте в программу средства коррекции хода :) © Капитан.

 

А что, там есть внутри термокомпенсированный RTC с погрешностью 3-4ррм по которому можно корректировать или его и использовать?

 

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

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


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

По ссылке выше всё прекрасно разжёвано, даже программная коррекция хода.

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


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

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

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

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

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

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

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

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

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

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