Перейти к содержанию

Глюк С Таймером Atmega16


zeycon

Рекомендуемые сообщения

на вход ICP1 подаю импульсы с периодом 5000мкс

и пытаюсь измерить периоды каждого импульса

но таймер меряет 17 раз правильно потом 1 раз меньше на 255 мкс

и 1 раз больше на 255 мкс потом опять 13 раз правильно и цикл повторяется.

подскажите пожалуйста в чем прикол?

/*****************************************************
Chip type : ATmega16
Program type : Application
AVR Core Clock frequency: 8,000000 MHz
*****************************************************/

#include <mega16.h>

char ch[10];
unsigned int val=0;
unsigned int last_val=0;
unsigned int buf=0;


// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 1000,000 kHz
// Mode: Normal top=0xFFFF
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer1 Overflow Interrupt: Off
// Input Capture Interrupt: On
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x02;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

// Timer1 input capture interrupt service routine
interrupt [TIM1_CAPT] void timer1_capt_isr(void)
{
val=ICR1H<<8|ICR1L;
buf=val-last_val;
ltoa(buf,ch);
puts(ch);
putsf("\r\n");
last_val=val;
}

вот что выводиться на терминал

5133
5133
5133
5133
5134
5133
5133
5133
5133
5133
5133
5133
5133
5133
5133
5133
5133
4877
5389
5133
5133
5133
5132
5133
5133
5133
5133
5133
5133
5133
5133
5133
5133
5133
5132
5133
5133
4877
5389
5133
5133
5133
5133
5133
5133
5133
5133
5133
5133
5133
5133
5133
5134
5133
5133
5133
5133
4876
5389
5134
5133
5133
5133
5133
5133
5133
5133
5133
5133
5133
5133
5133
5133
5133
5133
5134
4877
5389
5133
5133
5133
5133
5133
5133
5133
5133
5133
5133
5133
5133
5134
5133
5133
5133
5133
5133
4877
5389
5133
5133
5133
5133
5133
5133
5133
5133
5133
5133
5133
5133
5133
5133
5133
5133
5133
5133
4877
5389
5133
5133
5133
5133
5133
5133
5133
5133
5133
5133
5133
5133
5133
5133
5133
5133
5133
4877
5389
5133
5133
5134
5133
5133
5132
5133
5133
5133
5133
5133
5133
5133
5133
5133
5133
5133
5133
4877
5389
5133
5133
5133
5133
5133
5133
5133
5134
5133
5133
5133
5133
5134
5133
5133
5133
5133
5133
4877
5389
5133
5133
5133
5133
5133
5133
5133
5133
5133
5133
5133
5133
5133
5133
5133
5133
5133
4877
5389
5133
5133
5133
5133
5133
5133
5133
5133
5133
5133
5133
5133
5133
5133
5133
5133
5133
5133
4877
5389
5133
5133
5133
5133
5133
5133
5133
5133
5133
5133
5133
5133
5133
5133
5133
5133
5133
5133

а ведь все цифры должны быть почти одинаковы 5133 (ну плюс минус 1 погрешгость)

если тебя ударили по левой щеке — подставь правую... руку и с разворота бей ногой в челюсть

Ссылка на комментарий
Поделиться на другие сайты

Реклама: ООО ТД Промэлектроника, ИНН: 6659197470, Тел: 8 (800) 1000-321

Попробуй увеличить частоту работы кристалла. По моему 16 МГц она потянет.

Изменено пользователем Gramlin1

Главное иметь тех, которые имеют тех, которые имеют нас.

Ссылка на комментарий
Поделиться на другие сайты

20% скидка на весь каталог электронных компонентов в ТМ Электроникс!

Акция "Лето ближе - цены ниже", успей сделать выгодные покупки!

Плюс весь апрель действует скидка 10% по промокоду APREL24 + 15% кэшбэк и бесплатная доставка!

Перейти на страницу акции

Реклама: ООО ТМ ЭЛЕКТРОНИКС, ИНН: 7806548420, info@tmelectronics.ru, +7(812)4094849

увеличил до 16МГц

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

(откуда то периодично добавляеться и вычитывается 255, что за фигня)

9697
9953
9953
9953
9953
9953
9954
10209
9697
9953
9953
9953
9953
9953
9953
10209
9697
9953
9954
9953
9953
9953
9953
10209
9697
9953
9953
9953
9953
9953
9953
9953
10209
9697
9953
9953
9953
9953
9953
9953
10210
9697
9953
9953
9953
9953
9953
9953
10209
9697
9953
9953
9954
9953
9953
9953
9953
10209
9697
9953
9953
9952
9953
9953
9953
10209
9697
9953
9954
9953
9953
9953
9953

ЗЫ

