ПРоблема следующая - определенное сочетание некоторых строк кода вызывает постоянный ресет.
Пройденные и уже обсуждавшиеся грабли:
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"); //врубаем прерывания - и происходит ресет
}
#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.