|
|
  |
Глобальное разрешение прерываний и SPI одновременно => сброс контроллера, не могу их подружить |
|
|
|
Sep 2 2008, 17:02
|
Местный
  
Группа: Свой
Сообщений: 413
Регистрация: 15-12-06
Пользователь №: 23 563

|
Господа, открываю отдельную ветку специально для возникшей проблемы, обсуждавшейся в соседней теме про измерение длины импульса, здесь - http://electronix.ru/forum/index.php?showtopic=52057. ПРоблема следующая - определенное сочетание некоторых строк кода вызывает постоянный ресет. Пройденные и уже обсуждавшиеся грабли: 1. сторожевой таймер - отключен, отключался принудительно, при загрузке судя по WDTCR он отключен. Манипуляции со сторожем не влияют на ситуацию. 2. Ресет из-за проблем на входе RESET контроллера. По совету подключил резистор 4,7 к от RESET к + питания. Конденсатор не нашел, паять не стал. ПРи загрузке в регистре MCUCSR бит сброса по низкому уровню на ресет то сброшен, то установлен. ПРосьба не советовать мне копать в этом направлении ибо не зависимо от состояни этого бита работа контроллера одинакова. А при изменении кода определенным образом контроллер не сбрасывает даже при отсутствии подклчюения RESET к питанию через резистор. Итак программа представляет собой следующее (подробнее ниже): 1 .инициализации портов D и С для использования подключенных к ним диодов в качестве маячков 2. инициализация SPI 3. отправка байта по SPI 4. глобальное разрешение прерываний так вот если одновременно присутствуют пункты 2,3,4 происходит ресет контроллера. Что-нибудь одно убираем - все ОК. 3 часа перелопачивал код, убирал незначащие фрагменты, в итоге получил коротенькую дефектную программу, вызывающую постоянный ресет контроллера. Код #include <mega32.h> #include <delay.h> #include <stdio.h>
#define LCD_PORT PORTB // #define LCD_DDR DDRB //
#define LCD_RS 4 #define LCD_MOSI 5 #define LCD_MISO 6 #define LCD_SCK 7
#define SPI2X 0
#define SPR0 0 #define SPR1 1 #define SPHA 2 #define SPOL 3 #define MSTR 4 #define DORD 5 #define SPE 6 #define SPIE 7
void main(void) {
//WDTCR=0x18; // это отключение //WDTCR=0x00; // сторожевого барбоса. Не влияет на ситуацию
DDRD=0xFF; // здесь выводим состояние MCUCSR PORTD=MCUCSR; // на подключенные к порту светодиоды. На ресет у меня только резистор, советуемого конденсатора не подключал
DDRC=0xFF; // маркер старта контроллера PORTC=0xFF; // если контроллер постоянно ресетит, то диоды горят постоянно delay_ms(500); // через 500 мс DDRC=0x00; // отключаем - если погасло насовсем, значит ресета не происходит
LCD_DDR.LCD_MOSI=1; // MOSI must be set as output for SPI LCD_PORT.LCD_MOSI=1; // MOSI must be set as output for SPI LCD_PORT.LCD_SCK =0; // set SCK low LCD_DDR.LCD_SCK=1; // set SCK as output LCD_PORT.LCD_MISO=1; // enable pull up of MISO to avoid floating input
// а вот здеcь интересно - можно не включать PORTB.4 (LCD_RS) - проблема появляется только тогда, когда DDR установлен в 1. // LCD_PORT.LCD_RS=1; // RS=high LCD_DDR.LCD_RS=1; // RS is output
SPCR = (1<<SPE)|(1<<MSTR)|(0<<SPR1)|(0<<SPR0); SPSR = (1<<SPI2X);
// ниже asm текст из функции отправляюще байт. //АКЦЕНТИРУЮ ВАШЕ ВНИМАНИЕ: // в данном случае передаваемому байту взяться неоткуда, это выдрано из функции, в параметры которой передавался байт. // данный код и в представленном виде и будучи помещенным в функцию одинаково влияет на поведение контроллера. // так что проблема возникает при самом факте отправления чего либо, а не с содержанием отправляемой информации. // если не сокрщать программу, а использовать всю билиотеку - SPI работает нормально, что подтверждается корректной работой ЖКИ #asm ld r26,y
sbi 0xd,7 out 0xf,r26 SPI_SEND_2: sbis 0xe,7 rjmp SPI_SEND_2 sbi 0x18,2
#endasm
#asm("sei"); //врубаем прерывания - и происходит ресет
} ФЬЮЗЫ: OSCCAL = CC, CB, C5, C5 BLEV = 1 BODEN = 1 SUT = 2 CKSEL = F BLB1 = 3 BLB0 = 3 OCDEN = 1 JTAGEN = 1 CKOPT = 0 EESV = 1 BSIZ = 0 BRST = 1 В аттаче скриншот с настройками проекта в CodeVision.
Эскизы прикрепленных изображений
|
|
|
|
|
Sep 2 2008, 17:40
|

