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

Глюк С Таймером 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 погрешгость)

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

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

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

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

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

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

увеличил до 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

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

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

Сравнительное тестирование аккумуляторов EVE Energy и Samsung типоразмера 18650

Инженеры КОМПЭЛ провели сравнительное тестирование аккумуляторов EVE и Samsung популярного для бытовых и индустриальных применений типоразмера 18650. 

Для теста были выбраны аккумуляторы литий-никельмарганцевой системы: по два образца одного наименования каждого производителя – и протестированы на двух значениях тока разряда: 0,5 А и 2,5 А. Испытания проводились в нормальных условиях на электронной нагрузке EBD-USB от ZKEtech, а зарядка осуществлялась от лабораторного источника питания в режиме CC+CV в соответствии с рекомендациями в даташите на определенную модель. Подробнее>>

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

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

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

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

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

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

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

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

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

Новый аккумулятор EVE серии PLM для GSM-трекеров, работающих в жёстких условиях (до -40°С)

Компания EVE выпустила новый аккумулятор серии PLM, сочетающий в себе высокую безопасность, длительный срок службы, широкий температурный диапазон и высокую токоотдачу даже при отрицательной температуре. 

Эти аккумуляторы поддерживают заряд при температуре от -40/-20°С (сниженным значением тока), безопасны (не воспламеняются и не взрываются) при механическом повреждении (протыкание и сдавливание), устойчивы к вибрации. Они могут применяться как для автотранспорта (трекеры, маячки, сигнализация), так и для промышленных устройств мониторинга, IoT-устройств. Подробнее параметры и результаты тестов новой серии PLM по ссылке.

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

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

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

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

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

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

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

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

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

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

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

Литиевые батарейки и аккумуляторы от мирового лидера  EVE в Компэл

Компания Компэл, официальный дистрибьютор EVE Energy, бренда №1 по производству химических источников тока (ХИТ) в мире, предлагает продукцию EVE как со склада, так и под заказ. Компания EVE широко известна в странах Европы, Америки и Юго-Восточной Азии уже более 20 лет. Недавно EVE была объявлена поставщиком новых аккумуляторных элементов круглого формата для электрических моделей «нового класса» компании BMW.

Продукция EVE предназначена для самого широкого спектра применений – от бытового до промышленного. Подробнее>>

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

Как-то нехорошо дёргать 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 пользователей онлайн

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