Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: часы реального времени на MSP430F2013
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > MSP430
chainikru
Добрый вечер, Ни у кого нет программы на С++ для часов реального времени? Или что посоветуете при програмировании.
У меня есть 2 варианта программы на ассемблере:

; *****************************************************************************
; RTC, использующие сторожевой таймер
;
; Описание: Эта программа демонстрирует возможность реализации часов реального времени.
; В основной программе MSP430 переводится в режим LPM3.
; Сторожевой таймер формирует прерывание каждую секунду и переводит
; MSP430 в активный режим, который позволяет выполнить основную программу.
; Основная программа вызывает подпрограмму часов Clock и вновь переводит микроконтроллер в режим LPM3.
;
; Эта программа написана для микроконтроллера MSP430F1121, но легко может
; быть переработана для использования в любом микроконтроллере семейства MSP430.
;
; Для хранения информации о часах, минутах и секундах используются три регистра.
;

;*****************************************************************************
#include ”msp430x11x1.h” ; включить файл заголовков
; переменные RTC
#define SEC R13
#define MIN R14
#define HR R15
;–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
; Программа RESET
RSEG CODE
;–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
RESET
MOV #02FEh,SP ; Инициализация указателя стека
CALL #Setup ; Подготовка ЖКИ и основного таймера
; Основная программа
Mainloop
BIS #LPM3,SR ; Установка битов SR для режима LPM3
CALL #Clock ; обновление состояния часов
JMP Mainloop ; окончание основной программы
;–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
; Clock: обновление состояния переменных секунд, минут и часов (SEC, MIN и HR)
;
; Автор: Lutz Bierl.
;
; Эта подпрограмма, которая считает количество часов, минут и секунд.
; Она может использоваться с любым периферийным счетчиком любого микроконтроллера
; семейства MSP430, имеющим период переполнения 1 сек.
;
; Эта подпрограмма весьма специфическая. Она рассчитывает секунды, минуты
; и часы только в двоично-десятичном коде. При необходимости могут быть рассчитаны
; значения и в шестнадцатеричном коде.
;
; Среди примеров применения MSP430 имеются описания реализации часов реального
; времени, которые также рассчитывают и год с учетом коррекции високосного года.
;
;–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
Clock
SETC ; установка бита переноса
DADC.b SEC ; увеличение десятичного значения секунд
CMP.b #060h,SEC ; окончилась минута?
JLO Clockend ; нет, возврат
CLR.b SEC ; Да, очистка секунд
DADC.b MIN ; увеличение десятичного значения минут
CMP.b #060h,MIN ; прошло 60 минут?
JLO Clockend ; Нет, возврат
CLR.b MIN ; Да, очистка минут
DADC.b HR ; увеличение десятичного значения часов
CMP.b #024h,HR ; прошло 24 часа?
JLO Clockend ; Нет, возврат
CLR.b HR ; Да, очистка часов
Clockend
RET ;
;–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
; Setup: Настройка модулей и управляющих регистров
;–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
Setup
BIS.b #BIT0,&IE1 ; Разрешение прерывания от сторожевого таймера
MOV #WDTPW+WDTTMSEL+WDTCNTCL+WDTSSEL,&WDTCTL
; Остановка сторожевого таймера
; Установка интервала
; режима таймера и установка
; интервала прерывания
; 1 секунда с ACLK.
ClearRTC
MOV.b #00h,SEC ; Очистка секунд (SEC)
MOV.b #00h,MIN ; Очистка минут (MIN)
MOV.b #00h,HR ; Очистка часов (HR)
EINT ; Разрешение прерываний
RET ; установки выполнены
;–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
; Подпрограмма обработки прерывания от сторожевого таймера:
; ЦП просто переходит в активное состояние в RETI путем манипулирования битами SR
; в переменной SR, которая помещена в стек.
; Флаг прерывания очищается автоматически
;–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
WDINT
BIC #LPM3,0(SP) ; Очистка SR LPM3 битов в верхней части стека
RETI ;
;–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
RSEG INTVEC ; вектора прерываний
;–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
DW RESET ;
DW RESET ;
DW RESET ;
DW RESET ;
DW RESET ;
DW RESET ;
DW RESET ;
DW RESET ;
DW RESET ;
DW RESET ; Таймер Timer_A (CCIFG0)
DW WDINT ; Сторожевой таймер
DW RESET ;
DW RESET ;
DW RESET ;
DW RESET ; NMI, повреждение автогенератора
DW RESET ; POR, внешний сброс, сторожевой таймер
END

