AVR Раздел по микроконтроллерам компании Atmel - AVR / ATtiny / ATmega / ATMega128 / ATxmega, вопросы по программированию в AVR studio и все, относящееся к AVR... |
09.02.2013, 10:26
|
|
Почётный гражданин KAZUS.RU
Регистрация: 25.05.2010
Адрес: г. Королёв
Сообщений: 8,497
Сказал спасибо: 30
Сказали Спасибо 3,072 раз(а) в 2,013 сообщении(ях)
|
Re: RESET в AVR
Сообщение от SasaVitebsk
|
MCUSR не переменная а регистр процессора.
|
Вы это мне объясняете?
Сообщение от SasaVitebsk
|
И он volatile по определению.
|
![Нажмите на изображение для увеличения
Название: Image1.jpg
Просмотров: 71
Размер: 18.5 Кб
ID: 43376](https://kazus.ru/forums/attachment.php?attachmentid=43376&thumb=1&d=1360390869)
хде именно?
MCUSR в программе нигде не изменяется, поэтому компилятор вполне может выкинуть (соптимизировать) его чтение, если переменную, в которую он считывается, не объявить volatile.
ТС хочет непременно читать этот регистр, хотя он ему нафиг не нужен.
|
|
|
|
09.02.2013, 13:21
|
|
Почётный гражданин KAZUS.RU
Регистрация: 20.03.2007
Адрес: "Братское кольцо враждебности", т.е. ближайшее заМКАДье.
Сообщений: 6,916
Сказал спасибо: 2,980
Сказали Спасибо 3,161 раз(а) в 2,146 сообщении(ях)
|
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.RU
Регистрация: 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.RU
Регистрация: 08.06.2008
Сообщений: 1,394
Сказал спасибо: 4
Сказали Спасибо 183 раз(а) в 167 сообщении(ях)
|
Re: RESET в AVR
Сообщение от SasaVitebsk
|
volatile говорит о том, что переменная может быть изменена внешним способом. Это напрямую касается всех портов ввода вывода, а также регистрам проца. Бит там может быть изменён без участия программы, то есть внешним, по отношению к ней, способом.
|
Да не порите чепуху. Нет ничего "говорящего".
Volatile - это модификатор, который я (программист) пишу для того, что б компилятор не трогал эту переменную своим "умным оптимизатором" от греха подальше. И не более того. И это касается только того, что я отметил этим модификатором !!!
А при многопоточности - все лежит на Вас что б не залететь на переменных - volatile - не спасет, надо еще чуток думать.
А компилятор делает только то, что Вы ему предпишите. Самовольства там нет.
|
|
|
|
12.02.2013, 00:45
|
|
Гражданин KAZUS.RU
Регистрация: 04.08.2006
Сообщений: 911
Сказал спасибо: 28
Сказали Спасибо 180 раз(а) в 139 сообщении(ях)
|
Re: RESET в AVR
Сообщение от Boba_spb
|
Да не порите чепуху.
|
Да не переходите на личности. 3 ссылка по поиску в инете.... "Квалификатор volatile указывает компилятору на то, что значение переменной может измениться независимо от программы, т.е. вследствие воздействия еще чего-либо, не являющегося оператором программы." Аналогично описано у Шилдта, который являлся одним из авторов стандарта. Смысл очевиден. Каждая процедура в Си является законченной. Это и хорошо и плохо. Но это отдельный разговор. Таким образом она компилится отдельно и связывается на этапе сборки Линкером. И компилятор не может знать, что переменная меняется где-то на стороне. Будь то в прерывании или в другой задаче в ОС либо внутри процесоора.
Цитата:
|
Volatile - это модификатор, который я (программист) пишу для того, что б компилятор не трогал эту переменную своим "умным оптимизатором" от греха подальше. И не более того. И это касается только того, что я отметил этим модификатором !!!
А при многопоточности - все лежит на Вас что б не залететь на переменных - volatile - не спасет, надо еще чуток думать.
А компилятор делает только то, что Вы ему предпишите. Самовольства там нет.
|
Всё что вы объявили, либо разработчики файла описания регистров процессора. А именно разработчики компилятора и/или разработчики производителя данного камня. Например я могу просто написать PINB; и компилятор вставит пустое чтение.
===
И надоело. Пожалуйста приводите примеры ссылки, а не просто свои выдумки и откровенный бред.
Я утверждаю что компилятор не выбросит этот регистр, если я воспользуюсь готовым файлом процессора от поставщика компилятора. И готов это доказать. Приведите пример обратного. Я потрачу время и перепроверю. Надоел безответственный трёп.
|
|
|
|
12.02.2013, 00:51
|
|
Почётный гражданин KAZUS.RU
Регистрация: 08.06.2008
Сообщений: 1,394
Сказал спасибо: 4
Сказали Спасибо 183 раз(а) в 167 сообщении(ях)
|
Re: RESET в AVR
чтение куда? В регистр, в стек, в переменную ?
|
|
|
|
12.02.2013, 01:08
|
|
Почётный гражданин KAZUS.RU
Регистрация: 08.06.2008
Сообщений: 1,394
Сказал спасибо: 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.RU
Регистрация: 08.06.2008
Сообщений: 1,394
Сказал спасибо: 4
Сказали Спасибо 183 раз(а) в 167 сообщении(ях)
|
Re: RESET в AVR
Вот Вам сравнение с volatile short a; и просто short a;
А теперь объясните в чем разница с Вашей точки зрения.
Прошу заметить, что никаких запретов прерываний сам компилятор не ставит. И "дырок", где на прерываниях тут залетишь, хватает.
|
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 09:16.
|
|