Измерение частоты T1 и пара вопросв)

Обсуждаем контроллеры компании Atmel.
Ответить
Встал на лапы
Сообщения: 146
Зарегистрирован: Вс сен 16, 2012 22:00:40

Сообщение foton6 »

Вообщем на меге 8 хочу собрать что-то типо круиз контроля.
Обороты двигателя думаю брать с генератора(выдает прямоугольники).
Вот накатал заготовочку но не пойму почему не работает.
Спойлер

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

/*
 * exp_mega8.c
 *
 * Created: 15.07.2013 10:22:54
 *  Author: foton6
 */ 
#define F_CPU 4000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <stdio.h>
 unsigned short int a=0;
 int k;
void init (void)
{
///////////________UASRT________/////////////
	UCSRB|=0x18;
	UCSRC|=0x83;
	UBRRL=25;
//////////___Timer 1-counter___/////////////	
TCCR1B|=0x06;
/////////____Timer 0-timer____/////////////
TCCR0|=0x05;
TIMSK|=0x01;
/////////______////////////
DDRC=0x08;
}
void send (void)
{
	char buff[250]={0};
	char *out=itoa(a,buff,10);
	while(k>0)
	{
		k--;
		UDR=0x08;
	}
	while(*out)
	{
		k++;
		if( UCSRA & (1<<UDRE))
		{
			UDR=*out++;
		}
	}
}
int main(void)
{
init();
while(1)
{
	send();
	_delay_ms(500);	
}
}
ICR(TIMER0_OVF_vect)
{
	int e=0;
	e=TCNT1L;
	a=TCNT1H;
	a<<=4;
	a|=e;
	TCNT1L=0x00;
	TCNT1H=0x00;
	PORTC^=0x08;
}

В данном варианте он в прерывание не входит, не пойму никак почему не входит.

Перетаскивал в "мейн" этот кусок:

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

	int e=0;
	e=TCNT1L;
	a=TCNT1H;
	a<<=4;
	a|=e;
Досчитывает только до 255 и дальше глюки прут, хотя по идее это же 16 бит...

Подскажите в чем тут дело?
И может есть более рациональные способы мерить частоту?
О и в плане "говно кода" нормально ли оформлено? и что считается плохим тоном в программировании? )))))
Реклама
Друг Кота
Аватара пользователя
Сообщения: 7016
Зарегистрирован: Вс июл 12, 2009 19:15:29
Откуда: Ижевск

Сообщение pyzhman »

Ткните мне пальцем в место, где разрешаются прерывания.
что-то типо круиз контроля
Упаси меня...(извиняйте за офф)
Docendo discimus
Контактная информация:
Реклама
Встал на лапы
Сообщения: 146
Зарегистрирован: Вс сен 16, 2012 22:00:40

Сообщение foton6 »

Вот я валенок)
вместо ISR написал ICR вот и не входило в прерывания))))
А пишет всякую охинею потому что сдвигал на 4 биты а не на 8 ))))
Я болдею со своей глупости и невнимательности))))
Вроде частоту норм считает, пока ток в протусе моделирую.

Но появилась новая трабла ^^ :
перед выводом цифр все стираю командой backspace (0x08 посылаю в UDR).
Спойлер

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

void send (void)
{
   char buff[250]={0};
   char *out=itoa(a,buff,10);
   while(k>0)
   {
      k--;
       if( UCSRA & (1<<UDRE))
      UDR=0x08;
   }
   while(*out)
   {
      k++;
      if( UCSRA & (1<<UDRE))
      {
         UDR=*out++;
      }
   }
}
Пока число 4-ёх значное все отл.
При появлении 5 символа он его не стирает (
к примеру 10523, то выходит такая фигня:
10523 >>> 110524 >>> 1110525 и с каждым тиком число единиц возрастает.

И все еще актуален вопрос по более продуктивному-эффективному подсчету частоты.
Так же актуален вопрос в плане оценки опрятности и адекватности написанного кода)
Встал на лапы
Сообщения: 146
Зарегистрирован: Вс сен 16, 2012 22:00:40

Сообщение foton6 »