пример программы на ассемблере использующая таймер TIMER_A
; RTC, использующие таймер TIMER_A
;
; Описание: Эта программа демонстрирует возможность реализации часов реального времени.
; В основной программе MSP430 переводится в режим LPM3.
; Таймер Timer_A формирует прерывание раз в секунду, по которому
; MSP430 переходит в активный режим и оканчивает выполнение основной программы
; Основная программа вызывает подпрограммы Clock, а затем переводит микроконтроллер в режим LPM3.
;
; Эта программа написана для микроконтроллера MSP430F1121, но легко может
; быть переработана для использования в любом микроконтроллере семейства MSP430.
;
; Для хранения информации о часах, минутах и секундах используются три регистра.
;
;*****************************************************************************
;
#include ”msp430x11x1.h” ; включить файл заголовков определения
; переменных RTC
#define SEC R13
#define MIN R14
#define HR R15
;–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
; Программа RESET
RSEG CODE
;–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
RESET
MOV #02FEh,SP ; Инициализация указателя стека
CALL #Setup ; Подготовка ЖКИ и основного таймера
; Основная программа
Mainloop
BIS #LPM3,SR ; установка битов SR для режима LPM3
CALL #Clock ; обновление часов
JMP Mainloop ; окончание основной программы
;–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
; Clock: Обновление переменных секунд, минут и часов (SEC, MIN и HR)
;
; Автор Lutz Bierl.
;
; Эта подпрограмма, которая считает количество часов, минут и секунд.
; Она может использоваться с любым периферийным счетчиком любого микроконтроллера
; семейства MSP430, имеющим период переполнения 1 сек.
;
; Эта подпрограмма весьма специфическая. Она рассчитывает секунды, минуты
; и часы только в двоично-десятичном коде. При необходимости могут быть рассчитаны
; значения и в шестнадцатеричном коде.
;
; Среди примеров применения MSP430 имеются описания реализации часов реального
; времени, которые также рассчитывают и год с учетом коррекции високосного года.
;
;–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
Clock
SETC ; Установка бита переноса
DADC.b SEC ; увеличение десятичного значения секунд
CMP.b #060h,SEC ; Прошла одна минута?
JLO Clockend ; Нет, возврат
CLR.b SEC ; Да, очистка секунд
DADC.b MIN ; Увеличение десятичного значения минут
CMP.b #060h,MIN ; Прошло 60 минут?
JLO Clockend ; Нет, возврат
CLR.b MIN ; Да, очистка минут
DADC.b HR ; Увеличение десятичного значения часов
CMP.b #024h,HR ; Прошло 24 часа?
JLO Clockend ; Нет, возврат
CLR.b HR ; Да, очистка часов
Clockend
RET ;
;–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
; Setup: Настойка модулей и управляющих регистров
;–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
Setup
MOV #WDTPW+WDTHOLD,&WDTCTL ; Остановка сторожевого таймера
setupTA
MOV #TASSEL0+TACLR,&TACTL ; ACLK – источник для Timer_A.
BIS #CCIE,&CCTL0 ; Разрешение прерывания от CCR0.
MOV #07FFFh,&CCR0 ; загрузка в CCR0 значения 32,767.
BIS #MC0, &TACTL ; запуск TA в режиме ”up to CCR0”
ClearRTC
MOV.b #00h,SEC ; Очистка переменной SEC
MOV.b #00h,MIN ; Очистка переменной MIN
MOV.b #00h,HR ; Очистка переменной HR
EINT ; Разрешение прерываний
RET ;
;–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
; Подпрограмма обработки прерывания от таймера Timer_A:
; ЦП просто переходит в активное состояние в RETI путем манипулирования битами SR
; в переменной SR, которая помещена в стек.
; Флаг прерывания CCR0 очищается автоматически
;–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
CCR0INT
BIC #LPM3,0(SP) ; Очистка битов SR LPM3 переход в верх указателя стека
RETI ;
;–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
RSEG INTVEC ; Вектора прерываний
;–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
DW RESET ;
DW RESET ;
DW RESET ;
DW RESET ;
DW RESET ;
DW RESET ;
DW RESET ;
DW RESET ;
DW RESET ;
DW CCR0INT ; Таймер Timer_A (CCIFG0)
DW RESET ; Сторожевой таймер
DW RESET ;
DW RESET ;
DW RESET ;
DW RESET ; NMI, повреждение автогенератора
DW RESET ; POR, внешний сброс, сторожевой таймер
END
Что лучше использовать при программировании на С++ таймер TIMER_A или сторожевой таймер?И можно ли использовать какую нибуть из этих программ?
=DS=
Это передранный и слегка модифицированный код тексасовских апнот типа slaa076, slaa280 (может и для других серий есть, не смотрел). Причем модифицирован он так, что исключает совместное использование этого кода с С и С++ , поскольку компилятор как раз использует R12-R15 как временные регистры для передачи аргументов функций. Посмотрите лучше эти аппноты, там готовый пример стыковки ассемблера и С. Только два момента - во первых, для С++ функции, обьяваленные в хедере как extern, надо обьявить extern "C", во вторых, писались эти апноты во времена компиляторов 3.хх ), а с тех пор соглашения о передаче аргументов изменились, кажется с версии 4.(что-то там)... Так что ассемблерный код надо будет слегка перековырять, предварительно проштудировав главу Assembler language interface в IAR C/C++ Compiler Reference Guide.
А что касается того, что использовать - собаку или таймер - без разницы. Что свободно, то и используйте.
Approxymator_66
#include <io.h>
#include <signal.h>
#include <dz1612\dz1612.h>
#include "timerb.h"

