| AVR Раздел по микроконтроллерам компании Atmel - AVR / ATtiny / ATmega / ATMega128 / ATxmega, вопросы по программированию в AVR studio и все, относящееся к AVR... |
RESET в AVR
09.02.2013, 10:26
|
|
|
Почётный гражданин KAZUS.RUN
Регистрация: 25.05.2010
Адрес: г. Королёв
Сообщений: 8,487
Сказал спасибо: 30
Сказали Спасибо 3,070 раз(а) в 2,011 сообщении(ях)
|
Re: RESET в AVR
Сообщение от SasaVitebsk
|
|
MCUSR не переменная а регистр процессора.
|
Вы это мне объясняете?
Сообщение от SasaVitebsk
|
|
И он volatile по определению.
|

хде именно?
MCUSR в программе нигде не изменяется, поэтому компилятор вполне может выкинуть (соптимизировать) его чтение, если переменную, в которую он считывается, не объявить volatile.
ТС хочет непременно читать этот регистр, хотя он ему нафиг не нужен.
|
|
|
|
09.02.2013, 13:21
|
|
|
Почётный гражданин KAZUS.RUN
Регистрация: 20.03.2007
Адрес: "Братское кольцо враждебности", т.е. ближайшее заМКАДье.
Сообщений: 7,458
Сказал спасибо: 3,227
Сказали Спасибо 3,512 раз(а) в 2,393 сообщении(ях)
|
Re: RESET в AVR
Сообщение от papa_n
|
|
Мануал к чему?
|
К CVAVR. Что-то вроде avr-libc, идущего с GCC.
Вот как это было у меня (GCC):
файл ".аш"
|
Код:
|
// *****
// *****
void do_Early_Init(void) __attribute__((naked)) __attribute__ ((section (".init3")));
/* Установки аппаратуры контроллера, требуемые сразу после запуска:
Сброс сторожевого таймера и т.д. */
// *****
// ***** |
файл ".с"
|
Код:
|
void do_Early_Init() {
// Установки аппаратуры контроллера, требуемые сразу после запуска
// *****
// *****
byte_EI = MCUCSR;
MCUCSR = 0;
wdt_disable(); // Сброс сторожевого таймера
// *****
// *****
} // do_Early_Init |
А смысл обработки MCUSR компилятором в прологе тот, что на новых AVR'ках при получении сброса от WDT он будет автоматом разрешён после него и программа впадёт в вечный цикл сброса.
P.S. А так - да, надо пересмотреть алгоритм. Кривой он у Вас.
|
|
|
|
11.02.2013, 15:13
|
|
|
Временная регистрация
Регистрация: 08.01.2007
Сообщений: 92
Сказал спасибо: 17
Сказали Спасибо 9 раз(а) в 9 сообщении(ях)
|
Re: RESET в AVR
Всем Спасибо за участие!
Переделую по другому... но факт остается фактом((
В CVAVR я не нашол возможности прочитать этот регистр до пролога как в GCC.
Хотя кому интересно вот пример программы где работает но с эпромовским индексом... проверено.
Там 2 цикла, один основной, рабочий... другой, это подпрограмма которая запускается после прихода в Уарт определенной последовательности
|
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) Наблюдатель
unsigned char M=0xFF;
eeprom char WD=0;
unsigned char W;
//////////////////////////////////////////////////////////////////////////////////////
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_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;
static unsigned int RX0;
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((RX0&0x0F00)==0x0F00)
{
if (W==0x00) { #asm("cli") WD=0xFF; WDT_on(); while(1); };
RX0=0x0000;
M=0x00;
};
break;
case 0x85:
SetBit(RX0, 7);
if((RX0&0x0E80)==0x0E80) { RX0=0x0000; M=0x01; };
break;
case 0x86:
SetBit(RX0, 6);
if((RX0&0x0E40)==0x0E40) { RX0=0x0000; M=0x02; };
break;
case 0x04:
SetBit(RX0, 5);
if((RX0&0x0E20)==0x0E20) { RX0=0x0000; M=0x04; UCSR0B=0x18; };
break;
case 0x05:
SetBit(RX0, 4);
if((RX0&0x0E10)==0x0E10) { RX0=0x0000; M=0x05; UCSR0B=0x18; };
break;
case 0x06:
SetBit(RX0, 3);
if((RX0&0x0E08)==0x0E08) { RX0=0x0000; M=0x06; UCSR0B=0x18; };
break;
case 0x78:
SetBit(RX0, 2);
if((RX0&0x0C04)==0x0C04) { RX0=0x0000; M=0x03; return; };
break;
case 0x66:
SetBit(RX0, 1);
break;
case 0x72:
SetBit(RX0, 0);
break;
default: break;
};
};
}
void main(void)
{
char j, data0;
// 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")
strcpyre(basa_1r, basa_1);
strcpyre(basa_2r, basa_2);
strcpyre(basa_3r, basa_3);
W=WD;
SetBit(DDRA, 3);
SetBit(DDRA, 4);
SetBit(DDRE, 2);
SetBit(PORTE, 2);
ClearBit(PORTE, 2); //включение блока, 0-EN TPS
while(W)
{
SetBit(PORTA, 3);
switch (M)
{
case 0xFF:
break;
case 0x00:
putchar(0x02);
putchar(0x00);
putchar(0x20);
putchar(0x0C);
putchar(0x00);
putchar(0x0A);
putchar(0x00);
putchar(0x70);
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);
M=0xFF;
break;
case 0x01:
putchar(0x02);
putchar(0x00);
putchar(0x20);
putchar(0x0C);
putchar(0x00);
putchar(0x0A);
putchar(0x00);
putchar(0x70);
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);
M=0xFF;
break;
case 0x02:
putchar(0x02);
putchar(0x00);
putchar(0x20);
putchar(0x0C);
putchar(0x00);
putchar(0x0A);
putchar(0x00);
putchar(0x70);
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);
M=0xFF;
break;
case 0x03:
putchar(0x02);
putchar(0x00);
putchar(0x20);
putchar(0x03);
putchar(0x00);
putchar(0x01);
putchar(0x00);
putchar(0x78);
strcpywe(basa_1r, basa_1);
strcpywe(basa_2r, basa_2);
strcpywe(basa_3r, basa_3);
W=0x00;
WD=0x00;
#asm("cli")
UCSR0B=0x98;
#asm("sei")
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;
};
};
ClearBit(PORTA, 3);
while (16)
{
delay_ms(500);
SetBit(PORTA, 4);
delay_ms(500);
ClearBit(PORTA, 4);
};
}
|
После сброса, прога входит в первый цикл, и отрабатывает с Уартом ... в моем случаи читает/пишет номера для работы с GSM модемом.
Последний раз редактировалось papa_n; 11.02.2013 в 15:15.
|
|
|
|
11.02.2013, 20:33
|
|
|
Гражданин KAZUS.RUN
Регистрация: 04.08.2006
Сообщений: 911
Сказал спасибо: 28
Сказали Спасибо 180 раз(а) в 139 сообщении(ях)
|
Re: RESET в AVR
Сообщение от omercury
|
Вы это мне объясняете?
...хде именно?...
|
Я конечно не берусь судить за CVAVR. Но если это не так, в чём я жутко сомневаюсь, то этот компилятор и гроша ломанного не стоит.
volatile говорит о том, что переменная может быть изменена внешним способом. Это напрямую касается всех портов ввода вывода, а также регистрам проца. Бит там может быть изменён без участия программы, то есть внешним, по отношению к ней, способом.
Естественно это отмечается в файле объявлений для конкретного процессора.
Так для IAR сей регистр объявлявляется след. образом:
SFR_B_N(0x34, MCUSR, Dummy7, Dummy6, Dummy5, JTRF, WDRF, BORF, EXTRF, PORF)
там же приводится пример как это расшифровывается
|
Код:
|
* An example showing the SFR_B_N() macro call,
* the expanded result and usage of this result:
* SFR_B_N(0x25, TCCR2, FOC2, WGM20, COM21, COM20, WGM21, CS22, CS21, CS20)
* Expands to:
* __io union {
* unsigned char TCCR2;
* struct {
* unsigned char TCCR2_Bit0:1,
* TCCR2_Bit1:1,
* TCCR2_Bit2:1,
* TCCR2_Bit3:1,
* TCCR2_Bit4:1,
* TCCR2_Bit5:1,
* TCCR2_Bit6:1,
* TCCR2_Bit7:1;
* };
* struct {
* unsigned char TCCR2_CS20:1,
* TCCR2_CS21:1,
* TCCR2_CS22:1,
* TCCR2_WGM21:1,
* TCCR2_COM20:1,
* TCCR2_COM21:1,
* TCCR2_WGM20:1,
* TCCR2_FOC2:1;
* };
* } @ 0x25; |
Обратите внимание на __io.
К сожалению, я впрямую не нашёл расшифровки __io. Но также объявляются и порты pin. Например SFR_B_N(0x03, PINB, PINB7, PINB6, PINB5, PINB4, PINB3, PINB2, PINB1, PINB0)
Могу сказать, что volatile в IAR для __io не нужны. Для ARM это тоже соответствует. Тоже могу сказать и по Keil. Я думаю, GCC тоже. И врядли такой хомут будет наблюдаться в CV.
Ну кто проверит? Сделает пустой цикл на максимальном уровне оптимизации? Что-нибудь типа while(MCUSR & (1‹‹WDRF)); printf("!!!");
|
|
|
|
11.02.2013, 21:25
|
|
|
Почётный гражданин KAZUS.RUN
Регистрация: 08.06.2008
Сообщений: 1,393
Сказал спасибо: 4
Сказали Спасибо 183 раз(а) в 167 сообщении(ях)
|
Re: RESET в AVR
Сообщение от SasaVitebsk
|
|
volatile говорит о том, что переменная может быть изменена внешним способом. Это напрямую касается всех портов ввода вывода, а также регистрам проца. Бит там может быть изменён без участия программы, то есть внешним, по отношению к ней, способом.
|
Да не порите чепуху. Нет ничего "говорящего".
Volatile - это модификатор, который я (программист) пишу для того, что б компилятор не трогал эту переменную своим "умным оптимизатором" от греха подальше. И не более того. И это касается только того, что я отметил этим модификатором !!!
А при многопоточности - все лежит на Вас что б не залететь на переменных - volatile - не спасет, надо еще чуток думать.
А компилятор делает только то, что Вы ему предпишите. Самовольства там нет.
|
|
|
|
12.02.2013, 00:45
|
|
|
Гражданин KAZUS.RUN
Регистрация: 04.08.2006
Сообщений: 911
Сказал спасибо: 28
Сказали Спасибо 180 раз(а) в 139 сообщении(ях)
|
Re: RESET в AVR
Сообщение от Boba_spb
|
|
Да не порите чепуху.
|
Да не переходите на личности. 3 ссылка по поиску в инете.... "Квалификатор volatile указывает компилятору на то, что значение переменной может измениться независимо от программы, т.е. вследствие воздействия еще чего-либо, не являющегося оператором программы." Аналогично описано у Шилдта, который являлся одним из авторов стандарта. Смысл очевиден. Каждая процедура в Си является законченной. Это и хорошо и плохо. Но это отдельный разговор. Таким образом она компилится отдельно и связывается на этапе сборки Линкером. И компилятор не может знать, что переменная меняется где-то на стороне. Будь то в прерывании или в другой задаче в ОС либо внутри процесоора.
|
Цитата:
|
Volatile - это модификатор, который я (программист) пишу для того, что б компилятор не трогал эту переменную своим "умным оптимизатором" от греха подальше. И не более того. И это касается только того, что я отметил этим модификатором !!!
А при многопоточности - все лежит на Вас что б не залететь на переменных - volatile - не спасет, надо еще чуток думать.
А компилятор делает только то, что Вы ему предпишите. Самовольства там нет.
|
Всё что вы объявили, либо разработчики файла описания регистров процессора. А именно разработчики компилятора и/или разработчики производителя данного камня. Например я могу просто написать PINB; и компилятор вставит пустое чтение.
===
И надоело. Пожалуйста приводите примеры ссылки, а не просто свои выдумки и откровенный бред.
Я утверждаю что компилятор не выбросит этот регистр, если я воспользуюсь готовым файлом процессора от поставщика компилятора. И готов это доказать. Приведите пример обратного. Я потрачу время и перепроверю. Надоел безответственный трёп.
|
|
|
|
12.02.2013, 00:51
|
|
|
Почётный гражданин KAZUS.RUN
Регистрация: 08.06.2008
Сообщений: 1,393
Сказал спасибо: 4
Сказали Спасибо 183 раз(а) в 167 сообщении(ях)
|
Re: RESET в AVR
чтение куда? В регистр, в стек, в переменную ?
|
|
|
|
12.02.2013, 01:08
|
|
|
Почётный гражданин KAZUS.RUN
Регистрация: 08.06.2008
Сообщений: 1,393
Сказал спасибо: 4
Сказали Спасибо 183 раз(а) в 167 сообщении(ях)
|
Re: RESET в AVR
Ну покажите как это Ваш компиляторе делает и листинги в студию сишный и асмовский. Что ж голословно так.
Хоть узнаю что такое "голое чтение".
На AVR - правда на АSМ на такую выходку
мне пишут
D:\EKRAN_320\avr\str.asm(167): error: PINB: Unknown instruction or macro
хотя в .include "m128def.inc" есть строка " .equ PINB = $16"
|
|
|
|
12.02.2013, 10:17
|
|
|
Почётный гражданин KAZUS.RUN
Регистрация: 08.06.2008
Сообщений: 1,393
Сказал спасибо: 4
Сказали Спасибо 183 раз(а) в 167 сообщении(ях)
|
Re: RESET в AVR
Вот Вам сравнение с volatile short a; и просто short a;
А теперь объясните в чем разница с Вашей точки зрения.
Прошу заметить, что никаких запретов прерываний сам компилятор не ставит. И "дырок", где на прерываниях тут залетишь, хватает.
|
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 03:01.
|
|