источник входных импульсов тактируеться от RC генератора поэтому импульсы не ровно 5000мкс

Изменено пользователем zeycon

если тебя ударили по левой щеке — подставь правую... руку и с разворота бей ногой в челюсть

Ссылка на комментарий
Поделиться на другие сайты

Выбираем схему BMS для корректной работы литий-железофосфатных (LiFePO4) аккумуляторов

 Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ, также как и для других, очень важен контроль процесса заряда и разряда, а специализированных микросхем для этого вида аккумуляторов не так много. Инженеры КОМПЭЛ подготовили список имеющихся микросхем и возможных решений от разных производителей. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

Это похоже на глюк кристалла. Попробуй другой МК.

Или усредняй показания.

Например Х это наши показания.

Складывай 10 Х подряд, а потом это значение дели на 10.

Получишь в среднем правильный результат.

Изменено пользователем Gramlin1

Главное иметь тех, которые имеют тех, которые имеют нас.

Ссылка на комментарий
Поделиться на другие сайты

Это похоже на глюк кристалла. Попробуй другой МК.

поменял МК, ничего не изменилось, никакой это ни глюк кристалла, они редко бывают забракованы (почти никогда)

Или усредняй показания.

Например Х это наши показания.

Складывай 10 Х подряд, а потом это значение дели на 10.

Получишь в среднем правильный результат.

мне нужно мерить длительность каждого импульса.

Я не частотомер делаю, а логический анализатор!

если тебя ударили по левой щеке — подставь правую... руку и с разворота бей ногой в челюсть

Ссылка на комментарий
Поделиться на другие сайты

Как-то нехорошо дёргать UART в прерывании таймера.

Вынесите работу с ним в главный цикл, а прерывание пусть кладёт данные в какой-то буфер ....

Изменено пользователем hd44780
Ссылка на комментарий
Поделиться на другие сайты

это я знаю, но к делу это не имеет отношение.

бодрейт выставил максимально (115200) всего пару символов выплевывает, за рамки 5000мкс

точно не выходит !

Изменено пользователем zeycon

если тебя ударили по левой щеке — подставь правую... руку и с разворота бей ногой в челюсть

Ссылка на комментарий
Поделиться на другие сайты

может он синхронно определяет фронт импульса а в некоторые периоды не успевает?

Ругался на отсутствие форматирования исходного кода (включая отсутствие осмысленных комментариев и наличие неубранного после конфигуратора мусора) не менее 15 раз.

Часть моих наработок.

Ссылка на комментарий
Поделиться на другие сайты

Организуйте программу правильно и все пройдет. Итоа, путсам и прочим не место в обработчике. Только val и флаг.. И предусмотрите некий аналог критических секций.

Любой, заслуживающий внимания, опыт приобретается себе в убыток...

Ссылка на комментарий
Поделиться на другие сайты

Уважаемый Goodefine,

организовал программу "правильно" но ситуация от этого совсем не изменилась...

/*****************************************************
Chip type : ATmega16
Program type : Application
AVR Core Clock frequency: 8,000000 MHz
*****************************************************/

#include <mega16.h>

#define BUFFER_SIZE 64
unsigned int buffer[bUFFER_SIZE];

#if BUFFER_SIZE <= 256
unsigned char wr_index,rd_index,counter;
#else
unsigned int wr_index,rd_index,counter;
#endif

bit buffer_overflow;

char ch[10];
unsigned int val=0;
unsigned int last_val=0;
unsigned int buf=0;
unsigned int tmp=0;


// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 1000,000 kHz
// Mode: Normal top=0xFFFF
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer1 Overflow Interrupt: Off
// Input Capture Interrupt: On
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x02;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

