Вопросы по С/С++ (СИ)

Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Ответить
isx
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2316
Зарегистрирован: Вс июн 26, 2011 20:03:21

Сообщение isx »

Код просто очень большой и безумно коряво написан (мой первый опыт с СИ :) ), но тем не менее исправно работает.
Смысл в том, что при start == 1 начинается считывание показаний с датчика холла в переменную schet. Всё это находится в main.
Так вот, необходимо сделать так: если при start == 1 в течении 1 секунды переменная schet остаётся неизменной, то переменная error = 2;.
Без применения прерываний код работает, но как только я добавляю их , то в итоге пишет на строку с "ISR (TIMER1_COMPA_vect)" такое ругательство: "Error: : declaration syntax error"
Сейчас код прерывания имеет такой вид (всё это находится перед main):

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

ISR (TIMER1_COMPA_vect)
{                    
if (start == 1) {
if (koordold == schet) {start = 3; error = 2;} else {koordold = schet;}};
}               



TCCR1A = 0x00;
TCCR1B = (1 << CS12)|(0 << CS11)|(1 << CS10)|(1 << WGM12); 
TCNT1 = 0x00;
OCR1A = 7812;
TIMSK |= (1 << OCIE1A); 
Да кстати, совсем забыл... Это всё делается на CVAVR. Все примеры которыя я нашёл в нете были для WINAVR, поэтому пришлось немного править, но по ходу и это не помогло :))
Реклама
Друг Кота
Аватара пользователя
Сообщения: 8007
Зарегистрирован: Вс ноя 14, 2010 19:24:26
Откуда: Лукалэнд

Сообщение hybroid »

По-моему ISR() - это фича GCC для AVR, а не кодевижн. У вас прерывания объявляются не так. И векторы имеют другие имена, но больше не подскажу, ибо CV не видел.
Реклама
Встал на лапы
Сообщения: 80
Зарегистрирован: Ср янв 13, 2010 12:35:17

Сообщение CEBKA »

Народ, нужен код для открытия- закрытия транзистора на порту В, и регулировку тока(или напряжения) на порту С, чтобы 12В лампочки плавно потухали
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2482
Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень

Сообщение vitalik_1984 »

hybroid писал(а):По-моему ISR() - это фича GCC для AVR, а не кодевижн. У вас прерывания объявляются не так. И векторы имеют другие имена, но больше не подскажу, ибо CV не видел.
Вот вот я тоже заметил и нечего подсказывать там мастер есть.

вообще там вроде нет

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

#include <avr/io.h>  
зато есть

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

#include <mega8.h>
Не пробовали мастером проекта воспользоваться?(кнопка шестеренка)
Вообще не понимаю людей, которые задают такие вопросы, когда под рукой мастер.
Можно в любой момент подглядеть как правильно инициализировать, как прерывания правильно оформить
Даже не просто подглядеть а еще и скопировать!!!
Главное в самом мастере не на шестерню нажимать, а на листок с лупой, тогда уже написанный код не портится, там можно скопировать.
В поисках истины человек развивается.
Контактная информация:
Реклама
Эиком - электронные компоненты и радиодетали
Держит паяльник хвостом
Аватара пользователя
Сообщения: 995
Зарегистрирован: Сб апр 02, 2011 17:59:22
Откуда: Город-герой Севастополь

Сообщение SubDia »

Да ну его в дупу, того мастера. Меня он в свое время только запутывал.
Обработчики прерываний в CVAVR декларируются подобным образом:

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

interrupt [vector_name] void func_name(void)
{
  //тут собсно обработчик
}
А имя вектора подсмотрите в interrupt.h, я уж и не помню.
pavel_cydenov: Вобще я праAVRославный человек. Но и про ислARM слышал много хорошего )
MrYuran: Самые ортодоксальные — это PICудеи )
Katz: Не, 51-ники. )
Изображение
Реклама
Друг Кота
Аватара пользователя
Сообщения: 8007
Зарегистрирован: Вс ноя 14, 2010 19:24:26
Откуда: Лукалэнд

Сообщение hybroid »

