Обсуждаем контроллеры компании Atmel.
Ответить

Re: Калибровка встроенного RC-генератора

Чт окт 21, 2021 10:23:16

Starichok51 писал(а):и откуда взялись 100011 мкс?
У меня всего один USB удлинитель, эталон так же как и МК(прошивка) управляется по UART, эталон не запоминает установленную частоту и начинает после включения частоту гнать 1Гц.
Так вот, либо управляю МК либо эталоном.
100011 мкс это частота эталона, производитель уверяет 10 минус 12 степени.

Re: Калибровка встроенного RC-генератора

Чт окт 21, 2021 10:39:01

то есть, ты меняешь частоту эталона, пока не получишь стабильную картинку?

Re: Калибровка встроенного RC-генератора

Чт окт 21, 2021 13:08:05

Starichok51, да, пока так.

Как вам такой вариант:
На вывод XCK T0 подаем наш эталонный 1Гц, это будет калибровочный интервал.
100 раз в секунду вызывается прерывание по таймера T1.
В прерывании производим сам отсчёт времени и отсчёт длительности калибровочного интервала T0.
Так как прерывание T1 будет вызываться 100 раз в секунду, соответственно и будет проверять состояние T0.

По прошествии какого-то времени останавливаем процесс и записываем разницу в еепром или еще куда.
Благодаря делителю в T0 это время можно увеличить.

Чисто теоретически время в T1 должно совпасть с T0.

Re: Калибровка встроенного RC-генератора

Чт окт 21, 2021 16:42:28

а я бы сделал так:
пусть таймер0 считает свои тактовые импульсы. плюс счетчик переполнений таймера0.
а на вход Т1 подал бы эталонную частоту. в принципе - любую частоту. и настроил таймер1 делить по совпадению до интервала 1 секунда.
получим "окно для измерения собственной частоты в 1 секунду.
и в прерывании по сравнению считываем счетчик таймера0 и счетчик переполнений.
но проверяемое устройство должно иметь экран для вывода посчитанных импульсов таймером0. и сразу увидим собственную частоту.

Добавлено after 3 minutes 49 seconds:
получим частотомер наоборот.
частотомер формирует собственное "окно" и считает внешние импульсы, а тут "окно" формируется внешними импульсами, а считает собственную частоту.

Re: Калибровка встроенного RC-генератора

Чт окт 21, 2021 18:10:51

Starichok51 писал(а):а я бы сделал так:
держи
Спойлер
Код:
volatile uint32_t hast_t;
volatile uint32_t hast;
volatile uint8_t hast0;

volatile bool flag1;

ISR (TIMER0_OVF_vect)
{
   hast_t++;
}

ISR (TIMER1_COMPA_vect)
{
   hast0 = TCNT0;
   hast = hast_t;

   TCNT0=0; hast_t=0;  TCNT0=0;

   flag1 =1;
}

int main()
 {

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 16000,000 kHz
// Mode: Normal top=0xFF
// OC0A output: Disconnected
// OC0B output: Disconnected
// Timer Period: 0,016 ms
TCCR0A=(0<<COM0A1) | (0<<COM0A0) | (0<<COM0B1) | (0<<COM0B0) | (0<<WGM01) | (0<<WGM00);
TCCR0B=(0<<WGM02) | (0<<CS02) | (0<<CS01) | (1<<CS00);
TCNT0=0x00;
OCR0A=0x00;
OCR0B=0x00;

// Timer/Counter 1 initialization
// Clock source: T1 pin Falling Edge
// Mode: CTC top=OCR1A
// OC1A output: Disconnected
// OC1B output: Disconnected
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: On
// Compare B Match Interrupt: Off
TCCR1A=(0<<COM1A1) | (0<<COM1A0) | (0<<COM1B1) | (0<<COM1B0) | (0<<WGM11) | (0<<WGM10);
TCCR1B=(0<<ICNC1) | (0<<ICES1) | (0<<WGM13) | (1<<WGM12) | (1<<CS12) | (1<<CS11) | (0<<CS10);
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x01;
OCR1BH=0x00;
OCR1BL=0x00;

// Timer/Counter 0 Interrupt(s) initialization
TIMSK0=(0<<OCIE0B) | (0<<OCIE0A) | (1<<TOIE0);

// Timer/Counter 1 Interrupt(s) initialization
TIMSK1=(0<<ICIE1) | (0<<OCIE1B) | (1<<OCIE1A) | (0<<TOIE1);

flag1=0;

// Global enable interrupts
sei();

printf("\nHello, world! \r\n");

while (1)
      {

      if(flag1==1) {

      printf("hast=%lu hast0=%d\n\r", hast, hast0);

      flag1 = 0;
      }

      }
}
СпойлерНа вход была подана частоты 1Гц