// Timer1 input capture interrupt service routine
interrupt [TIM1_CAPT] void timer1_capt_isr(void)
{
#asm("cli")
val=ICR1H<<8|ICR1L;
buf=val-last_val;
buffer[wr_index++]=buf;
#if BUFFER_SIZE == 256
if (++counter == 0)
{
#else
if (wr_index == BUFFER_SIZE) wr_index=0;
if (++counter == BUFFER_SIZE)
{
counter=0;
#endif
buffer_overflow=1;
}

last_val=val;
#asm("sei")
}

unsigned int getdata(void)
{
unsigned int data;
while (counter==0);
data=buffer[rd_index++];
#if BUFFER_SIZE != 256
if (rd_index == BUFFER_SIZE) rd_index=0;
#endif
#asm("cli")
--counter;
#asm("sei")
return data;
}


while (1)
{
if(counter)
{
tmp=getdata();
ltoa(tmp,ch);
puts(ch);
putsf("\r\n");
}
}

результат

9692
9948
9948
9948
9948
9948
9948
10204
9692
9948
9948
9948
9948
9948
10204
9692
9948
9948
9947
9949
9948
10203
9692
9948
9948
9948
9948
9948
10204
9692
9948
9948
9948
9948
9947
10204
9693
9947
9948
9948
9949
9948
10203
9693
9948
9948
9948
9948
9948
10204
9692
9948
9948
9948
9948
9948
10204
9692
9947
9948
9948
9948
9948
10204
9692
9948
9948
9948
9948
9948

Изменено пользователем zeycon

если тебя ударили по левой щеке — подставь правую... руку и с разворота бей ногой в челюсть

Ссылка на комментарий
Поделиться на другие сайты

Лишнюю часть вырезал (инклуды и инициализация остальной периферии).

кстати в протеусе тоже самое твориться

9744
10256
10000
10000
10000
10000
10000
10000
10000
10000
10000
10000
10000
10000
10000
10000
9744
10256
10000
10000
10000
10000
10000
10000
10000
10000
10000
10000
10000
10000
10000
10000
9744
10256
10000
10000
10000
10000
10000
10000
10000
10000
10000
10000
10000
10000
10000
10000
9744
10256

Изменено пользователем zeycon

если тебя ударили по левой щеке — подставь правую... руку и с разворота бей ногой в челюсть

Ссылка на комментарий
Поделиться на другие сайты

вотtimer_glyuk.rar

Изменено пользователем zeycon

если тебя ударили по левой щеке — подставь правую... руку и с разворота бей ногой в челюсть

Ссылка на комментарий
Поделиться на другие сайты

неужели никто не знает в чем может быть косяк ?

если тебя ударили по левой щеке — подставь правую... руку и с разворота бей ногой в челюсть

Ссылка на комментарий
Поделиться на другие сайты

Да проблему то вы создали на ровном месте. Иногда нужно и даташит читать. Объясняю - регистр захвата физически состоит из двух регистров, которые надо считывать в определенном порядке: сначала младший, потом старший. Ваша запись:

val=ICR1H<<8|ICR1L;

не дает однозначного задания последовательности считывания регистров компилятору. Поэтому периодически (оптимизация) происходило считывание в неправильном порядке. В первом измерении байт терялся (256), а во втором он прибавлялся. Например, минимальный код:

/*****************************************************
Chip type			   : ATmega16
Program type		    : Application
AVR Core Clock frequency: 8,000000 MHz
*****************************************************/
#include <mega16.h>
#include <delay.h>
#include <stdlib.h>
#include <stdio.h>
unsigned char ch[10];
volatile unsigned int val=0;
volatile unsigned int last_val=0;
volatile unsigned int buf=0;
unsigned char fl_izm=0;
// Timer1 input capture interrupt service routine
interrupt [TIM1_CAPT] void timer1_capt_isr(void)
{
val=ICR1H<<8|ICR1L;
buf=(val-last_val);
last_val=val;
fl_izm=1;
}
void main(void)
{
// Port D initialization
PORTD=0xFF;
DDRD=0x02;
// Timer/Counter 1 initialization
TCCR1B=0x02;
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x20;
// USART initialization
UCSRA=0x00;
UCSRB=0x08;
UCSRC=0x86;
UBRRH=0x00;
UBRRL=0x08;
// Analog Comparator initialization
ACSR=0x80;
SFIOR=0x00;
// Global enable interrupts
#asm("sei")
while (1)
  { 
	 if(fl_izm) 
	 {  //#asm("cli")
	    ltoa(buf,ch);
	    //#asm("sei")
	    puts(ch);
	    putsf("\r\n");
	    fl_izm=0;
	 }					
  }
}

Дает примерно такое:

250

8720

10256

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

9744

10256

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

9744

10256

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

9744

10256

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

9744

10256

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

Но стоит в обработчике однозначно указать последовательность считывания регистров:

// Timer1 input capture interrupt service routine
interrupt [TIM1_CAPT] void timer1_capt_isr(void)
{
val=ICR1L;
val|=(ICR1H<<8);
buf=(val-last_val);
last_val=val;
fl_izm=1;
}

И, вуаля:

9210

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

10000

Вот такие-вот грабельки ))) ...

Изменено пользователем Goodefine

Любой, заслуживающий внимания, опыт приобретается себе в убыток...

Ссылка на комментарий
Поделиться на другие сайты

спасибо,

честно говоря я уже догадался сразу после написания поста №15 когда отчаяно читал даташит.

но уже инета небыло чтоб высказатся об этом ;)

Изменено пользователем zeycon

если тебя ударили по левой щеке — подставь правую... руку и с разворота бей ногой в челюсть

Ссылка на комментарий
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Ответить в этой теме...

×   Вставлено с форматированием.   Восстановить форматирование

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

Загрузка...
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
×
×
  • Создать...