Грабли с граббером сигнала на Atmega8

Обсуждаем контроллеры компании Atmel.
Ответить
alexparser
Родился
Сообщения: 9
Зарегистрирован: Пн апр 15, 2013 00:34:04

Грабли с граббером сигнала на Atmega8

Сообщение alexparser »

Доброго дня!

Есть линия по которой передается цифровой сигнал (данные в HEX), логическая 1 первые 3/4 периода +5V, вторые 1/4 0V. Период составляет 1/4 ms.
Имею тестовый код, который должен вести подсчет возрастающих фронтов.
Проблема в том, что код не успевает корректно считать.
Вместо 10 фронтов на выходе получаю 1.
Камень Atmega8A бегает на 16 мегагерц (фьюзы выставлены правильно, питание +5V).
Вывод результата в UART делаю по таймеру раз в ~2 сек.

Вопрос - почему код не успевает обрабатывать фронты?

Код: Выделить всё

for(;;){
while ((PINB & (1<<0))==0); // ждем передний фронт
while (PINB & (1<<0)); // ждем задний фронт
frontCount++;
}
Реклама
Аватара пользователя
ИС-пытатель
Вымогатель припоя
Сообщения: 577
Зарегистрирован: Ср июн 19, 2013 08:10:48
Откуда: Москва, СПб, Липецк, Рязань

Re: Грабли с граббером сигнала на Atmega8

Сообщение ИС-пытатель »

А расскажите, пожалуйста, в цикле for у Вас какое условие выполнения или выхода?
Реклама
alexparser
Родился
Сообщения: 9
Зарегистрирован: Пн апр 15, 2013 00:34:04

Re: Грабли с граббером сигнала на Atmega8

Сообщение alexparser »

ИС-пытатель писал(а):А расскажите, пожалуйста, в цикле for у Вас какое условие выполнения или выхода?
Нет условия для выхода, как видно из кода это вечный цикл.
Вывод результата в UART делаю по таймеру раз в ~2 сек. и после вывода обнуляю счетчик.
Аватара пользователя
ИС-пытатель
Вымогатель припоя
Сообщения: 577
Зарегистрирован: Ср июн 19, 2013 08:10:48
Откуда: Москва, СПб, Липецк, Рязань

Re: Грабли с граббером сигнала на Atmega8

Сообщение ИС-пытатель »

А если вечный цикл так обозначить:

Код: Выделить всё

while (1)
{
}
Это решит проблему?

Покажите весь код, плиз! )
Реклама
Эиком - электронные компоненты и радиодетали
uk8amk
Поставщик валерьянки для Кота
Сообщения: 2222
Зарегистрирован: Вт ноя 27, 2007 11:32:06
Откуда: Tashkent

Re: Грабли с граббером сигнала на Atmega8

Сообщение uk8amk »

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

Касательно вашей программы - косяк где-то в том коде, который вы не показываете.
Реклама
alexparser
Родился
Сообщения: 9
Зарегистрирован: Пн апр 15, 2013 00:34:04

Re: Грабли с граббером сигнала на Atmega8

Сообщение alexparser »

uk8amk писал(а):Касательно вашей программы - косяк где-то в том коде, который вы не показываете.
Выкладываю код, он конечно далек от идеала, но явного косяка я не нахожу.

Код: Выделить всё

#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <stdlib.h>

#define SPEED 9600
volatile unsigned int front_cnt = 0;

void serial_init(unsigned int bittimer)
{

	// set baud rate
	UBRRH = (unsigned char) (bittimer >> 8);
	UBRRL = (unsigned char) bittimer;	
	// set the framing to 8N1
	UCSRC = (1 << URSEL) | (1 << USBS) | (3 << UCSZ0);
	// enable transmitter
	UCSRB = (1 << TXEN);	
	return;
}

void serial_write(unsigned char c)
{
	while ( !(UCSRA & (1 << UDRE)) );
	UDR = c;
	return;
}

void serial_write_str(char *s)
{
	for(unsigned int i=0; i<strlen(s); i++)
	{
		serial_write(s[i]);
	}
	return;
}

void send_timer_reset(unsigned int val)
{
	char s[50];
	sprintf(&s,"front counts: %u \r\n", front_cnt); 
	serial_write_str(&s[0]);
	return;
}

ISR(TIMER1_OVF_vect)
{
	send_timer_reset(0);
	front_cnt = 0;
	return;
}

void timer_init(void)
{
	TCCR1B = (1<<CS12) | (0<<CS11) | (1<<CS10); // divider
	TIMSK = (1<<TOIE1); // interrupt if overload
	TCNT1 = 0; // start value
	sei();
	return;
}