Нечётный пользователь.
     
Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417

|
Цитата(Зверюга @ Sep 2 2008, 20:02)  3 часа перелопачивал код, убирал незначащие фрагменты, в итоге получил коротенькую дефектную программу, вызывающую постоянный ресет контроллера. Код void main(void) {
... #asm("sei"); //врубаем прерывания - и происходит ресет } Ну именно этот, приведённый тут код, выглядит странно. Хоть бы for(;;); перед закрывающей main() фигруной скобкой. Куда пойдёт в CV программа после выхода из main() ? В avr-gcc она на нулевой адрес и перейдёт. А так - не знаю. Если при разрешении прерываний бяка - не знаю, как у CV с незадействованными в програме векторами работа идёт, но вдруг ненароком прерывание разрешается (проверьте mega32.h на правильность определения битов, может вместо какого SPR0 включается SPIE) и возникает, а обработчика нет.
--------------------
Ну, я пошёл… Если что – звоните…
|
|
|
|
|
Sep 2 2008, 17:52
|
Местный
  
Группа: Свой
Сообщений: 413
Регистрация: 15-12-06
Пользователь №: 23 563

|
Цитата Куда пойдёт в CV программа после выхода из main() ? В avr-gcc она на нулевой адрес и перейдёт. Простите меня, но вы нелогичны))) Вы пишите что пр отсутствии цикла for(;;) программа должна перейти на нулевой адрес. Я же писал о том что некоторые манипуляции с кодом НЕ СВЯЗАННЫЕ С ЗАЦИКЛИВАНИЕМ устраняют постоянный ресет. Тогда причем здесь зацикливание? Справедливости ради скажу, что зацикливание раньше в прорамме было и ресет при нем был. Зацикливание убрал для упрощения кода. Цитата (проверьте mega32.h на правильность определения битов, может вместо какого SPR0 включается SPIE) и возникает, а обработчика нет. Ну вот опять.... имеет смысл ваше предположения учитывая что я писал: "если не сокрщать программу, а использовать всю билиотеку - SPI работает нормально, что подтверждается корректной работой ЖКИ"? Повнимательней пожалуйста )))
|
|
|
|
|
Sep 2 2008, 18:27
|

фанат дивана
     
Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684

|
Цитата(Зверюга @ Sep 2 2008, 23:52)  Простите меня, но вы нелогичны))) ... Я же писал о том что некоторые манипуляции с кодом НЕ СВЯЗАННЫЕ С ЗАЦИКЛИВАНИЕМ устраняют постоянный ресет. Тогда причем здесь зацикливание? ... Ну вот опять.... имеет смысл ваше предположения учитывая что я писал: ... Вы часом не юрист? Уж больно грамотно юлите  Однако тут у вас немного другая задача, надо не запутать всё до предела, и не уличить оппонентов в невнимании, а вовсе даже наоборот, всё прояснить и во всём разобраться  И люди, которые пишут - не оппоненты вовсе, а хотят вам помочь (ну, кроме меня конечно  ) По сути. Пример кривой, стало быть выводы на его основе некорректны. Отмазки типа "был цикл" - не принимаются. Надо новый пример, снова всё проверить, все эти 1, 2, 3 и 4.
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Sep 2 2008, 19:14
|
Местный
  
Группа: Свой
Сообщений: 413
Регистрация: 15-12-06
Пользователь №: 23 563

|
Цитата Вы часом не юрист? Я судмедэксперт. В судах иногда в такие баталии с юристами приходится вступать, что приходится приспосабливаться, так что интуиция вас не подвела. Цитата Отмазки типа "был цикл" - не принимаются. Надо новый пример, снова всё проверить, все эти 1, 2, 3 и 4. Так я прежде чем писать снова цикл поставил и проверил))) Общение с юристами приучило))) В общем странная фишка получается - манипулирую с LCD_PORT.LCD_RS и LCD_DDR.LCD_RS - комментироваине этих строк решает проблему, но выключает ЖКИ. ПРичем какую-то непостижимую роль играет номер бита 4 - пересадил ножку RS на PORTA.0 - Проблема исчезла, но ЖКИ не захотел работать. Пересадил на PORTA.4 - ЖКИ заработал, но проблема появилась вновь... Цитата Отмазки типа "был цикл" - не принимаются. Вы как плохие из моих коллег врачей - с чем бы к ним ни пришел - попейте анальгин, не поможет - аспирин, через неделю приходите. Я расписал все как мог. И если я вижу, что совет противоречит тому что написано, я вправе сделать вывод, что мой пост не читали. Уж извините, я не хочу здесь накалять обстановку, но просто по опыту общения на форумах знаю, что хоть я и написал про "грабли", про сторожевой таймер, про RESET - еще не один человек в теме мне на это укажет. Проверил еще раз с циклом - не заработало. Что делать и кто виноват?
|
|
|
|
|
Sep 2 2008, 20:16
|