в протеусе при частоте МК 16МГц
Код:
hast=124999 hast0=228
hast=124999 hast0=229
hast=124999 hast0=227
в реальности
Код:
hast=124986 hast0=90
hast=124986 hast0=89
hast=124986 hast0=88
hast=124986 hast0=89
hast=124986 hast0=89
hast=124986 hast0=88
hast=124986 hast0=88
hast=124986 hast0=89
hast=124986 hast0=88
hast=124986 hast0=89
считай частоту МК

Re: Калибровка встроенного RC-генератора

Чт окт 21, 2021 19:08:56

надо поставить в такой последовательности:
Код:
   hast0 = TCNT0;
  TCNT0=0;
   hast = hast_t;
   hast_t=0;

чтобы меньше потерять импульсов между чтением регистра TCNT0 и его обнулением.
а еще лучше сделать это на ассемблере, чтобы еще меньше было потерь времени между чтением и обнулением.
в протеусе у тебя получилась частота 15999986. потеряно 14 импульсов.
переделай, как я предложил, потерь должно стать меньше. ну, это я так думаю ...

Re: Калибровка встроенного RC-генератора

Чт окт 21, 2021 20:38:35

Переделал так
Спойлер
Код:
ISR (TIMER1_COMPA_vect)
{
   hast0 = TCNT0;
   TCNT0=0;
   TIFR0 |= (1<<TOV0);
   hast = hast_t;
   hast_t=0;
   flag1 =1;
}
Если в друг произошел запрос на прерывание Т0, обнулить его
Спойлерв протеусе так
Код:
hast=124999 hast0=253
hast=124999 hast0=253
hast=124999 hast0=253
hast=124999 hast0=253
в реальности так
Код:
hast=124986 hast0=100
hast=124986 hast0=101
hast=124986 hast0=100
hast=124986 hast0=101
hast=124986 hast0=101
hast=124986 hast0=102
hast=124986 hast0=101
hast=124986 hast0=102
hast=124986 hast0=101
hast=124986 hast0=102
hast=124986 hast0=101
А так кварц дерьмо, палец на кварц ложишь число hast0=101 лезет вверх, долезло до 159, при холодном старте начало с 80. После 10 минут работы находится в диапазоне 99-104.
Не поленился, паяльник включил, нагрел до hast0=239, потом какой-то сбой пошел, спустя 5 минут остывания в норму вошел 101-102.

А вы хотите стабильность? В термокамеру его надо сувать, может тогда и будет стабильность.

Re: Калибровка встроенного RC-генератора

Чт окт 21, 2021 20:48:58

Dimon456 писал(а):Если в друг произошел запрос на прерывание Т0, обнулить его
если произошел запрос на прерывание Т0, то нужно не только сбросить флаг, но и сделать инкремент hast_t, так как переполнение уже наступило.
ну вот, в протеусе теперь потерялось всего 3 импульса вместо 14 импульсов.
в реальности тоже "нашлось" 12-13 импульсов.
то есть, стало гораздо точнее.
потерей 3 импульсов на частоте 16 МГц, я думаю, уже можно пренебречь.

Re: Калибровка встроенного RC-генератора

Чт окт 21, 2021 21:00:35

Starichok51 писал(а):потерей 3 импульсов на частоте 16 МГц, я думаю, уже можно пренебречь.
Для протеуса самый раз.

