Jump to content
-=gga=-

Настройка Таймера В Nec Контроллере

Recommended Posts

Собсна как можно настроить таумер чтобы он выдавал прерывания каждую секурду ?

Вот отрывок кода, из настройки таймера:

void init_TMH1()

{

TMHE1 = 0; //stop timerH1

TMHMD1 = 0x40; //set input clock to fxp / 2^12 = 1953,125 Hz @ 8MHz

CMP01 = 0x62; //set interval time to 50ms

TMIFH1 = 0; //clear interrupt request flag

TMMKH1=0; //enable timerH1 interrupt

}

Скажите плиз какая строчка за что отвечает ?

Да и вот этот коментарий

set input clock to fxp / 2^12 = 1953,125 Hz @ 8MHz

как его понимать ? 2 умноженное на 12 никак не даст 1953,125. а тут равенство какоето....

Share this post


Link to post
Share on other sites

На одну секунду сделать задержку одним таймером не получится.

Если конечно говорить о семействе 78K0S

В более навороченных семействах есть больше таймеров, предусмотрены разные режимы тактирования, иногда имеется второй кварц на 32,768 КГц

Вот с помощью этого кварца можно сформировать довольно точную секунду.

Остальные кварцы, не выдающие частоту 2^х, точной секунды сформировать не помогут :(

Теперь конкретнее о твоем примере.

Вообще таймер - просто счетчик, который считает входные импульсы, и при совпадении с заранее заданным числов выставляет флаг и(или) генерирует прерывание. В данном случае таймер настроен на время 50 мСек.

1. Сначала останавливается таймер, что-бы не мешался

2. Непонятная тебе строчка fxp / 2^12 = 1953,125 Hz @ 8MHz говорит о том, что входной частотой для таймера является не частота процессора fxp, которая в примере 8 МГц, а она-же но поделенная на 2 в степени 12.

Т.е. между тактом проца и таймером включили предделитель на 4096.

Соответственно 8 МГц / 4096 = 1953,125 Гц Эта частота является тактовой для таймера.

Предделитель можно выбрать один из ряда 2^2, 2^4, 2^6, 2^12 или вообще подавать на таймер частоту тактирования ядра.

Особый случай fRL / 2^7, тут делится не частота ядра процессора, а дополнительный генератор 240 кГц, т.е. входной частотой для таймера тут будет 1875 Гц

3. В таймер записывается число 0х62 (98 в десятичной системе). Т.е. таймер будет отсчитывать интервалы времени, равные 98 периодам тактовой частоты, по сути 1953,125 / 98 = 19,929846938775510204081632653061 Гц

Период этой частоты будет 0,050176 Сек

От нужного нам интервала 50 мСек, он отличается на 0,352%

Вроде немного, но за сутки такие часы отстанут примерно на 5 минут

4. Сбрасываем флаг прерываний, что-бы не вызвать ложного прерывания сразу после следующей команды

5. Разрешаем прерывания, которые будут вызываться каждые 0,050176 Сек

В программе тебе надо выделить переменную, и в п/п прерывания ее увеличивать.

Как только она станет равной 20, значит прошла секунда, и ты можешь выполнить какое-то действие.

Не забудь при этом сбросить свою переменную.

P.S. Посмотри даташит на русском, страница 111, там более полная информация.

P.P.S. У разных таймеров свои предделители, каждый из них может инициализироваться на свою частоту.

Edited by Migray

Share this post


Link to post
Share on other sites

Почемуто твоё объяснение удложилось у меня в голове лучше, чем то что написано в даташите. :)

Зная то что ты сказал, и формулу Т(периуд)=1/частоту. Я подсчитал что если вместо 0х62 записать 0хС5 (196) у меня получиться 1953,125/196=9,96492346938776 а периуд будет равен 0,100352 то есть 0.1с. это покрупнее будет чем 50мс. А если умножить на 255 то я получу здержку в 25.5 секунд, и это вполне удовлетроряет мои потребности. :)

Спасибо тебе, теперь всё работает! :)

Share this post


Link to post
Share on other sites

Вебинар STM32G0 – новый лидер бюджетных 32-битных микроконтроллеров от STMicroelectronics