void io_init(void)
{
	// input pin
	DDRB &=!_BV(0);
	PORTB&=!_BV(0);
	return;
}

// *******************************************************************************
//    main 
// *******************************************************************************

int main(void)
{
	io_init();
	serial_init( F_CPU/16/SPEED-1 );
	timer_init();

	while(1)
	{
		while ((PINB & (1<<0))==0); // ждем передний фронт
		while (PINB & (1<<0)); // ждем задний фронт
		front_cnt++;
		TCNT1 = 0;
	}
	
	return 0;
}
Реклама
uk8amk
Поставщик валерьянки для Кота
Сообщения: 2222
Зарегистрирован: Вт ноя 27, 2007 11:32:06
Откуда: Tashkent

Re: Грабли с граббером сигнала на Atmega8

Сообщение uk8amk »

Код: Выделить всё

   while(1)
   {
      while ((PINB & (1<<0))==0); // ждем передний фронт
      while (PINB & (1<<0)); // ждем задний фронт
      front_cnt++;
      TCNT1 = 0;  <<<<<<<<--- вот это зачем?
   }
Аватара пользователя
ИС-пытатель
Вымогатель припоя
Сообщения: 577
Зарегистрирован: Ср июн 19, 2013 08:10:48
Откуда: Москва, СПб, Липецк, Рязань

Re: Грабли с граббером сигнала на Atmega8

Сообщение ИС-пытатель »

И еще косяк:

Код: Выделить всё

void io_init(void)
{
   // input pin
   DDRB &=!_BV(0);
   PORTB&=!_BV(0);
   return;
}
Не совсем так. Это вот так обозначается:

Код: Выделить всё

void io_init(void)
{
   // input pin
   DDRB &=~_BV(0);
   PORTB&=~_BV(0);
   return;
}
alexparser
Родился
Сообщения: 9
Зарегистрирован: Пн апр 15, 2013 00:34:04

Re: Грабли с граббером сигнала на Atmega8

Сообщение alexparser »

uk8amk писал(а):

Код: Выделить всё

   while(1)
   {
      TCNT1 = 0;  <<<<<<<<--- вот это зачем?
   }
Чтобы во время приема сигнала не сработал таймер, обнуляем его.

Код: Выделить всё

void io_init(void)
{
   // input pin
   DDRB &=~_BV(0);
   PORTB&=~_BV(0);
   return;
}
Подправил этот кусок кода, но оно никак не повлияло.
Аватара пользователя
ИС-пытатель
Вымогатель припоя
Сообщения: 577
Зарегистрирован: Ср июн 19, 2013 08:10:48
Откуда: Москва, СПб, Липецк, Рязань

Re: Грабли с граббером сигнала на Atmega8

Сообщение ИС-пытатель »

А это и не должно было повлиять.

Сторожевой таймер отключите.
uk8amk
Поставщик валерьянки для Кота
Сообщения: 2222
Зарегистрирован: Вт ноя 27, 2007 11:32:06
Откуда: Tashkent

Re: Грабли с граббером сигнала на Atmega8

Сообщение uk8amk »

Таймер и не сработает если у вас интервал между посылками короткий.
Тактирование=16MHz/1024=15625Hz
Переполнение=15625/65536=0.23Гц => 4.3 сек
Не многовато ли?

На всякий случай уберите обнуление таймера в цикле. Убедитесь что хоть как-то оно считает.
Аватара пользователя
ИС-пытатель
Вымогатель припоя
Сообщения: 577
Зарегистрирован: Ср июн 19, 2013 08:10:48
Откуда: Москва, СПб, Липецк, Рязань

Re: Грабли с граббером сигнала на Atmega8

Сообщение ИС-пытатель »

У него по идее таймер должен сработать через 4 секунды после прихода последнего импульса и отправить количество импульсов
alexparser
Родился
Сообщения: 9
Зарегистрирован: Пн апр 15, 2013 00:34:04

Re: Грабли с граббером сигнала на Atmega8

Сообщение alexparser »

Привет братья по разуму!
Был в командировке :beer: , вернулся и пересмотрел все свежим взглядом и о эврика обнаружились грабли, те на которые я так долго наступал, но в упор не видел.
Короче, трабла крылась не в софтверной а в хардверной части.
Перед ногой МК стоял медленный диод. :kill:
Zhevagin
Родился
Сообщения: 9
Зарегистрирован: Чт июн 05, 2014 22:09:46

Re: Грабли с граббером сигнала на Atmega8

Сообщение Zhevagin »

Настолько медленный, что даже импульс длительностью в несколько миллисекунд не открывал его? Может там падение напряжения на диоде сказывалось?
Ответить

Вернуться в «AVR»