pyzhman писал(а):Ткните мне пальцем в место, где разрешаются прерывания.
что-то типо круиз контроля
Упаси меня...(извиняйте за офф)
Да по поводу прерываний тут я затер случайно перед тем как выкладывать)
А в первоначальном виде нельзя было выкладывать, ибо там было столько левого го**а. (типо мигания светодиодами для отслеживания хода программы^^)
Вообщем как говорится: "утро вечера....."
Заработали все прерывания, выше отписал что и как.

Что за "упаси меня" это только кусочек, да и я еще учусь)))
Дальше еще подвязать по SPI ЦАП, включить АЦП 2 штуки)
по UART менять переменные для отладки.
Опрос кнопок и соответствующие события)
Поддержка оборотов в определенных границах)
Реклама
Эиком - электронные компоненты и радиодетали
Встал на лапы
Сообщения: 146
Зарегистрирован: Вс сен 16, 2012 22:00:40

Сообщение foton6 »

ААА извиняюсь за много постов, но это все мая тупость и рассеяность. Все проблемы решил:
Спойлер

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

void send (void)
{
	char buff[250]={0};
	char *out=itoa(a,buff,16);
	while(k)
	{
		if( UCSRA & (1<<UDRE))
		{
			UDR=0x08;
			k--;
		}
	}
	while(*out)
	{
		
		if( UCSRA & (1<<UDRE))
		{
			UDR=*out++;
			k++;
		}
	}
	_delay_ms(100);
}
Просто забыл что готовность UART'а это ни 1 "тик" ,а k-- делал каждый тик почти, соответственно k уходил в 0 раньше чем успевал послать нужное кол-во стираний)))))))

Спойлер

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

/*
 * exp_mega8.c
 *
 * Created: 15.07.2013 10:22:54
 *  Author: foton6
 */ 
#define F_CPU 4000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <stdio.h>
 unsigned short int a=0;
 int k;
void init (void)
{
///////////________UASRT________/////////////
	UCSRB|=0x18;
	UCSRC|=0x83;
	UBRRL=25;
//////////___Timer 1-counter___/////////////	
TCCR1B|=0x06;
/////////____Timer 0-timer____/////////////
TCCR0|=0x05;
TIMSK|=0x01;
/////////______////////////
DDRC=0x08;
}
void send (void)
{
	char buff[250]={0};
	char *out=itoa(a,buff,10);
	while(k)
	{
		if( UCSRA & (1<<UDRE))
		{
			UDR=0x08;
			k--;
		}
	}
	while(*out)
	{
		
		if( UCSRA & (1<<UDRE))
		{
			UDR=*out++;
			k++;
		}
	}
	_delay_ms(100);
}
int main(void)
{
init();
while(1)
{
	sei();

	send();
}
}
ISR(TIMER0_OVF_vect)
{
	int e=0;
	e=TCNT1L;
	a=TCNT1H;
	a<<=8;
	a|=e;
	TCNT1H=0x00;
	TCNT1L=0x00;
}


Вроде работает причем точность радует) думал скакать будет +/-20 при 10000 с лишним тиках, ан нет почти не дергается,
точнее периодически на 1 больше скакнет и все ))))

Выслушаю замечания и советы, точнее очень нуждаюсь в этом)
Реклама
Опытный кот
Сообщения: 804
Зарегистрирован: Чт мар 12, 2009 16:31:05

Сообщение Vov123 »

А в России есть дороги,чтобы пользоваться круиз контролем?
У меня на машине стоит штатный,я его ни разу не включал.
Реклама
Встал на лапы
Сообщения: 146
Зарегистрирован: Вс сен 16, 2012 22:00:40

Сообщение foton6 »

Vov123 писал(а):А в России есть дороги,чтобы пользоваться круиз контролем?
У меня на машине стоит штатный,я его ни разу не включал.
Это не круиз контроль) а его аналог по некоторым функциям)
Опытный кот
Сообщения: 804
Зарегистрирован: Чт мар 12, 2009 16:31:05

Сообщение Vov123 »

А вот этим

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