Компания Компэл приглашает вас 25 сентября принять участие в вебинаре, который посвящен новому семейству микроконтроллеров STM32G0. Вебинар рассчитан на технических специалистов и тех, кто хорошо знаком с семейством STM32. На вебинаре будут освоены современные методы тестирования производительности микроконтроллеров на примере самых бюджетных 32-битных семейств общего назначения STM32G0 и STM32F0 и проведено их подробное сравнение.

Подробнее

В принципе с таймером я разобрался, но осталась одна неурядица.

Я не понял как настроить регистр TMHMD1 точнее я не могу настроить биты предделителя.

В даташите есть такоеописание

post-17647-1205591709_thumb.jpg

Но дело в том что у меня сецчас в регистр TMHMD1 записано число 0х40 что даёт 00101000

В примере указано что у меня предлелитель на 2^12 а это значит что биты должны быть выстовлены вот так:

CKS12 1

CKS11 0

CKS10 0

Это я взял из даташита.

Но с какой бы стороны я не считал, у меня эти три бита не совпадают с нужными числами. :(

Или может я чтото не правильно делаю ?

Share this post


Link to post
Share on other sites

Ты просто ошибся в переводе в двоичную систему.

0x40 = 40h = 01000000b

Так-что 0100 0000 в регистре TMHMD1 как раз выставляет

CKS12 1

CKS11 0

CKS10 0

при остановленном таймере.

Потом, с годами тренировки, будешь переводить в уме :)

На первых порах можно пользоваться стандартным виндовым калькулятором, переведя его в инженерный вид.

Я и сейчас им иногда пользуюсь, даже на клавиатуре бумажки наклеены, у горячих клавиш.

F5 - "Hex"

F6 - "Dec"

F7 - "Oct"

F8 - "Bin"

Share this post


Link to post
Share on other sites
                     

Литиевые батарейки Fanso в беспроводных датчиках пожарно-охранной сигнализации

Выбор подходящего элемента питания, способного обеспечивать требуемый уровень напряжения и выдавать необходимый ток на протяжении всего периода эксплуатации беспроводной пожарно-охранной системы является одной из первостепенных задач. Наиболее подходящим для этих целей элементом являются литий-тионилхлоридные элементы питания, а одним из наиболее конкурентоспособных производителей – компания Fanso, предлагающая своим клиентам продукты как универсальные, так и разработанные специально для решения конкретных задач.

Подробнее...

Ах вот где собака зарыта. Дело в том что я переводил не так:

0x40 = 40h = 01000000b

а вот так

0x40 = 00101000b

Вот по этому и получал другое число :(

Я тоже пользуюсь калькулятором, но не виндовым а более сложным и удобным. Он имеет три независимых калькулятора в одном окне (их можно переключать) и это очень удобно. Ну и ещё плюс кучи функций, типа синусы, арксинусы и т.п.

Если хочешь могу поделиться, протативная версия :)

Share this post


Link to post
Share on other sites

Все понятно :)

0х40 это всегда 40h, слева - альтернативное обозначение 16-ричной системы

а вот 40 это 40d, в смысле десятичная.

Похоже ты забыл перед набором числа перевести калькулятор в 16-ричный

Вот и получилось что

40 d = 28 h = 0010 1000 b

Калькулятор давай, пригодится, но у виндового есть свое преимущество, он стоит на любой машине.

Когда в командировке заходишь в сеть из инет-кафе, то в случае необходимости калькулятор там есть.

А тебе маленький совет.

Попробуй вообще без калькуляторов пару недель поработать.

16/10 не обещаю, а вот 16/2 выучишь точно.

И еще совет, при записи двоичного числа разбивай его на тетрады, удобней воспринимается и в 16-ричную переводится автоматом.

Share this post


Link to post
Share on other sites

Главное что уже разобрался, теперь перейду на тайтер 80.

Калькулятор вот, называется он HEXelon MAX 6.07 версия на данный момент последняя. Размер 1 мб. Протативная. Там есть такие функции как синусы, косинусы и ещё куча всего, чего я не знаю :) Скачать можно тут http://eldigi.ru/site/programms.php

Да и ещё там есть утилита, для перевода знаков в ASCII код.

В уме переводить я не умею, и учить в ближайшие три месяца наверное не буду, сейчас у меня есть куча всего что мине нужнее, в том числе физика и математика....