CEBKA писал(а):Народ, нужен код для открытия- закрытия транзистора на порту В, и регулировку тока(или напряжения) на порту С, чтобы 12В лампочки плавно потухали
Рады за вас. Мигать портами учат в гугле, валом статей. А по второй части вопроса - ШИМ. Не поверите, но тоже тонны всего написаны.
Если лень самому - есть другой раздел форума, где могут удовлетворить любой каприз за ваши деньги.
Реклама
isx
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2316
Зарегистрирован: Вс июн 26, 2011 20:03:21

Сообщение isx »

Спасибо за советы :)
interrupt [TIM1_OVF] void timer1_ovf_isr(void)
{...........}
Так поставил, а остальное в основной цикл засунул. Компиль вроде не проругал :)
isx
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2316
Зарегистрирован: Вс июн 26, 2011 20:03:21

Сообщение isx »

Поставил sei(); после настроек таймера... Программа вообще стала творить чёрт пойми что...
Ладно, позже буду ковырять, ато на экзамен скоро идти... :)
Мне вот что ещё интересно... Получается за 1 секунду МК делает 8 миллионов тактов... Так что же будет если обойтись без таймера, но его способом?
Берём 2 переменные tim1 и tim2 и строим такую фигню:

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

 tim1 = tim1 + 1;
 if (tim1 == 1024) {tim2 = tim2 + 1; tim1 = 0;}
 if (tim2 == 7812) {
 // выполняем наши команды
 tim1 = 0; tim2 = 0;
 }
Как я понял таймер работает по тому же принципу...
Друг Кота
Аватара пользователя
Сообщения: 8007
Зарегистрирован: Вс ноя 14, 2010 19:24:26
Откуда: Лукалэнд

Сообщение hybroid »

isx писал(а):Так что же будет если обойтись без таймера, но его способом?
Говнокод.
isx
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2316
Зарегистрирован: Вс июн 26, 2011 20:03:21

Сообщение isx »

А прикинте.... Работает блин :))
Только значения малость уменьшил...
isx
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2316
Зарегистрирован: Вс июн 26, 2011 20:03:21

Сообщение isx »

И почему сразу говнокод?
Мне кажется что принцип тот же и у таймера, ведь не зря же восьмиразрядный таймер имеет максимальный коэффициент пересчета 2^8=256, а шестнадцатиразрядный 2^16=65536 (без использования делителя), что в принципе соответствует максимальным значениям переменных объявленых в unsigned char и unsigned int.
И в моём случае нужно было использовать шестнадцатиразрядный таймер, и соответственно, мне пришлось использовать переменные int
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2482
Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень

Сообщение vitalik_1984 »

SubDia писал(а):Да ну его в дупу, того мастера. Меня он в свое время только запутывал.
А никто нет заставляет все его строки брать,только те, где нужно подсмотреть
SubDia писал(а):А имя вектора подсмотрите в interrupt.h, я уж и не помню.
Какой нафиг? там это не нужно.
Выставил в мастере нужное он сам все пропишет.И названия векторов там сильно отличаются от стандартных.
В поисках истины человек развивается.
Контактная информация:
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2482
Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень

Сообщение vitalik_1984 »

isx писал(а):

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

 tim1 = tim1 + 1;
 if (tim1 == 1024) {tim2 = tim2 + 1; tim1 = 0;}
 if (tim2 == 7812) {
 // выполняем наши команды
 tim1 = 0; tim2 = 0;
 }
Как я понял таймер работает по тому же принципу...
Таймер то может и работает по тому же принципу, но он то это делает в фоне, не мешая делать других, более полезных, вещей.
Если хотите сделать таймер на основе ненужного мк, так можно сделать, но ничем, кроме таймера, он не будет заниматься.
В поисках истины человек развивается.
Контактная информация:
Держит паяльник хвостом
Аватара пользователя
Сообщения: 995
Зарегистрирован: Сб апр 02, 2011 17:59:22
Откуда: Город-герой Севастополь

Сообщение SubDia »

vitalik_1984 писал(а): Какой нафиг? там это не нужно.
Выставил в мастере нужное он сам все пропишет.
А пожрать мастер не приготовит, не? :)))
По поводу векторов - да, достаточно хидера mega8.h.
pavel_cydenov: Вобще я праAVRославный человек. Но и про ислARM слышал много хорошего )
MrYuran: Самые ортодоксальные — это PICудеи )
Katz: Не, 51-ники. )
Изображение
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2482
Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень

Сообщение vitalik_1984 »

Пожрать не нужно, я сам справлюсь.А вот если бы сам программу писал, цены бы не было. :)))
В поисках истины человек развивается.
Контактная информация:
isx
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2316
Зарегистрирован: Вс июн 26, 2011 20:03:21

Сообщение isx »

И вот ещё один похоже безумно глупый вопрос :)
Как можно проще обнулить определённый бит порта?

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

 PORTB = 0b00010000;
 x = PORTB & 0b00010000;
if (x == 0b00010000) {PORTB = PORTB - 0b00010000;}
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2482
Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень

Сообщение vitalik_1984 »

это обсуждалось в этой же ветке листов 25 назад.по моим репликам ориентируясь легко можно найти.

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

PORTB = 0b00010000;//так можно делать только при инициализации
 x = PORTB & 0b00010000;//так если нужно сбросить все биты кроме того,где 1
if (x == 0b00010000) {PORTB = PORTB - 0b00010000;}//это я вообще не знаю зачем.не даст ничего хорошего
 

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

 PORTB| = 0b00010000;// установка бита
 PORTB &= ~0b00010000;//снятие бита либо 
PORTB &= 0b11101111;
//но удобнее так :
#define Led 4
PORTB| = (1<< Led);//зажечь светодиод.
PORTB &= ~ (1<< Led);//потушить светодиод

 
В поисках истины человек развивается.
Контактная информация:
isx
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2316
Зарегистрирован: Вс июн 26, 2011 20:03:21

Сообщение isx »

vitalik_1984 писал(а)://это я вообще не знаю зачем.не даст ничего хорошего
Это если бит == 1, то присвоить ему 0.
Спасибо за помощь)))
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2482
Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень

Сообщение vitalik_1984 »

а ну да,можно и так сейчас подумал,но удобнее через сдвиг биты выставлять.
а потом как хотите можно и вычесть.или через логическое и.
есть еще инверсия бита
PORTB = PORTB ^ 0b00010000;
В поисках истины человек развивается.
Контактная информация:
Встал на лапы
Сообщения: 125
Зарегистрирован: Вс мар 01, 2009 20:41:19

Сообщение xVekx »

Уважаемые, поясните пожалуйста в AVR ST6 есть файл crc16.h, там есть функция _crc_ibutton_update(uint8_t __crc, uint8_t __data)

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

** \ingroup util_crc
    Optimized Dallas (now Maxim) iButton 8-bit CRC calculation.

    Polynomial: x^8 + x^5 + x^4 + 1 (0x8C)<br>
    Initial value: 0x0

    See http://www.maxim-ic.com/appnotes.cfm/appnote_number/27

    The following is the equivalent functionality written in C.

    \code
    uint8_t
    _crc_ibutton_update(uint8_t crc, uint8_t data)
    {
	uint8_t i;

	crc = crc ^ data;
	for (i = 0; i < 8; i++)
	{
	    if (crc & 0x01)
	        crc = (crc >> 1) ^ 0x8C;
	    else
	        crc >>= 1;
	}

	return crc;
    }
    \endcode
*/

static __inline__ uint8_t
_crc_ibutton_update(uint8_t __crc, uint8_t __data)
{
	uint8_t __i, __pattern;
	__asm__ __volatile__ (
		"	eor	%0, %4" "\n\t"
		"	ldi	%1, 8" "\n\t"
		"	ldi	%2, 0x8C" "\n\t"
		"1:	lsr	%0" "\n\t"
		"	brcc	2f" "\n\t"
		"	eor	%0, %2" "\n\t"
		"2:	dec	%1" "\n\t"
		"	brne	1b" "\n\t"
		: "=r" (__crc), "=d" (__i), "=d" (__pattern)
		: "0" (__crc), "r" (__data));
	return __crc;
}
вопрос, правильно нахожу crc8 для массива?

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

	 uint8_t crc8=_crc_ibutton_update(0x00,data[0]); 
	 for(int crc8_size=1;crc8_size<size;crc8_size++)
	 {
		 uint8_t crc8=_crc_ibutton_update(crc8,data[crc8_size]);
	 }
	 if(crc8!=data[size-1]){return 0x00;}
Ответить

Вернуться в «Разные вопросы по МК»