void send (void)
{
   char buff[250]={0};
что хотел сделать?
Установить первый элемент массива в ноль или "типо" очистить массив полностью?
Друг Кота
Аватара пользователя
Сообщения: 7016
Зарегистрирован: Вс июл 12, 2009 19:15:29
Откуда: Ижевск

Сообщение pyzhman »

foton6 писал(а):аналог по некоторым функциям
О, так у меня приборка, оказывается, на самом-то деле - круиз-контроль! Буду пацанам теперь хвастать! :)) (Еще раз простите за офф.)
Docendo discimus
Контактная информация:
Встал на лапы
Сообщения: 146
Зарегистрирован: Вс сен 16, 2012 22:00:40

Сообщение foton6 »

Vov123 писал(а):А вот этим

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

void send (void)
{
   char buff[250]={0};
что хотел сделать?
Установить первый элемент массива в ноль или "типо" очистить массив полностью?
Просто нулями забил массив) хотя стал сомневаться в правильности записи.
Опытный кот
Сообщения: 804
Зарегистрирован: Чт мар 12, 2009 16:31:05

Сообщение Vov123 »

Сомневаться - это уже хорошо.Для очистки буфера можно использовать цикл for(.... обнуляя каждый элемент массива,а можно использовать функцию memset(... .На скорость,я думаю это не влияет.Хотя,возможно,потребуется подкорректировать (в случае использования memset)настройки компилятора,если будет брыкаться,в разделе "куча"(heap).
Встал на лапы
Сообщения: 146
Зарегистрирован: Вс сен 16, 2012 22:00:40

Сообщение foton6 »

Vov123 писал(а):Сомневаться - это уже хорошо.Для очистки буфера можно использовать цикл for(.... обнуляя каждый элемент массива,а можно использовать функцию memset(... .На скорость,я думаю это не влияет.Хотя,возможно,потребуется подкорректировать (в случае использования memset)настройки компилятора,если будет брыкаться,в разделе "куча"(heap).
Все норм)

так как сделал я можно при обьявлении массива)
Я просто обьявил массив с "0-вым" содержанием)
А "ваши" способы уже походу программы надо юзать так как данная запись char buff[250]={0} будет ноль присваивать только первому элементу, а при обьявлении все забивает. .
Опытный кот
Сообщения: 804
Зарегистрирован: Чт мар 12, 2009 16:31:05

Сообщение Vov123 »

Забивает,это когда объявляется глобально,а когда локально,то только с мусором.
Встал на лапы
Сообщения: 146
Зарегистрирован: Вс сен 16, 2012 22:00:40

Сообщение foton6 »

Vov123 писал(а):Забивает,это когда объявляется глобально,а когда локально,то только с мусором.
Ну у меня все ок работает)
Встал на лапы
Сообщения: 146
Зарегистрирован: Вс сен 16, 2012 22:00:40

Сообщение foton6 »

Подскажите пожалуйста что не так написано:
Спойлер

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

#define F_CPU 4000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <stdio.h>
 unsigned short int a=0;
 int k;
void init (void)
{
///////////________USART________/////////////
	UCSRB|=0x18;
	UCSRC|=0x83;
	UBRRL=25;
//////////___Timer 1-counter___/////////////	
TCCR1B|=0x06;
/////////____Timer 2-timer____/////////////
TCCR1B=0x05;
TIMSK|=0x80;
OCR2=195; ///__0,05 сек.
/////////______////////////
}
void send (void)
{
	char buff[250]={0};
	char *out=itoa(a,buff,10);
	while(k)
	{
		if( UCSRA & (1<<UDRE))
		{
			UDR=0x08;
			k--;
		}
	}
	while(*out)
	{
		
		if( UCSRA & (1<<UDRE))
		{
			UDR=*out++;
			k++;
		}
	}
	_delay_ms(100);
}
int main(void)
{
init();
while(1)
{
	sei();
	send();
}
}
ISR(TIMER2_COMP_vect)
{
	int e=0;
	e=TCNT1L;
	a=TCNT1H;
	a<<=8;
	a|=e;
	TCNT1H=0x00;
	TCNT1L=0x00;
}
к T1 подключен тактовый генератор.
Программа должна выдавать число импульсов за 0,05с по USART.
Данный код работал кода я использовал T0 по переполнению.
Как перешел на Т2 , все...
При компиляции только предупреждения по поводу этой строки: char *out=itoa(a,buff,10);
При работе на дисплее только "0" печатает. Значит не уходит в обработчик прерываний.
YS
Друг Кота
Аватара пользователя
Сообщения: 7518
Зарегистрирован: Вс мар 29, 2009 22:09:05