А в реальности - получается целая печка.
Вот лог нагрева и сбоя, кому интересно
Спойлер
Код:
hast=124986 hast0=104
hast=124986 hast0=102
hast=124986 hast0=104
hast=124986 hast0=102
hast=124986 hast0=103
hast=124986 hast0=102
hast=124986 hast0=101
hast=124986 hast0=102
hast=124986 hast0=104
hast=124986 hast0=117
hast=124986 hast0=134
hast=124986 hast0=156
hast=124986 hast0=181
hast=124986 hast0=150
hast=124986 hast0=239
hast=124986 hast0=17
hast=124986 hast0=172
hast=124987 hast0=80
hast=122688 hast0=90
hast=64791 hast0=214
hast=124986 hast0=214
hast=124986 hast0=197
hast=124986 hast0=182
hast=124986 hast0=171
hast=124986 hast0=164
hast=124986 hast0=157
hast=124986 hast0=151
hast=124986 hast0=149
hast=124986 hast0=146
hast=124986 hast0=142
hast=124986 hast0=139
hast=124986 hast0=134
hast=124986 hast0=131
hast=124986 hast0=127
hast=124986 hast0=129
hast=124986 hast0=126
hast=124986 hast0=124
hast=124986 hast0=124
hast=124986 hast0=124
hast=124986 hast0=117
hast=124986 hast0=121
hast=124986 hast0=122
hast=124986 hast0=119
hast=124986 hast0=121
hast=124986 hast0=119
hast=124986 hast0=119
hast=124986 hast0=119
hast=124986 hast0=119
hast=124986 hast0=92
hast=124986 hast0=124
hast=124986 hast0=134
hast=124986 hast0=130
hast=124986 hast0=128
hast=124986 hast0=127
hast=124986 hast0=124
hast=124986 hast0=122
hast=124986 hast0=123
hast=124986 hast0=117
hast=124986 hast0=119
hast=124986 hast0=116
hast=124986 hast0=119
hast=124986 hast0=117
hast=124986 hast0=114
hast=124986 hast0=116
hast=124986 hast0=114
hast=124986 hast0=112
hast=124986 hast0=114
hast=124986 hast0=112
hast=124986 hast0=113
hast=124986 hast0=112
hast=124986 hast0=111
hast=124986 hast0=114
hast=124986 hast0=109
hast=124986 hast0=112
hast=124986 hast0=114
hast=124986 hast0=112
hast=124986 hast0=111
hast=124986 hast0=111
hast=124986 hast0=112
hast=124986 hast0=111
hast=124986 hast0=109
hast=124986 hast0=109
hast=124986 hast0=109

Re: Калибровка встроенного RC-генератора

Чт окт 21, 2021 21:07:40

в протеусе частоты идеальные.
а в реальности кварцы имеют отклонение от номинала.
можно с достаточной уверенностью утверждать, что и в реальности мы теряем те же 3 импульса на частоте 16 МГц. поэтому я и сказал, что тремя импульсами можно пренебречь.
если измерять меньшую частоту, например, 1 МГц, то потерь вообще может не быть.
для интереса можешь у себя в протеусе это проверить, задав частоту МК 1 МГц.

Re: Калибровка встроенного RC-генератора

Чт окт 21, 2021 21:14:05

Starichok51 писал(а):если измерять меньшую частоту, например, 1 МГц, то потерь вообще может не быть.
Так же потери составляют, не хватает 2-3 импульса.

Re: Калибровка встроенного RC-генератора

Чт окт 21, 2021 21:15:04

а вообще-то, я про 1 МГц ерунду сказал.
между чтением счетчика Т0 и его сбросом пройдут те же 3 машинных цикла. те же 3 импульса потеряем.

Re: Калибровка встроенного RC-генератора

Пт окт 22, 2021 07:58:21

кстати, и простой расчет дает потерю 3 импульсов.
1. прочитали счетчик - счетчик стал +1.
2. загрузили регистр (например, R16) нулем - счетчик стал +2.
3. отправили в счетчик ноль - счетчик должен стать +3, а там оказался ноль.
вот эти +3 мы и теряем.

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

Re: Калибровка встроенного RC-генератора

Пт окт 22, 2021 08:41:21

Чтобы не мучаться с потерями в счетчике можно воспользоваться входом ICP1, на который подается эталонный период. Активным перепадом запоминается состояние T1 и очищается счетчик переполнений. Следующим активным перепадом значение ICR1 считывается, добавляется к счетчику переполнений. Вычитается начальное значение.

Re: Калибровка встроенного RC-генератора

Пт окт 22, 2021 09:32:20

нам не надо запоминать состояние Т1.
у нас считает счетчик Т0, и потери были при его сбросе в 0.

Re: Калибровка встроенного RC-генератора

Пт окт 22, 2021 09:51:02

akl, вот так сделал
Спойлер
Код:
ISR (TIMER1_OVF_vect)
{
   hast_t++;
}

ISR (TIMER1_CAPT_vect)
{   
   TCNT1=0; TIFR1 |= (1<<TOV1);
    hast0 = ICR1;
    ICR1 = 0;
   
    hast = hast_t;
    hast_t=0;
   flag1 =1;
}

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 16000,000 kHz
// Mode: Normal top=0xFFFF
// Noise Canceler: On
// Input Capture on Rising Edge
// Timer Period: 4,096 ms
// Timer1 Overflow Interrupt: On
// Input Capture Interrupt: On
TCCR1A=(0<<COM1A1) | (0<<COM1A0) | (0<<COM1B1) | (0<<COM1B0) | (0<<WGM11) | (0<<WGM10);
TCCR1B=(1<<ICNC1) | (1<<ICES1) | (0<<WGM13) | (0<<WGM12) | (0<<CS12) | (0<<CS11) | (1<<CS10);
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

