AVR Раздел по микроконтроллерам компании Atmel - AVR / ATtiny / ATmega / ATMega128 / ATxmega, вопросы по программированию в AVR studio и все, относящееся к AVR... |
31.07.2010, 17:41
|
|
Почётный гражданин KAZUS.RU
Регистрация: 13.10.2007
Адрес: Беларусь
Сообщений: 8,048
Сказал спасибо: 60
Сказали Спасибо 3,954 раз(а) в 2,309 сообщении(ях)
|
Re: RESET в AVR
picavr, ваш ответ задержался на год...
|
|
|
|
01.08.2010, 13:17
|
|
Почётный гражданин KAZUS.RU
Регистрация: 07.10.2007
Адрес: Луганск
Сообщений: 1,816
Сказал спасибо: 13
Сказали Спасибо 399 раз(а) в 214 сообщении(ях)
|
Re: RESET в AVR
__________________
"picavr(ГАВ)мыло.ру" USB_Analyzer, Digital_Storage_Oscilloscope "picavr.kr1.ru" заказы в Китай компонентов/изготовление: плат/ЖКИ/мембраных клавиатур/имп трансформаторов
|
|
|
|
07.02.2013, 11:17
|
|
Временная регистрация
Регистрация: 08.01.2007
Сообщений: 92
Сказал спасибо: 17
Сказали Спасибо 9 раз(а) в 9 сообщении(ях)
|
Re: RESET в AVR
Доброго Вам всем!
Хочу продолжить тему))
Внимательно перечитав весь топик хочу снова открыть тему, так как не получил ответ на то что меня интересовало(
У меня сложилась подобная ситуация: Кристал работает, потом входит в бесконечный цикл.. и продолжает работать. Но вот в какой то момент времени появляется соединение с ком портом (юартом) и мне надо четко отработать эту процедуру.
Так как я не знаю когда будет соединение... мне нужно что то типо подпрограммы.
В начале программы есть бесконечный цикл по параметру где все и должно работать, но после сброса не совсем коректно работает(( Подскажите что не так?
PHP код:
|
#include ‹mega2560.h›
#include ‹stdio.h›
#include ‹bits_macros.h›
#include ‹delay.h›
#define RXB8 1
#define TXB8 0
#define UPE 2
#define OVR 3
#define FE 4
#define UDRE 5
#define RXC 7
#define FRAMING_ERROR (1‹‹FE)
#define PARITY_ERROR (1‹‹UPE)
#define DATA_OVERRUN (1‹‹OVR)
#define DATA_REGISTER_EMPTY (1‹‹UDRE)
#define RX_COMPLETE (1‹‹RXC)
eeprom char basa_1[14]="+380675000850"; //Диспечерский Центр 1 (Д.Ц.1)
eeprom char basa_2[14]; //Диспечерский Центр 2 (Д.Ц.2)
eeprom char basa_3[14]; //Диспечерский Центр 3 (Д.Ц.3) Наблюдатель
char basa_1r[13]; //Диспечерский Центр 1 (Д.Ц.1)
char basa_2r[13]; //Диспечерский Центр 2 (Д.Ц.2)
char basa_3r[13]; //Диспечерский Центр 3 (Д.Ц.3) Наблюдатель
static unsigned int RX0;
volatile char M=0xFF;
eeprom char WD=0x00;
//////////////////////////////////////////////////////////////////////////////////////
void strcpyre(char *str, eeprom char *str0)
{
char i;
for(i=0; i‹13; i++) str[i]=str0[i];
}
//////////////////////////////////////////////////////////////////////////////////////
void strcpywe(char *str, eeprom char *str0)
{
char i;
for(i=0; i‹13; i++) str0[i]=str[i];
}
/////////////////////////////////////////////////////////////////////////////////////
void WDT_off(void)
{
#asm("cli")
#asm("wdr")
/* Clear WDRF in MCUSR */
MCUSR &= ~(1‹‹3);
/* Write logical one to WDCE and WDE */
/* Keep old prescaler setting to prevent unintentional time-out*/
WDTCSR|=(1‹‹4)|(1‹‹3);
/* Turn off WDT */
WDTCSR = 0x00;
}
/////////////////////////////////////////////////////////////////////////////////////
void WDT_on(void)
{
// Watchdog Timer initialization
// Watchdog Timer Prescaler: OSC/2k
// Watchdog Timer interrupt: Off
//#pragma optsize-
#asm("wdr")
WDTCSR=0x18;
WDTCSR=0x08;
//#ifdef _OPTIMIZE_SIZE_
//#pragma optsize+
//#endif
}
// USART0 Receiver interrupt service routine
interrupt [USART0_RXC] void usart0_rx_isr(void)
{
char status,data;
status=UCSR0A;
data=UDR0;
if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0)
{
switch (data)
{
case 0x00:
SetBit(RX0, 11);
break;
case 0x20:
SetBit(RX0, 10);
break;
case 0x70:
SetBit(RX0, 9);
break;
case 0x84:
SetBit(RX0, 8);
if(WD==0x00) { #asm("cli") WD=0xFF; WDT_on(); while(1); };
if((RX0&0x0F00)==0x0F00) { RX0=0x0000; M=0x00; return; };
break;
case 0x85:
SetBit(RX0, 7);
if((RX0&0x0E80)==0x0E80) { RX0=0x0000; M=0x01; return; };
break;
case 0x86:
SetBit(RX0, 6);
if((RX0&0x0E40)==0x0E40) { RX0=0x0000; M=0x02; return; };
break;
case 0x04:
SetBit(RX0, 5);
if((RX0&0x0E20)==0x0E20) { RX0=0x0000; M=0x04; UCSR0B=0x18; return; };
break;
case 0x05:
SetBit(RX0, 4);
if((RX0&0x0E10)==0x0E10) { RX0=0x0000; M=0x05; UCSR0B=0x18; return; };
break;
case 0x06:
SetBit(RX0, 3);
if((RX0&0x0E08)==0x0E08) { RX0=0x0000; M=0x06; UCSR0B=0x18; return; };
break;
case 0x78:
strcpywe(basa_1r, basa_1);
strcpywe(basa_2r, basa_2);
strcpywe(basa_3r, basa_3);
WD=0x00;
UCSR0B=0x98;
//SetBit(RX0, 2);
//if((RX0&0x1C04)==0x1C04) { RX0=0x0000; M=0x03; return; };
break;
case 0x66:
SetBit(RX0, 1);
break;
case 0x72:
SetBit(RX0, 0);
break;
};
UDR0=data;
};
}
void main(void)
{
char j, data0;
WDT_off();
strcpyre(basa_1r, basa_1);
strcpyre(basa_2r, basa_2);
strcpyre(basa_3r, basa_3);
// Crystal Oscillator division factor: 1
#pragma optsize-
CLKPR=0x80;
CLKPR=0x00;
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif
// USART0 initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART0 Receiver: On
// USART0 Transmitter: On
// USART0 Mode: Asynchronous
// USART0 Baud Rate: 115200
UCSR0A=0x00;
UCSR0B=0x98;
UCSR0C=0x06;
UBRR0H=0x00;
UBRR0L=0x01;
// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
ADCSRB=0x00;
// Global enable interrupts
#asm("sei")
SetBit(DDRA, 3);
SetBit(DDRA, 4);
SetBit(DDRE, 2);
ClearBit(PORTE, 2); //включение блока, 0-EN TPS
if(WD!=0x00) SetBit(PORTA, 3);
while(WD)
{
switch (M)
{
case 0xFF:
break;
case 0x00:
putchar(0x04);
putchar((basa_1r[0]‹‹4)|(basa_1r[1]&0x0F));
putchar((basa_1r[2]‹‹4)|(basa_1r[3]&0x0F));
putchar((basa_1r[4]‹‹4)|(basa_1r[5]&0x0F));
putchar((basa_1r[6]‹‹4)|(basa_1r[7]&0x0F));
putchar((basa_1r[8]‹‹4)|(basa_1r[9]&0x0F));
putchar((basa_1r[10]‹‹4)|(basa_1r[11]&0x0F));
putchar((basa_1r[12]‹‹4)|0x0F);
putchar(0xFF);
RX0=0x0000;
break;
case 0x01:
putchar(0x05);
putchar((basa_2r[0]‹‹4)|(basa_2r[1]&0x0F));
putchar((basa_2r[2]‹‹4)|(basa_2r[3]&0x0F));
putchar((basa_2r[4]‹‹4)|(basa_2r[5]&0x0F));
putchar((basa_2r[6]‹‹4)|(basa_2r[7]&0x0F));
putchar((basa_2r[8]‹‹4)|(basa_2r[9]&0x0F));
putchar((basa_2r[10]‹‹4)|(basa_2r[11]&0x0F));
putchar((basa_2r[12]‹‹4)|0x0F);
putchar(0xFF);
RX0=0x0000;
break;
case 0x02:
putchar(0x06);
putchar((basa_3r[0]‹‹4)|(basa_3r[1]&0x0F));
putchar((basa_3r[2]‹‹4)|(basa_3r[3]&0x0F));
putchar((basa_3r[4]‹‹4)|(basa_3r[5]&0x0F));
putchar((basa_3r[6]‹‹4)|(basa_3r[7]&0x0F));
putchar((basa_3r[8]‹‹4)|(basa_3r[9]&0x0F));
putchar((basa_3r[10]‹‹4)|(basa_3r[11]&0x0F));
putchar((basa_3r[12]‹‹4)|0x0F);
putchar(0xFF);
RX0=0x0000;
break;
case 0x04:
for(j=0; j‹8; j++)
{
data0=getchar();
if(j==0x00)
{
basa_1r[0]= (0x20|(data0››4));
basa_1r[1]= (0x30|(data0&0x0F));
}
else
{
basa_1r[j*2] = (0x30|(data0››4));
basa_1r[j*2+1]= (0x30|(data0&0x0F));
}
}
#asm("cli")
UCSR0B=0x98;
#asm("sei")
M=0xFF;
break;
case 0x05:
for(j=0; j‹8; j++)
{
data0=getchar();
if(j==0x00)
{
basa_2r[0]= (0x20|(data0››4));
basa_2r[1]= (0x30|(data0&0x0F));
}
else
{
basa_2r[j*2] = (0x30|(data0››4));
basa_2r[j*2+1]= (0x30|(data0&0x0F));
}
}
#asm("cli")
UCSR0B=0x98;
#asm("sei")
M=0xFF;
break;
case 0x06:
for(j=0; j‹8; j++)
{
data0=getchar();
if(j==0x00)
{
basa_3r[0]= (0x20|(data0››4));
basa_3r[1]= (0x30|(data0&0x0F));
}
else
{
basa_3r[j*2] = (0x30|(data0››4));
basa_3r[j*2+1]= (0x30|(data0&0x0F));
}
}
#asm("cli")
UCSR0B=0x98;
#asm("sei")
M=0xFF;
break;
};
};
while (16)
{
SetBit(PORTA, 3);
delay_ms(1000);
ClearBit(PORTA, 3);
SetBit(PORTA, 4);
delay_ms(1000);
ClearBit(PORTA, 4);
};
}
|
Вот отладочная программа этого процесса
При приходе определенной последовательности пишется флажок в эпром и сбрасывается МК, и входит в подпрограмму. Такая задумка ![Озадачен](images/smilies/icon_confused.gif) Но вот не всегда работает((( через раз ![Бьюсь об стену](images/smilies/icon_obstenu.gif)
И меня смущает что диодик подключен к PA3 не светится а моргает
|
|
|
|
07.02.2013, 11:46
|
|
Супер-модератор
Регистрация: 13.03.2004
Адрес: Minsk
Сообщений: 2,378
Сказал спасибо: 1,955
Сказали Спасибо 1,328 раз(а) в 578 сообщении(ях)
|
Re: RESET в AVR
Сообщение от papa_n
|
У меня сложилась подобная ситуация: Кристал работает, потом входит в бесконечный цикл.. и продолжает работать. Но вот в какой то момент времени появляется соединение с ком портом (юартом) и мне надо четко отработать эту процедуру.
Так как я не знаю когда будет соединение... мне нужно что то типо подпрограммы.
В начале программы есть бесконечный цикл по параметру где все и должно работать, но после сброса не совсем коректно работает(( Подскажите что не так?
|
Вот не понял я, каким боком тут сброс.
Есть программа с бесконечным рабочим циклом.
Есть прерывание по приему с USART - на то оно и прерывание, чтобы происходить "не знаю когда".
Обрабатывайте принятые байты в прерывании (ну, анализ там и т.д.), по приему осмысленного - выставляйте какой-ниюудь флаг, а этот флаг обрабатывайте в рабочем цикле
В программу не вникал, но удивление вызвала переменная WD в eeprom-е
__________________
[ жизнь приятна и красива, если выпить литр пива ]
|
|
|
|
07.02.2013, 13:12
|
|
Временная регистрация
Регистрация: 08.01.2007
Сообщений: 92
Сказал спасибо: 17
Сказали Спасибо 9 раз(а) в 9 сообщении(ях)
|
Re: RESET в AVR
В цикле есть очень длинные процедуры, и во время их выполнения может быть соединение, по этому пишу флажок в эпром WD, что бы зайти в тот цикл что в начале программы...
Сейчас экспериментирую с битом WDRF, в регистре MCUSR, но все равно как то некоректно(
|
|
|
|
07.02.2013, 13:24
|
|
Почётный гражданин KAZUS.RU
Регистрация: 19.08.2006
Адрес: Львов
Сообщений: 1,616
Сказал спасибо: 65
Сказали Спасибо 315 раз(а) в 264 сообщении(ях)
|
Re: RESET в AVR
Сообщение от papa_n
|
В цикле есть очень длинные процедуры, и во время их выполнения может быть соединение, по этому пишу флажок в эпром WD, что бы зайти в тот цикл что в начале программы...
Сейчас экспериментирую с битом WDRF, в регистре MCUSR, но все равно как то некоректно(
|
Что значит "длинные процедуры" В каких единицах? Метры, литры, секунды?
Соединение - это как? Есть понятие, получение байта по прерыванию. Насколько я понял, получить этот байт (или группу байтов) и взвести флаг готовности данных - это ваше прерывание в состоянии произвести? Как никак у него приоритет повыше фонового. Зачем флаг писать в eeprom?! Время записи в эту область непозволительно долго для прерывания. Ведь вам придется ждать окончания записи.
__________________
С уважением,
Vic / ut1wpr
|
|
|
|
07.02.2013, 13:44
|
|
Временная регистрация
Регистрация: 08.01.2007
Сообщений: 92
Сказал спасибо: 17
Сказали Спасибо 9 раз(а) в 9 сообщении(ях)
|
Re: RESET в AVR
Я отказался от эпрома, сейчас читаю бит WDRF, в регистре MCUSR.
Алгоритм работы компьютерной программы таков:
Приходит последовательность
"020020040002007084" (это в 16 ти ричной форме) потом пауза..
потом запросы, на которые нужно отвечать, потом сделать запись переменных с номерами телефонов, для работы GSM modul.
Мне кажется это удобнее делать в подпрограмме, чем писать преривание на страницу.
Для этого есть цикл
PHP код:
|
while(x) {...}
где х это тот флажок что установится после принятия последовательности
|
|
|
|
|
07.02.2013, 15:30
|
|
Временная регистрация
Регистрация: 08.01.2007
Сообщений: 92
Сказал спасибо: 17
Сказали Спасибо 9 раз(а) в 9 сообщении(ях)
|
Re: RESET в AVR
PHP код:
|
#include ‹mega2560.h›
#include ‹stdio.h›
unsigned char M=0xFF;
unsigned char W;
unsigned char WDT_off(void)
{
unsigned char result;
result=(MCUSR&0x08)››3;
if(result!=0x00)
{
#asm("wdr")
MCUSR &= ~(1‹‹3);
WDTCSR|=(1‹‹4)|(1‹‹3);
WDTCSR = 0x00;
}
return result;
}
void WDT_on(void)
{
#pragma optsize-
#asm("wdr")
WDTCSR=0x18;
WDTCSR=0x08;
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif
}
// USART0 Receiver interrupt service routine
interrupt [USART0_RXC] void usart0_rx_isr(void)
{
char status,data;
static unsigned int RX0;
status=UCSR0A;
data=UDR0;
if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0)
{
data=....
//ловим последовательность
WDT_on();
while(1);
}
}
void main(void)
{
char j, data0;
W=WDT_off(); //если была сработка WDT, отключает WDT и возвращает "1", иначе "0"
// Crystal Oscillator division factor: 1
#pragma optsize-
CLKPR=0x80;
CLKPR=0x00;
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif
// USART0 initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART0 Mode: Asynchronous
// USART0 Baud Rate: 115200
UCSR0A=0x00;
UCSR0B=0x98;
UCSR0C=0x06;
UBRR0H=0x00;
UBRR0L=0x01;
// Analog Comparator initialization
ACSR=0x80;
ADCSRB=0x00;
// Global enable interrupts
#asm("sei")
while(2*W) //заходит в этот цикл если был сброс по WDT
{
//тут ловятся прерывания UART0
//и отрабатывается соединение
};
while (16)
{
//основной цикл моргания диодиков:ok:
};
}
|
В общем вот такая структура программы
Подскажите как правильно сбросить
|
|
|
|
07.02.2013, 15:33
|
|
Гражданин KAZUS.RU
Регистрация: 04.08.2006
Сообщений: 911
Сказал спасибо: 28
Сказали Спасибо 180 раз(а) в 139 сообщении(ях)
|
Re: RESET в AVR
Сообщение от papa_n
|
Для этого есть цикл
|
Да нет. Вам уже несколько раз повторили. Для этого существуют прерывания. В основном цикле обработали сообщение и заснули. По прерыванию проснулись и начали принимать новое сообщение. Обрабатывать опросом - некрасиво. Да и проблемы могут быть на больших скоростях. В AVR буфер 2 байта. То есть задержка на обработку на скорости 115200 не должна превышать 174 мкс.
Да и разбор полётов вы уж как то слишком в лоб делаете.
|
|
|
|
07.02.2013, 15:38
|
|
Почётный гражданин KAZUS.RU
Регистрация: 26.11.2011
Адрес: Анапа
Сообщений: 1,620
Сказал спасибо: 284
Сказали Спасибо 129 раз(а) в 111 сообщении(ях)
|
Re: RESET в AVR
пока не будет буфера, куда прерывание ложит байтики - не будет толку. Очень удобно иметь например два буфера. Или очередь. Или кольцевой.
У вас же есть признаки окончания приема команд от мопеда? Например, разделитель \r?
Вот по нему флаг и ставится, а в главном цикле ожидание. Это означает что в буфере есть команда (ответ, что угодно) и ее надо пропарсить. Я так делал.
|
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 09:17.
|
|