// initialize variable
volatile int i=0; // counter of interrupts
volatile int k=0; // counter of buttons' interrupts


//sistem time initialize
struct{
int ms; // 0,1 of second
int ss; // second
int mm; // minutes
int hh; // hours
} st = {0,0,0,0};

//initialize TIMER_B
void init_timerb(){
TBCTL = 0;
TBCCR0 =60000; // interrupt time point = 60000 ticks = 0,01 s
TBCCTL0 = (1<<4);
TBCTL = TBSSEL_2 + MC_0 + CNTL_0 + TBCLR;
// Timer_B SMCLK source mode
// up mode (from 0 to TACCR0)
// interrupt enable
// divider in TIMER_A to SMCLK = 1
};

void en_intp1(){
// for bit whith button write 0 to P1DIR
P1DIR &= 0x0f; // write 0 to P1DIR
P1IES &= 0x0f; // write 0 to P1IES
P1SEL &= 0x0f; // write 0 P1SEL
P1IFG = 0;
P1IE |= 0xf0; // write 1 to P1IE

}

volatile int a = 0;
// interrupt vector for TIMER_B
void __attribute__((interrupt(TIMERB0_VECTOR))) port2_irq() {
a |= 1;
i++;
if (i>=10){
st.ms++;
i=0;
}
if (st.ms>=10){
st.ss++;
st.ms = 0;
}
if (st.ss>=60){
st.mm++;
st.ss = 0;}
if (st.mm>=60){
st.hh++;
st.mm = 0;
}

}

void __attribute__((interrupt(PORT1_VECTOR))) port1_irq(){
/* this function will be called every time then button state changed */
a |= 2;
k++;
// if (P1IFG & (1<<4) ){
if (k==1) {
TBCTL &= 0xffcf;
TBCTL |= MC_1 ; //start timer by pressing button 1
}
// if (P1IFG & (1<<5)){
if (k==2) {
TBCTL &= 0xffcf; //stop timer by pressing button 2 1100
}
if (k==3){
st.ms = 0;
st.ss = 0;
st.mm = 0;
k=0;
}

if (P1IFG & (1<<6)){
TBCTL = TBCLR;
init_timerb(); //clear timer

}

P1IFG = 0; //set interrupt flag to 0

}

int main(){
init_pins();
init_clock();
if( init_systimer(128) )
halt(23);
stdio_init(9600);
ka_setmode( KAM_NORMAL );
wdog_reassure();
eint();
puts ("start\r\n\f");
init_timerb();
en_intp1();
puts(" timer B ok \r\f");
while(1){
wdog_reassure();


if( a ) {
a &= ~1;
a &= ~2;
printf (" timer: %02d %02d %02d %01d \r\f",st.hh, st.mm, st.ss, st.ms);
}
}
}

Здесь конечно не часы, но сделать можно. СДелано на таймере Б (Timer_B)
chainikru
а назначение этой программы какое?
Вовчег
Цитата(chainikru @ Dec 15 2011, 10:54) *
а назначение этой программы какое?

Ну судя по этому:
Цитата
TBCTL |= MC_1 ; //start timer by pressing button 1
}
// if (P1IFG & (1<<5)){
if (k==2) {
TBCTL &= 0xffcf; //stop timer by pressing button 2 1100

ну в общем ты понял.

Но вопрос с просто часами реального времени на Си так и остался открытым.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.