// Timer/Counter 1 Interrupt(s) initialization
TIMSK1=(1<<ICIE1) | (0<<OCIE1B) | (0<<OCIE1A) | (1<<TOIE1);
Все равно не хватает.
Должно быть 244 переполнения и 9216
а получается 244 9192, не хватает 24

Re: Калибровка встроенного RC-генератора

Пт окт 22, 2021 11:32:30

с таймером1 тут другая проблема. и дело даже хуже, чем с таймером0.
от момента захвата (фиксации в регистре ICR1) до входа в прерывание проходит 7-8 машинных циклов.
плюс нужна добавка, о которой я сказал выше - учет выполнения сброса регистра TCNT1 в ноль.
я сделал себе проект в протеусе с таймером1.
мне пришлось записать в регистр TCNT1 число 10. только после этого я получил в захвате стабильно число 0х2400 = 9216.
а почему у тебя получилось потерять 24, пока не понятно.
скорее всего, это лишние потери времени при компиляции с языка Си.
а у меня сделано на ассемблере без лишних операций.
получился вот такой код:
Код:
.include "m8def.inc"   ; ATMega8

.def counter_ovf1   = R16

.cseg
.org 0
rjmp nachalo_code

.org ICP1addr
rjmp timer1_ICP

.org OVF1addr
rjmp timer1_OVF

nachalo_code:
ldi R26,  low(RAMEND)
out SPL, R26
ldi R26, high(RAMEND)
out SPH, R26

clr counter_ovf1

;--- Timer1 ---
ldi R26, (0<<COM1A1) | (0<<COM1A0) | (0<<COM1B1) | (0<<COM1B0) | (0<<WGM11) | (0<<WGM10)
out TCCR1A, R26
ldi R26, (1<<ICNC1) | (1<<ICES1) | (0<<WGM13) | (0<<WGM12) | (0<<CS12) | (0<<CS11) | (1<<CS10)
out TCCR1B, R26
ldi R26, (1<<TICIE1) | (0<<OCIE1B) | (0<<OCIE1A) | (1<<TOIE1)
out TIMSK, R26

sei

cycle:
rjmp cycle

timer1_ICP:
ldi R26, 0
out TCNT1H, R26
ldi R26, 10
out TCNT1L, R26
clr counter_ovf1
reti

timer1_OVF:
inc counter_ovf1
reti

Re: Калибровка встроенного RC-генератора

Пт окт 22, 2021 14:10:22

Спойлер
Код:
volatile uint16_t hast_t;
volatile uint16_t hast;
volatile uint16_t hast0;

volatile bool flag1;

ISR (TIMER1_OVF_vect)
{
   hast_t++;
}

ISR (TIMER1_CAPT_vect)
{ static uint16_t hast_temp;
   hast0 = ICR1 - hast_temp; hast_temp = ICR1;
   hast = hast_t;   hast_t=0;
   flag1 =1;
}
я получаю то что нужно, но иногда срабатывает лишнее прерывание
Код:
hast=244 hast0=9216
hast=244 hast0=9216
hast=244 hast0=9216
hast=244 hast0=9216
hast=244 hast0=9216
hast=245 hast0=9216
hast=244 hast0=9216
hast=244 hast0=9216
hast=244 hast0=9216
hast=244 hast0=9216
hast=244 hast0=9216
hast=244 hast0=9216
hast=245 hast0=9216
hast=244 hast0=9216
hast=244 hast0=9216
вставка этой строки TIFR1 |= (1<<TOV1) не на что не влияет.

Re: Калибровка встроенного RC-генератора

Пт окт 22, 2021 14:20:45

Dimon456 писал(а):вставка этой строки TIFR1 |= (1<<TOV1) не на что не влияет.
она и не должна повлиять.
в состоянии счетчика 9216 ни о каком переполнении во время захвата не может быть речи.

Re: Калибровка встроенного RC-генератора

Пт окт 22, 2021 14:23:35

Starichok51, ну ты же видишь
hast=244 hast0=9216
hast=245 hast0=9216
появляется с определенной периодичностью.

9216 получается разностью
Код:
hast0 = ICR1 - hast_temp; hast_temp = ICR1;

Ха, решил проблему
Спойлер
Код:
ISR (TIMER1_CAPT_vect)
{ static uint16_t hast_temp;

   if(hast_temp > ICR1) hast_t--;
   hast0 = ICR1 - hast_temp; hast_temp = ICR1;
   hast = hast_t;   hast_t=0;
   flag1 =1;

}
Я прогнал по всему диапазону, любую частоту подавал, идеально считает.
Ответить