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

Оценка точности измерения тока интеллектуальными силовыми ключами PROFET

Интеллектуальные силовые ключи PFOFET производства Infineon могут измерять ток нагрузки с разной точностью, зависящей как от абсолютной величины потребляемого тока, так и от технологии производства конечной продукции, в частности – от наличия или отсутствия этапа калибровки. В статье подробно разбирается расчет коэффициента передачи тока на примере ключа BTS7004-1EPP.
Подробнее

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

Я не понял как настроить регистр 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

STMicroelectronics: электростатический разряд больше не проблема

Защита от статического электричества необходима каждому современному устройству. Компания STMicroelectronics представляет решения, соответствующие стандарту IEC61000-4-2, а также специальное приложение PROTECTION FINDER, которое поможет легкого и эффективно подобрать необходимые компоненты. Рассмотрим практические примеры защиты от ESD, отраслевые стандарты и ряд ключевых параметров важных при проектировании электростатической защиты устройств.

Подробнее

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

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

Удалось ли сделать резервную копию? Обеспечение бесперебойного питания

Для работы портативных электронных устройств с постоянным или длительным включением необходим резервный источник питания. Микросхемы диспетчеров питания производства Analog Devices LTC4040 или LTC4041 позволяют легко подключить резервное питание в виде Li-Ion-аккумулятора или суперконденсатора соответственно в случае сбоя или потери основного питания. Рассмотрим решения по резервированию питания на основе этих микросхем.
Подробнее

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

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...

  • Сообщения

    • Ошибаешься. Нуждается. Любопытство - двигатель прогресса. Так уж человек устроен, что ему необходима новая информация и знания, которые он будет всегда стремиться получить.   Для нас - да. А для них - нет. Люди не просто так отдают большие деньги на то, чтобы подняться в космос и посмотреть на Землю со стороны.    Можно завидовать, можно сожалеть, а можно наворовать как наши чинуши, и свалить туда жить, как они и делают.
    • Ну вот не дает мне народ закодироваться от флуда на форумах... эх... придется ответить... Не соглашусь кардинально, и дело тут не в законодательстве. Тут чисто практический аспект: производитель предусмотрел периодическое подтверждение характеристик по средством поверки, значит такое подтверждение надо обязательно выполнять. Хорошо я готов сделать маленькую поблажку: не так часто подтверждать как пишет производитель, поскольку речь о любителях... но все-таки подтверждать надо!!! Не делать ничего - могут позволить себе только коллекционеры. Если прибор используется, и особенно если прибор уже мне ровесник, процедура подтверждения характеристик обязательно должна быть проведена.   На тему поверять-калибровать-настраивать, эти термины вызывают у меня определенный когнитивный диссонанс, и вот почему: Процедура поверки по установленной методике, с платным оформлением протокола измерений и выдачей свидетельства обычно стоит "X" рублей. При этом клиент получает самое главное(по моему мнению) - данные измерения и жесточайшую метрологическую прослеживаемость до ГПЭ, при этом это могут делать только лаборатории аккредитованные на это. Процедура "калибровки" законодательно, может проводится лабораториями с куда худшей аккредитаций, и как таковой жесткой прослеживаемости может в определенных случаях даже и не быть. При этом типичная практика показывает что на процедуру  "калибровки" устанавливается ценник "X*2" рублей. Я с этим столкнулся при возникновении желания получить актуальные данные по сопротивлению мер "Р40*3" купленных на разных барахолках. Тоже примерно мне заявляли о мерах емкости КМЕ-**, типа поверить не можем, на данный вид измерений нет аккредитации на поверку, но можем откалибровать, и по результату выдать вам желанный протокол измерения.   Посмотрев на всю эту анархию, я решил что буду сдавать на поверку, потому-что она дешевле, и платить немного сверху за оформление протокола измерений, а так-же выбирать для критичных мне мер только поверителей с высоким уровнем доверия. Кстати на тему КМЕ-шек ночью родил материал: https://ampnuts.com/etalon/
    • Мне почему то кажется что с указанными хотелками правильнее переносить тему в раздел "Работа"
×
×
  • Create New...