Это мне особо и не нужно, как ты и скащал виндовый калькулятор всегда под рукой :)

Share this post


Link to post
Share on other sites

Вообще-то с 80 таймера и надо было начинать.

Он как раз предназначен для формирования задержек, и его предделитель обладает большим коэффициентом деления.

2^6

2^8

2^10

2^16

Используя делитель 2^16 при 8 МГц тактовой можно было сформировать задержку до 2 секунд без использования внешних переменных.

А для таймера H1 есть более интересные функции, такие как ШИМ

Можно не просто светодиодом мигать, а еще менять его яркость, или управлять скоростью моторчика.

Edited by Migray

Share this post


Link to post
Share on other sites

Воспользовавшись твоим советом, решил менять яркость светодиода, используя ШИМ. Но у меня чтото не работает. Вот алгоритм в двух словах.

После включения у меня светодиод потухший, потом он должен постепенно загореться, достигнув максимума он должен постепенно выключаться. Но у меня с таким кодом светодиод просто моргает, при чём ни частота, ни ,тем более, яркость не меняются :(

Вот куски программы

PM4_bit.no2=0; // делаем порт 42 выходом ШИМ-а

//-----------------------------------------------------------------------------

// Module: init_TMH1

// Function: Initialization of TimerH1

//-----------------------------------------------------------------------------

void init_TMH1()

{

TMHE1 = 0; //stop timerH1

TMHMD1 = 0x49; //set input clock to fxp / 2^12 = 1953,125 Hz @ 8MHz

CMP01 = 0xFF; //Период навен 255

TMIFH1 = 0; //clear interrupt request flag

TMMKH1=0; //enable timerH1 interrupt

}

void main(void)

{

__disable_interrupt(); // global interrupt disable

init_CPU(); // CPU initialization

init_LED(); // LED port initialization

init_TM80(); // initialization of timer80

init_TMH1();

restart_TM80(); // start timer80

restart_TMH1(); // start timerH1

__enable_interrupt(); // global interrupt enable

unsigned char pwm = 1;

unsigned char inc = 1; // inc = 0 - уменьшать, inc = 1 - увеличивать яркость

if (inc == 1)

{

if (pwm < 254)

{

pwm++; // Увеличиваем яркость лампы, пока не достигнем максимума

CMP11 = pwm;

}

else

{

inc = 0;

}

}

else

{

if (pwm > 1)

{

pwm--; // Уменьшаем яркость лампы, пока не остигнем минимума

CMP11 = pwm;

}

else

{

inc = 1;

}

}

}

Вот весь код целиком:

#include "io78f9222.h"	// include LPC header files
#include <intrinsics.h>

//-----------------------------------------------------------------------------
// Definition of Option Byte
//-----------------------------------------------------------------------------
#pragma location = "OPTBYTE"
__root const unsigned char optbyte = 0x98;		

//-----------------------------------------------------------------------------
// Global Defines
//-----------------------------------------------------------------------------

#define LED1   P2_bit.no3    	    // LED D1
#define LED2   P13_bit.no0	    // LED D2
#define LED   P4_bit.no2           
#define LED4   P12_bit.no3	    // LED D4


//-----------------------------------------------------------------------------
// Global variables
//-----------------------------------------------------------------------------

__saddr volatile unsigned char Timer80Flag;
__saddr volatile unsigned char IntP0Flag;



//-----------------------------------------------------------------------------
// Module:   init_CPU
// Function: Initialization of CPU
//-----------------------------------------------------------------------------
void init_CPU (void)
{
// stop watchdog timer
 WDTM = 0x70;

//clock gererator settings
 PCC = 0x00;			// set CPU clock to fx
 PPCC = 0x00;
 LSRCM = 0x01;			// low speed ring oscillator stops

 OSTS  = 0x00;			//shortest stabilisation time 2^10/fx

// interrupt setting
  IF0  = 0x00;
  IF1  = 0x00;
  MK0  = 0xFF;
  MK1  = 0xFF;
}

//-----------------------------------------------------------------------------
// Module:   init_LED
// Function: Initialization of LED ports
//-----------------------------------------------------------------------------
void init_LED (void)
{
 PMC2_bit.no3=0;           // set port mode control of P23 to port mode
 PM2_bit.no3=0;            // set port P23 to output mode -> LED1
 PM4_bit.no2=0;            
 PM12_bit.no3=0;           // set port P123 to output mode -> LED4

 LED1=0;     	    // drive LED1
 LED2=0;	    // drive LED2
 LED4=0;	    // switch LED4 off

 LED1=1;	    // switch LED1 off
 LED2=1;	    // switch LED2 off  
 LED4=0;	    // drive LED4


}
//-----------------------------------------------------------------------------
// Module:   init_TM80
// Function: Initialization of Timer80
//-----------------------------------------------------------------------------
void init_TM80 (void)
{
  TCE80 = 0;			//disable timer80
  TMC80 = 0x06;	        //set input clock to fxp / 2^16 = 120 Hz @ 8MHz
  CR80  = 0x78;		//interval time = 1s	
  TMIF80 = 0;			//clear interrupt request flag
  TMMK80=0;			//enable timer80 interrupt
}

//-----------------------------------------------------------------------------
// Module:   restart_TM80
// Function: restarting of Timer80
//-----------------------------------------------------------------------------
void restart_TM80 (void)
{
  Timer80Flag=0;               //Reset status flag Timer80
  TCE80 = 0;			//disable timer80
  TCE80 = 1;			//enable timer80
}

//-----------------------------------------------------------------------------
// Module:   Wait50
// Function: This module delays the program for n * 50 ms.
//-----------------------------------------------------------------------------
void Wait(unsigned char Number)
{
 restart_TM80();
 while(Number>0)
 {
       while(Timer80Flag==0);
       Timer80Flag=0;               // Reset status flag Timer80
       Number--;
 }
 return;
}

//-----------------------------------------------------------------------------
// Module:   init_TMH1
// Function: Initialization of TimerH1
//-----------------------------------------------------------------------------
void init_TMH1()
{
  TMHE1 = 0;           //stop timerH1
  TMHMD1 = 0x49;	//set input clock to fxp / 2^12 = 1953,125 Hz @ 8MHz
  CMP01  = 0xFF;
  TMIFH1 = 0;		//clear interrupt request flag
  TMMKH1=0;		//enable timerH1 interrupt
}

//-----------------------------------------------------------------------------
// Module:   restart_TMH1
// Function: This module restarts TimerH1
//-----------------------------------------------------------------------------
void restart_TMH1 (void)
{
  TMHE1 = 0;
  TMHE1 = 1;
}
//-----------------------------------------------------------------------------
// Module:   main
// Function: main program
//-----------------------------------------------------------------------------
void main(void)
{

 __disable_interrupt();        // global interrupt disable
 init_CPU();           	// CPU initialization
 init_LED();		 	// LED port initialization
 init_TM80();			// initialization of timer80
 init_TMH1(); 	

   restart_TM80();		// start timer80
   restart_TMH1();		// start timerH1

 __enable_interrupt(); 	// global interrupt enable

unsigned char pwm = 1;
unsigned char inc = 1; // inc = 0 - уменьшать, inc = 1 - увеличивать яркость

   if (inc == 1) 
 {
   if (pwm < 254)
   {
     pwm++;  // Увеличиваем яркость лампы, пока не достигнем максимума
     CMP11 = pwm;
   }
   else
   {
     inc = 0;
   }
 }
 else
 {
   if (pwm > 1)
   {
     pwm--;  // Уменьшаем яркость лампы, пока не остигнем минимума
     CMP11 = pwm;
   }
   else
   {
     inc = 1;
   }
 }
 }

//-----------------------------------------------------------------------------
// ISR: 	  isr_INTTM80
// Function: Interrupt service routine of Timer80
//----------------------------------------------------------------------------
#pragma vector=INTTM80_vect
__interrupt void isr_INTTM80(void)
{
 Timer80Flag=0x1;    		 // Set status flag for Timer80
}
//-----------------------------------------------------------------------------
// ISR: 	  isr_INTTMH1
// Function: Interrupt service routine of Timer80
//-----------------------------------------------------------------------------
#pragma vector=INTTMH1_vect
__interrupt void isr_INTTMH1(void)
{
}

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

×
×
  • Create New...