Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: stm8s 16mhz и точность часов
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > Все остальные микроконтроллеры > STM8
dexter_khm
Сделал часы на базе контроллера 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 но и на ней отставание присутствует. Помогите советом что делаю не так?
RabidRabbit
Добавляйте в программу средства коррекции хода sm.gif © Капитан.
fowler
Насколько я помню, делитель учитывается как 'prescaler' + 1.
Попробуйте уменьшить его на единицу.
dexter_khm
Всем спасибо проблему решил ответ на этом форуме http://forum.easyelectronics.ru/viewtopic....=33&t=18186
Myron
Цитата(RabidRabbit @ Mar 12 2014, 00:34) *
Добавляйте в программу средства коррекции хода sm.gif © Капитан.


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

Или есть калибровочная таблица зависимости погрешности внутренней тактовой от температуры?
RabidRabbit
По ссылке выше всё прекрасно разжёвано, даже программная коррекция хода.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2024 Invision Power Services, Inc.