Сообщение YS »

что считается плохим тоном в программировании?

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

unsigned short int a=0;
int k;
Лучше использовать типы из stdint.h

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

uint16_t a=0;
int32_t k;
Размер int зависит от архитектуры. На AVR, например, int имеет размер два байта...

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

UCSRB|=0x18;
Лучше использовать дефайны из avr/io.h:

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

UCSRB|=(1<<TXEN) | (1<<RXEN);
Так гораздо понятнее, не правда ли?

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

   while(k>0)
   {
      k--;
      UDR=0x08;
   }
После каждой записи в UDR надо ждать, пока закончится отсылка. Впрочем, это, как я вижу, уже было замечено.

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

   char *out=itoa(a,buff,10);
В МК лучше не использовать динамическое выделение памяти.

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

   char buff[250]={0};
Буфер лучше обнулять явно.

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

ISR(TIMER2_COMP_vect)
{
   int e=0;
   e=TCNT1L;
   a=TCNT1H;
Прерывание таймера №2, а работаем с регистрами первого...
Разница между теорией и практикой на практике гораздо больше, чем в теории.
Контактная информация:
Встал на лапы
Сообщения: 146
Зарегистрирован: Вс сен 16, 2012 22:00:40

Сообщение foton6 »

YS писал(а):

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

   char *out=itoa(a,buff,10);
В МК лучше не использовать динамическое выделение памяти.
А чем это чгрозит?
YS писал(а):

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

ISR(TIMER2_COMP_vect)
{
   int e=0;
   e=TCNT1L;
   a=TCNT1H;
Прерывание таймера №2, а работаем с регистрами первого...
Так задумано)
Счетчик импульсов типо)
YS
Друг Кота
Аватара пользователя
Сообщения: 7518
Зарегистрирован: Вс мар 29, 2009 22:09:05

Сообщение YS »

А чем это чгрозит?
Трудноуловимыми глюками. В МК нет ОС, а динамическое выделение памяти - функция именно ОС. Да, эти вызовы реализовали автономно, но реализовали кривовастенько. В мелком МК без ОС динамическое выделение и невозможно реализовать нормально.

Да и нафига динамическое выделение памяти, если этой памяти целиком всего килобайт?
Так задумано)
OK. Я просто не вдумывался в логику, просто прошелся по программе как статический анализатор. :)
Разница между теорией и практикой на практике гораздо больше, чем в теории.
Контактная информация:
Встал на лапы
Сообщения: 146
Зарегистрирован: Вс сен 16, 2012 22:00:40

Сообщение foton6 »

Дабы темы не плодить спрошу тут.
Пытаюсь по USART выводить переменные.
В протусе программа отл работает.
На железе же все плохо...
На компе вместо чисел нужных получаю кракозябры, перепробывал разные способы настройки USART, не пашет.
Для прикола воткнул 16 Мгц кварц и к моему удивлению мега8 запустилась, хотя скопт отключен... Да и вовсе мега 8 вроде макс на 12 может работать.
Как настроить USART??????
9600, 8 бит, 1 стоп бит "на обоих концах".
Кварц 4 Мгц. хотелось бы использовать.
YS
Друг Кота
Аватара пользователя
Сообщения: 7518
Зарегистрирован: Вс мар 29, 2009 22:09:05

Сообщение YS »

На компе вместо чисел нужных получаю кракозябры
Чем смотрите? Если присылаете сырое значение, а терминалка интерпретирует как ASCII-код, то и будут кракозябры. Попробуйте realterm, он умеет показывать сырой HEX.

Еще такое бывает, если земля отвалилась, т.е., подключены только RX и TX.
к моему удивлению мега8 запустилась, хотя скопт отключен
Конечно запустится. Кварц даже и без конденсаторов работать может. Но только в таких режимах снижается надежность, т.е., не факт, что оно будет так же работать, например, и при -10°C или при +50°C. Так что если МК ставится в изделие, то делать надо по рекомендациям производителя. А в порядке эксперимента еще и не такое может получиться. :)
Разница между теорией и практикой на практике гораздо больше, чем в теории.
Контактная информация:
Ответить

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