Страница 258 из 421
Re: CodeVision AVR в вопросах и ответах
Добавлено: Чт май 02, 2013 11:04:39
kotriks
народ помогите норм сделать меню чтобы не висло, а то ввожу комманду c знаками и буквами в конце и он её не выполняет, например fdgdf+CMTI:dfsgdfg и всё оно в ступоре. собственно помогите сделать фильтр чтобы бралась тока комманда на выполнение после чего читалась месага и кидалась на юарт процу read: на выполнение другой команды read
Код: Выделить всё
void sms_read(){
printf("AT+CMGF=1\r"); //set text mode
printf("AT+CMGL\r"); //read all unreaded SMS
}
void activeCommand(char c[])
{
if (c[0]=='+'&&c[1]=='C'&&c[2]=='M'&&c[3]=='T'&&c[4]=='I')
{
sms_read();
}
if (c[0]=='R'&&c[1]=='E'&&c[2]=='A'&&c[3]=='D')
{
read();
}
}
unsigned char COMMAND[5];
unsigned int i = 0;
// USART Receiver interrupt service routine
interrupt [USART_RXC] void usart_rx_isr(void)
{
char status,data;
status=UCSR0A;
data=UDR0;
if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0) {
WDTCSR = (1<<WDCE) | (1<<WDE);
/* Выкл. сторожевого таймера */
WDTCSR = 0x00;
if (data != ':')
{
COMMAND[i] = data;
i++;
}
else
{
COMMAND[i] = data;
i = 0;
activeCommand(COMMAND);
}
}
#pragma optsize-
#asm("wdr")
WDTCSR=0x39;
WDTCSR=0x29;
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif
}
Re: CodeVision AVR в вопросах и ответах
Добавлено: Сб май 04, 2013 07:28:32
kotriks
не уж то не кто не поможет, выручите господа.
Re: CodeVision AVR в вопросах и ответах
Добавлено: Сб май 04, 2013 09:51:53
vitalik_1984
kotriks писал(а):не уж то никто не поможет, выручите господа.
Во первых причем тут CVAVR? Кроме того, что программа пишется для этого компилятора никакой связи в вопросе не прослеживается.
Во вторых непонятно что вы подразумеваете под словами
чтобы бралась токалько комманда на выполнение после чего читалась месага и кидалась на юарт
Что откуда приходит, что считается сообщением и куда должна браться команда?
По вашему коду не понятно что вам нужно ведь он у вас не работает.
PS.Вам нужно использовать функции сравнения строк вместо ваших if (c[0]=='R'&&c[1]=='E'&&c[2]=='A'&&c[3]=='D')
Re: CodeVision AVR в вопросах и ответах
Добавлено: Сб май 04, 2013 22:05:48
kotriks
Да знал бы как не спрашивал!
(чтобы бралась только команда на выполнение после чего читалась месага и кидалась на юарт )
это значит что в месаге пришло READ и только его выплёвывало бы в юарт из сообщения всё что вне сообщения отсеивалось.
Re: CodeVision AVR в вопросах и ответах
Добавлено: Сб май 04, 2013 23:53:07
vitalik_1984
Давайте без экспрессий, что вы делаете? Что должно происходить, и что происходит в вашем варианте исполнения.
Проверять, как вы понимаете, будете только вы, а все кто здесь присутствует сможет только элементы кода подсказать.
С какого символа вообще начинается сообщение? От него и плясать после него значит нулевой элемент сообщения. Далее принимаем все символы этого сообщения, далее выделяем пришедшую команду с помощью функции сравнения строк либо через определенный символ.
PS. Вообще я так пригляделся, вы пишете в массив из пяти элементов символы после двоеточия, но нигде нет проверки на переполнение массива. Остерегайтесь таких ситуаций в коде.
Объявление переменных не ограничивает использование кодексов массива, а лишь выделяет необходимое количество памяти под них. Если попытаетесь записать в COMMAND[6] он запишет и другие данные, которые там находились будут повреждены. ведь 6 это всего лишь смещение от начального указателя на массив.
Re: CodeVision AVR в вопросах и ответах
Добавлено: Вс май 05, 2013 04:19:31
kotriks
к чему разводить демагогию? если вы можете то покажите на готовом примере.
если делать так
Код: Выделить всё
char buffer[10];
int Count;
buffer[Count] = '\n';
if( strcmp( buffer, "READ" ) == 0 )
{
read();
}
как его воткнуть и куда? в while(1) нельзя у меня там другой код выполняется циклично.
Re: CodeVision AVR в вопросах и ответах
Добавлено: Вс май 05, 2013 06:26:34
Сериг
kotriks,запусти таймер,делай цикл который написал в прерывании по таймеру,8-ми битного тут хватит.
P.S. (Вот и я в дискуссию ворвался

)
Re: CodeVision AVR в вопросах и ответах
Добавлено: Вс май 05, 2013 09:42:03
vitalik_1984
kotriks писал(а):Код: Выделить всё
char buffer[10];
int Count;
buffer[Count] = '\n';
if( strcmp( buffer, "READ" ) == 0 )
{
read();
}
как его воткнуть и куда? в while(1) нельзя у меня там другой код выполняется циклично.
Да хоть куда его воткните, в таком виде работать не будет.
Сначала присваиваете буферу значение, потом сравниваете лучше, наверно так?
buffer[++Count] = '\n'; Так добавится завершающий символ. Вместо вашего варианта, в котором произойдет замещение последнего символа.
PS. Демагогию тут другие люди разводят, те, которые вопрос не могут правильно поставить, и приходится две страницы клещами вытаскивать.
Напишите нормально словами тех. задание, может кто и подберет для вас код из своих работ.
Я лично до сих пор слабо представляю что вы вообще там делаете.
Re: CodeVision AVR в вопросах и ответах
Добавлено: Вс май 05, 2013 13:34:21
servo
Пытаюсь посчитать четкое кол-во импульсов на входе INT1(mega128) по низкому уровню. Иногда получается что низкий уровень еще присутствует на ноге INT1 и прерывание срабатывает несколько раз и инкрементирует переменную пока уровень на ноге не будет высоким. Вот и вопрос как правильно можно реализовать четкий отсчет импульсов по прерыванию на INT1 ?
Код: Выделить всё
//Инициализация
EICRA=0x00;EICRB=0x00;EIMSK=0x02;EIFR=0x02;
Код: Выделить всё
//прерывание на INT1
interrupt [EXT_INT1] void ext_int1_isr(void)
{
count++;
}
Re: CodeVision AVR в вопросах и ответах
Добавлено: Вс май 05, 2013 15:39:31
vitalik_1984
А чем не нравится режим прерывание по переходу на низкий уровень? прерывание по низкому нужно только для того, чтобы МК проснулся, далее уже можно переключиться на любой желаемый режим.
Re:
Добавлено: Вс май 05, 2013 21:01:32
PabloVed
Еще раз прошу прощения за беспокойство.
Я уже писал в эту тему с проблемой, связанной с моими кривыми лапами.
Спойлер
PabloVed писал(а):Доброго времени суток.
Пишу в связке CodeVisionAVR + Proteus 7 программу для вентильного двигателя (он же BLDC). С датчиками Холла, с прерываниями, с даташитом avr492.
В качестве контроллера выбрал Atmega8. И тут такая проблема - не уверен, что правильно написал прерывание. В целях проверки, изменил код так, что у меня что приходит с датчиков Холла (PINC), то и должно выдаваться на обмотки (PORTD). И получается какая-то ерунда, при симуляции в протеусе показывает что на выход идет только сигнал с PORTD.0
Ткните носом, где я так напортачил, прошу.
Код: Выделить всё
#include <mega8.h>
//unsigned char tmp=0;
// char flag=1;
void port_init()
{DDRD=1;
PORTD=1;
DDRC=0;
PORTC=0xFF;
DDRB=0;
PORTB=0xFF;
}
void timer_init()
{
TCCR2=0x01;
TIMSK=0x40;
TCNT2=0x30;
}
void pwm_init()
{ OCR2=0x00;
// TCCR2=(1<<COM21)|(1<<WGM20)|(1<<WGM21)|(1<<CS20);
};
interrupt [TIM2_OVF] void overflow_timer2 (void)
{
char tmp;
tmp = PINC;
PORTD = tmp;
#asm("sei")
/*switch (tmp)
{
case 0b00000101: {PORTD=0b00000101;}break;
case 0b00000001: {PORTD=0b00001001;}break;
case 0b00000011: {PORTD=0b00011000;}break;
case 0b00000010: {PORTD=0b00010010;}break;
case 0b00000110: {PORTD=0b00100010;}break;
case 0b00000100: {PORTD=0b00100001;}break;
}*/
}
void main()
{
port_init();
timer_init();
pwm_init();
#asm("sei")
while (1)
{};
}
Посоветовали сменить настройку PORTD. Настройку поменял ( DDRD=0xFF; PORTD - удалил из инициализации), в качестве теста запустил с присвоением, PORTD=PINC (что пришло с датчиков Холла, то и ушло на выход), работает - привод вращается, сигналы принимаются/выдаются.
Но при попытке завести все это через switch - ничего не происходит. В чем может быть проблема?
Re: CodeVision AVR в вопросах и ответах
Добавлено: Вс май 05, 2013 23:31:09
vitalik_1984
Тут дело скорее даже не в том, что switch используется. Когда нужно, чтобы действовали только несколько бит из всего порта нужно использовать маску вроде такой
Код: Выделить всё
{
#define MASK 0b00000111
char tmp;
tmp = PINC&MASK;
#asm("sei")
switch (tmp)
{
Ведь у вас в настройках выставлено DDRC=0;
PORTC=0xFF;
это значит по умолчанию на неиспользуемых ножках порта будет 1, значит условие case 0b00000101: никогда не выполнится, как и все остальные.
Подучите побитовые операции и все получится.
и как это у вас все вращается, когда всего одна ножка порта используется как выход?
Может нужно так?
Re: CodeVision AVR в вопросах и ответах
Добавлено: Пн май 06, 2013 07:48:57
Аlex
servo писал(а):прерывание срабатывает несколько раз и инкрементирует переменную пока уровень на ноге не будет высоким.
Это заблуждение. Прерывание срабатывает только по перепаду уровня.
Re: CodeVision AVR в вопросах и ответах
Добавлено: Пн май 06, 2013 09:49:52
vitalik_1984
Это кто вам такое сказал? В AVR Есть несколько режимов прерывания, по спаду, по фронту, по низкому уровню(в дш это level interrupt).
Так вот нужно просто настроить прерывание на спад и все будет ОК.
Re: CodeVision AVR в вопросах и ответах
Добавлено: Пн май 06, 2013 15:35:20
servo
vitalik_1984 писал(а):Это кто вам такое сказал? В AVR Есть несколько режимов прерывания, по спаду, по фронту, по низкому уровню(в дш это level interrupt).
Так вот нужно просто настроить прерывание на спад и все будет ОК.
попробовал настроить прерывания по спадающему фронту.. работает.. спасибо !
я вот подумал, может есть такая возможность в AVR чтобы можно было вызывать прерывания программно

т.е отсчитал например в основном цикле кол-во входящих импульсов далее запустил прерывание, и считай импульсы не пропуская ни одного импульса, пока выполняется код в прерывании.
Re: CodeVision AVR в вопросах и ответах
Добавлено: Пн май 06, 2013 16:45:45
PabloVed
Спойлер
vitalik_1984 писал(а):Тут дело скорее даже не в том, что switch используется. Когда нужно, чтобы действовали только несколько бит из всего порта нужно использовать маску вроде такой
Код: Выделить всё
{
#define MASK 0b00000111
char tmp;
tmp = PINC&MASK;
#asm("sei")
switch (tmp)
{
Ведь у вас в настройках выставлено DDRC=0;
PORTC=0xFF;
это значит по умолчанию на неиспользуемых ножках порта будет 1, значит условие case 0b00000101: никогда не выполнится, как и все остальные.
Подучите побитовые операции и все получится.
Да, в этом и была ошибка. После добавления маски по первым трем битам все заработало. Большое спасибо за помощь!
Re: CodeVision AVR в вопросах и ответах
Добавлено: Пн май 06, 2013 18:25:41
Аlex
vitalik_1984 писал(а):Это кто вам такое сказал?
Всегда думал, что так и есть. Да и логика моя мне подсказывает, что прерывание по уровню - ненужная и глупая фича. Даже не укладывается в голове куда можно её применить

Re: CodeVision AVR в вопросах и ответах
Добавлено: Пн май 06, 2013 18:38:12
vitalik_1984
servo писал(а):попробовал настроить прерывания по спадающему фронту.. работает.. спасибо !
Рад, что помог
servo писал(а):
я вот подумал, может есть такая возможность в AVR чтобы можно было вызывать прерывания программно

т.е отсчитал например в основном цикле кол-во входящих импульсов далее запустил прерывание, и считай импульсы не пропуская ни одного импульса, пока выполняется код в прерывании.
ничего не понял, зачем вам в основном цикле считать? у вас все прекрасно в прерывании считается, можно при желании в самом прерывании устанавливать глобальные флаги для того, чтобы отслеживать какие либо события в основном цикле.
А чтобы можно было вызвать еще и программно то, что выполняется в прерывании можно просто оформить в функции и вызывать ее при необходимости либо в основном, либо из прерывания.
Только так, чтобы эта функция не была затратна по времени.
Даже не укладывается в голове куда можно её применить
Просто когда Мк просыпается только от этого прерывания его просто приходится применять

Есть еще, конечно вариант с прерыванием по изменению уровня( pin change), но оно, как я понял, не у всех Мк бывает.
Re: CodeVision AVR в вопросах и ответах
Добавлено: Вт май 07, 2013 17:45:19
Импульс
Здравствуйте!
Много прочитал информации про:
Прерывания (INTERRUPTS)
Таймеры/счетчики (TIMER/COUNTERS)
И теперь понятно ,что не чего не понятно

.
Теперь знаю:
в МК все прерывания —
аппаратные, и делятся они нa
• внутренние
• внешние (пока не интерисуют)
далее>>
для запуска инициализации любого прерывания надо в программе сделать :
1. разрешить прерывания вообще (по умолчанию они запрещены),
2. затем разрешить это конкретное прерывание,
3. установить для него один из доступных режимов и, наконец,
4. установить вектор прерывания:
или так >>
a) обработка прерываний была разрешена,
b) отслеживалось переполнение таймера, и
c) существовала программа обработки прерывания по переполнению таймера.
и то от чего может происходить прерывание:
1. от таймеров,
2. от аналогового компаратора,
3. от последовательного порта и т.д.
чуть не забыл
про 4 главных регистра:
- GIMSK (General Interrupt Mask Register) - разрешает или запрещает внешние прерывания по входу INT0/INT1;
- GIFR (General Interrupt Flag Register) - регистр флагов внешних прерываний;
- TIMSK (Timer/Counter Interrupt Mask Register) - регистр маскирования прерываний от таймера/счетчика Т/С0 и Т/С1;
- TIFR (Timer/Counter Interrupt Flag Register) - регистр флагов прерываний от таймеров/счетчиков.
А как теперь это связать

не знаю...
Re: CodeVision AVR в вопросах и ответах
Добавлено: Вт май 07, 2013 17:48:13
Аlex
И причём тут CV AVR ?