фанат дивана
     
Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684

|
Цитата(Зверюга @ Sep 3 2008, 01:14)  Я судмедэксперт. В судах иногда в такие баталии с юристами приходится вступать, что приходится приспосабливаться, так что интуиция вас не подвела. Ну тут всё же не там  Попроще надо. Цитата Вы как плохие из моих коллег врачей - с чем бы к ним ни пришел - попейте анальгин, не поможет - аспирин, через неделю приходите. Я пока лишь попросил поточнее описать симптомы и направил на анализы. Чтоб не делать поспешных выводов. Имхо так делают как раз хорошие из ваших коллег  Цитата Я расписал все как мог. И если я вижу, что совет противоречит тому что написано, я вправе сделать вывод, что мой пост не читали. Уж извините, я не хочу здесь накалять обстановку, но просто по опыту общения на форумах знаю, что хоть я и написал про "грабли", про сторожевой таймер, про RESET - еще не один человек в теме мне на это укажет. Ну что поделать, форум - он и есть форум. Человек читает сообщение, опытный взгляд видит явный ляп - и естественно считает, что причина в этом. Мало кто читал всю предысторию, тем более, что вы вынесли обсуждение в новую тему. Цитата Проверил еще раз с циклом - не заработало. Что делать и кто виноват? Давайте сделаем такой анализ: поставьте на все прерывания в системе заглушки. Пустые обработчики. Можно в них взводить какой-нибудь флажок. Можно выводить флажок на экран. Не суть. И посмотрите, перестанет зависать или нет. ........ Кажись нашёл. В spi_send() строчка Код sbi 0xd,7 как раз и включает прерывание от SPI. 0x0D - это SPCR, бит 7 - SPIE. Уберите её, она не нужна.
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Sep 3 2008, 03:12
|
Местный
  
Группа: Свой
Сообщений: 413
Регистрация: 15-12-06
Пользователь №: 23 563

|
Цитата sbi 0xd,7 ВЫ ГЕНИЙ! ЗАРАБОТАЛО! СПАСИБО! Только я не пойму, строка включала прерывание, что было неправильно, но почему исход был такой грубый - ресет?
|
|
|
|
|
Sep 3 2008, 05:17
|

Нечётный пользователь.
     
Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417

|
Цитата(Зверюга @ Sep 2 2008, 20:52)  Цитата(ReAl @ Sep 2 2008, 20:40)  А так - не знаю. Если при разрешении прерываний бяка - не знаю, как у CV с незадействованными в програме векторами работа идёт, но вдруг ненароком прерывание разрешается (проверьте mega32.h на правильность определения битов, может вместо какого SPR0 включается SPIE) и возникает, а обработчика нет. Ну вот опять.... имеет смысл ваше предположения учитывая что я писал: "если не сокрщать программу, а использовать всю билиотеку - SPI работает нормально, что подтверждается корректной работой ЖКИ"? Повнимательней пожалуйста ))) Цитата(AHTOXA @ Sep 2 2008, 23:16)  Кажись нашёл. В spi_send() строчка Код sbi 0xd,7 как раз и включает прерывание от SPI. 0x0D - это SPCR, бит 7 - SPIE. Уберите её, она не нужна. Цитата(Зверюга @ Sep 3 2008, 06:12)  ВЫ ГЕНИЙ! ЗАРАБОТАЛО! СПАСИБО! Только я не пойму, строка включала прерывание, что было неправильно, но почему исход был такой грубый - ресет? Ну и? При всей своей невнимательности я с самого начала посоветовал присмотреться к SPIE. Правда, не думал, что ляп в самой библиотеке, ожидал описку где-то во включаемых файлах. Так что направление поиска я указал правильно, а внимательно вычитывать код какой-то ненужной мне библиотеки от какого-то ненужного мне компилятора я и не собирался. Цитата(Зверюга @ Sep 3 2008, 07:57)  Тогда ваше предположение - чего хотел добиться автор кода этой строкой? Возможно, для Вас лично будет полезнее помедитировать над тем, как и почему при отсутствии обработчика включенного прерывания программа иногда работала (и что было основанием для упрёков в мой адрес). Может, в следующий раз вместо обвинений в невнимательности будете прислушиваться. За сим откланиваюсь.
--------------------
Ну, я пошёл… Если что – звоните…
|
|
|
|
|
Sep 3 2008, 05:25
|
Местный
  
Группа: Свой
Сообщений: 413
Регистрация: 15-12-06
Пользователь №: 23 563

|
Цитата и что было основанием для упрёков в мой адрес Да ладно, извините меня, был неправ. Почитайте предыдущую тему - я 3 дня до красных глаз бился над этой проблемой, представил ее как мог, а тут советы попробовать то, что я уже делал. Спасибо и Вам за Ваши советы.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|