Форум Микро-Чип
Поиск и заказ электронных компонентов
 

Вернуться   Форум Микро-Чип > Продукция MICROCHIP

Продукция MICROCHIP Технические вопросы по всей продукции Microchip

Ответ
 
Опции темы Опции просмотра
Старый 07.02.2008, 21:09   #1
MaxPIC
Senior Member
 
Регистрация: 02.05.2007
Возраст: 34
Сообщений: 148
Вес репутации: 387/51
MaxPIC is just really niceMaxPIC is just really niceMaxPIC is just really niceMaxPIC is just really nice
По умолчанию Проблема с PIC18F452

Отлаживаю устройство на МК PIC18F452. Работаю в среде MPLAB IDE ver. 8.00, компилятор микрочиповский C18, программатор - фирменная таблетка ICD2. Проблема в следующем. В произвольные моменты времени программа начинается выполняться с адреса 0x0000 ( определяю установкой breakpoint'а на первую команду GOTO по этому адресу). Сразу же после остановки в breakpoint'е смотрю содержание регистров RCON и STKPTR. Причин возможного сброса регистры не выявили. Перепадов напряжения на ноге MCLR также нет, смотрел осциллографом. Питание - нормальное 5 В, перепадов также нет. На всех ногах пика сигналы нормальные, острых импульсов нет нигде. Микроконтроллеры пробовал разные - результат один и тот же. Мне не понятно, если это даже сброс, то почему не "обнуляются" (устанавливаются в default'ное состояние) все регистры. Значение в них сохраняются. Также сохраняются и значения всех переменных. Вопрос - как такое может быть?
Конфигурационные биты МК:
Код:
#pragma config OSC = HSPLL   // HS-PLL Enable
#pragma config OSCS = ON     // Oscillator switch
#pragma config PWRT = OFF    // Power Up timer enable
#pragma config BOR = OFF      // Brown Out Reset enable
#pragma config BORV = 27     // Brown Out Voltage is 2.8 V
#pragma config WDT = OFF     // Watchlog Timer is OFF
#pragma config WDTPS = 128   // Watchlog Postscaler is 1:128
#pragma config CCP2MUX = ON  // CCP2 Mux enable (RC1) (If disable then RB3)
#pragma config STVR = ON     // Stack Overflow Reset is Enable
#pragma config LVP = OFF     // Low Voltage ICSP is disable (ICD2 is not support low voltage ISCP)
#pragma config DEBUG = ON     // Background Debugger Enable
#pragma config CP0 = OFF     // Code Protection Block 0 is disable
#pragma config CP1 = OFF     // Code Protection Block 1 is disable
#pragma config CP2 = OFF     // Code Protection Block 2 is disable
#pragma config CP3 = OFF     // Code Protection Block 3 is disable
#pragma config CPB = OFF     // Boot Block Code Protection is disable
#pragma config CPD = OFF     // Data EEPROM Code Protection is disable
#pragma config WRT0 = OFF     // Write Protection Block 0 is disable
#pragma config WRT1 = OFF     // Write Protection Block 1 is disable
#pragma config WRT2 = OFF     // Write Protection Block 2 is disable
#pragma config WRT3 = OFF     // Write Protection Block 3 is disable
#pragma config WRTB = OFF     // Boot Block Write Protection is disable
#pragma config WRTC = OFF     // Configuration Register Write Protection is disable
#pragma config WRTD    = OFF    // Data EEPROM Write Protection is disable
#pragma config EBTR0 = OFF   // Table Read Protection Block 0 is disable
#pragma config EBTR1 = OFF   // Table Read Protection Block 1 is disable
#pragma config EBTR2 = OFF   // Table Read Protection Block 2 is disable
#pragma config EBTR3 = OFF   // Table Read Protection Block 3 is disable
#pragma config EBTRB = OFF   // Boot Block Table Read Protection is disable
Сам код:
Код:
void main (void)
{
    Initialization();
    TRISAbits.TRISA1=0;
    TRISAbits.TRISA2=0;
    while (1)
    {
        LATAbits.LATA1=~LATAbits.LATA1;
        Rs232_Main();
        Nop();
        ClrWdt();
    }
}
Приоритетная система прерываний отключена. В прерываниях только вызов функции по таймеру1 - и всё:
Код:
#pragma code
#pragma interrupt InterruptHandlerHigh
void InterruptHandlerHigh ()
{    
    Nop();
    if ((PIR1bits.TMR1IF == (unsigned char)1) && (PIE1bits.TMR1IE == (unsigned char)1) && (IPR1bits.TMR1IP == (unsigned char)1))
    {  
        Interrupt_TMR1_High();
    }

    // Interrupt from USART
    if ((PIR1bits.RCIF==(unsigned char)1)&&(PIE1bits.RCIE == (unsigned char)1)&&(INTCONbits.PEIE == (unsigned char)1))
    {
        Rs232_Interrupt_Handler();
    }
    LATAbits.LATA2=~LATAbits.LATA2;
}
Хочу отметить, что была ещё одна проблема, которая на мой взгляд связана с вышеописанной. Дело заключается в том, что имеется сегмент кода, который выполнялся совсем неправильно. Привожу пример этого участка кода:
Код:
void Rs232_Main(void)
{
    unsigned char Received_Start_Byte;               // Принятый стартовый байт
    unsigned char Received_Command;                // Принятая команда
    unsigned char Received_ID;                          // Принятый ID
    unsigned char Received_Operand1;                // Принятый операнд 1
    unsigned char Received_Operand2;                // Принятый операнд 2
    unsigned char Received_Operand3;                // Принятый операнд 3
    unsigned char Received_Hash;                      // Принятый ХЭШ    
    unsigned char distance;                               // Расстояние между указателями Write и Read
    unsigned char a;
    // Вычисление расстояния между номером указателя на запись и чтение
    distance = (unsigned char)((Write_Pointer-Read_Pointer+BUFFER_SIZE)%BUFFER_SIZE);
    // Если расстояние равно (BUFFER_SIZE-1), то значит буфер полон
    if (distance < FRAME_LENGTH) return;
    if (distance == (unsigned char)(BUFFER_SIZE-1))
    {
        Rs232_Initialization();
        M1_Disable();
        M2_Disable();    
        // ОТКЛЮЧИТЬ ДВИГАТЕЛЬ ИЛИ ДАЖЕ СДЕЛАТЬ RESET
        return;    
    }
    if ((distance >= FRAME_LENGTH)&&(distance != (unsigned char)(BUFFER_SIZE-1)))
    {
    Received_Start_Byte=RS_232_Buffer[Read_Pointer];
    if (Received_Start_Byte == START_BYTE)
        {
            // Заполняем переменные пакета
            if (Read_Pointer == (BUFFER_SIZE - 1)) {Read_Pointer = 0;} else {Read_Pointer++;}    // INC(Read_Pointer)
            Received_ID = RS_232_Buffer[Read_Pointer];
            if (Read_Pointer == (BUFFER_SIZE - 1)) {Read_Pointer = 0;} else {Read_Pointer++;}    // INC(Read_Pointer)
            Received_Command = RS_232_Buffer[Read_Pointer];
            if (Read_Pointer == (BUFFER_SIZE - 1)) {Read_Pointer = 0;} else {Read_Pointer++;}    // INC(Read_Pointer)
            Received_Operand1 = RS_232_Buffer[Read_Pointer];
            if (Read_Pointer == (BUFFER_SIZE - 1)) {Read_Pointer = 0;} else {Read_Pointer++;}    // INC(Read_Pointer)
            Received_Operand2 = RS_232_Buffer[Read_Pointer];
            if (Read_Pointer == (BUFFER_SIZE - 1)) {Read_Pointer = 0;} else {Read_Pointer++;}    // INC(Read_Pointer)
            Received_Operand3 = RS_232_Buffer[Read_Pointer];
            if (Read_Pointer == (BUFFER_SIZE - 1)) {Read_Pointer = 0;} else {Read_Pointer++;}    // INC(Read_Pointer)
            Received_Hash = RS_232_Buffer[Read_Pointer];
            if (Read_Pointer == (BUFFER_SIZE - 1)) {Read_Pointer = 0;} else {Read_Pointer++;}    // INC(Read_Pointer)
            // Вычисляем Хеш
            a = Calculate_Hash(Received_Command,Received_ID,Received_Operand1,Received_Operand2,Received_Operand3);
            if ((a)==Received_Hash)
            {
                Frame_Processing(Received_Command,Received_ID,Received_Operand1,Received_Operand2,Received_Operand3);
            }
            else    /// temp_Hash != Received_Hash
            {
                // Неправильный Хеш. Отправляем ошибку.
                Send_Hash_Error();
                return;
            }
        }
    else // Received_Start_Byte != START_BYTE
        {
            if (Read_Pointer == (BUFFER_SIZE - 1)) {Read_Pointer = 0;} else {Read_Pointer++;}    // INC(Read_Pointer)    
        }
    }
}
Функция вычисления Хеша:
Код:
unsigned char Calculate_Hash(unsigned char N1, unsigned char N2, unsigned char N3, unsigned char N4, unsigned char N5)
{
    return(N1^N2^N3^N4^N5);
}
Данный код выполнялся при входных данных
137h Received_Command 0x90
138h Received_ID 0x04
139h Received_Operand1 0x00
13Ah Received_Operand2 0x00
13Bh Received_Operand3 0x00
13Ch Received_Hash 0x94
часто с результатом a=0x94, но иногда с a=0x04. В качестве доказательства своих слов привожу картинку из MPLAB'а, где таблеткой увидел через Watch неправильное значение. Думал может переполнение программного стека (он там по умолчанию 256 байт). Сделал его 1024 байта (галочку Multibank включил, т.е. компилятор работает с параметром -ls). Эффект пропал. Выполняться стало правильно, но первая проблема не устранилась. Кстати попутно такой вопрос: а как-нибудь можно определить переполнение программного стека другим способом?
Миниатюры
problem.GIF  
MaxPIC вне форума   Ответить с цитированием
Старый 08.02.2008, 15:36   #2
2AplusA
Senior Member
 
Аватар для 2AplusA
 
Регистрация: 26.02.2007
Адрес: Penza
Возраст: 38
Сообщений: 1,383
Вес репутации: 1267/73
2AplusA has much to be proud of2AplusA has much to be proud of2AplusA has much to be proud of2AplusA has much to be proud of2AplusA has much to be proud of2AplusA has much to be proud of2AplusA has much to be proud of2AplusA has much to be proud of2AplusA has much to be proud of
По умолчанию Re: Проблема с PIC18F452

Цитата:
Сообщение от MaxPIC Посмотреть сообщение
Думал может переполнение программного стека (он там по умолчанию 256 байт). Сделал его 1024 байта (галочку Multibank включил, т.е. компилятор работает с параметром -ls). Эффект пропал. Выполняться стало правильно, но первая проблема не устранилась. Кстати попутно такой вопрос: а как-нибудь можно определить переполнение программного стека другим способом?
Что-то уж он больно большой стек-то получается! Поставьте в настройках, default srorage class - static, вместо auto. И тогда 256 байт за глаза хватит! Посмотрите в дизассемблерном коде нечто подобное
Код:
 goto 0x0000
Потому что очень странно, что сброс не устанавливает по умолчанию SFR - регистры.
__________________
Лучше день потерять, потом за час долететь!
2AplusA вне форума   Ответить с цитированием
Старый 09.02.2008, 12:45   #3
MaxPIC
Senior Member
 
Регистрация: 02.05.2007
Возраст: 34
Сообщений: 148
Вес репутации: 387/51
MaxPIC is just really niceMaxPIC is just really niceMaxPIC is just really niceMaxPIC is just really nice
По умолчанию Re: Проблема с PIC18F452

Static для всех переменных ставил - не помогает.
Все Goto переходы проверил в дизасемблере -нет перехода в ноль. Ставил breakpoint в свободный код памяти программ, вдруг вылетает за пределы программы, ничего не происходит, т.е. в breakpoint не попадает, просто опять начинает выполняться с нуля. В соответствии с errat'ой даже отключил приоритетную систему прерываний, ничего не помогает. Что ещё предпринять - не знаю. Заново прогу переписывать уж очень не хочется, много, долго и нет гарантии, что эта проблема не повторится.
MaxPIC вне форума   Ответить с цитированием
Старый 09.02.2008, 14:43   #4
IceS
Super Moderator
 
Регистрация: 01.03.2007
Адрес: St. Petersburg
Возраст: 41
Сообщений: 3,246
Вес репутации: 3684/116
IceS has a reputation beyond reputeIceS has a reputation beyond reputeIceS has a reputation beyond reputeIceS has a reputation beyond reputeIceS has a reputation beyond reputeIceS has a reputation beyond reputeIceS has a reputation beyond reputeIceS has a reputation beyond reputeIceS has a reputation beyond reputeIceS has a reputation beyond reputeIceS has a reputation beyond repute
Отправить сообщение для IceS с помощью ICQ
По умолчанию Re: Проблема с PIC18F452

Подобная лажа была, правда я тогда 16 пик отлаживал с помощью ICD1 , решилось подключением внешнего источника питания для отладчика.
Т.е. пик питался от своего источника, а отладчик от своего, может и у вас по питанию что либо прет?

PS а ножки, к которым отладчик подлючен, в схеме не используются? может выставляется на них какой-нить уровень, отладчик не может с чипом связаться и перезапускает его?
IceS вне форума   Ответить с цитированием
Старый 09.02.2008, 21:47   #5
MaxPIC
Senior Member
 
Регистрация: 02.05.2007
Возраст: 34
Сообщений: 148
Вес репутации: 387/51
MaxPIC is just really niceMaxPIC is just really niceMaxPIC is just really niceMaxPIC is just really nice
По умолчанию Re: Проблема с PIC18F452

Отладчик подключён к ПК через USB. Ноги программирования нигде в программе и в схеме соответственно не используются, кроме как для ICD2. Плата питается от отдельного источника, земля которого соединена с землёй ПК. Все сигналы на пике нормальные, смотрел осциллографом относительно земляной ножки пика.
MaxPIC вне форума   Ответить с цитированием
Ответ


Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
 
Опции темы
Опции просмотра

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
проблема с обновлением pickit2 ctef Продукция MICROCHIP 13 25.08.2008 18:16
Проблема SPI slave с SS enabled у PIC18F452 murug Продукция MICROCHIP 6 28.05.2008 22:38
Связь AD5662 c PIC18F452 Equene Продукция MICROCHIP 9 26.05.2008 05:51
проблема с генератором PIC18F65J10 Lexi Продукция MICROCHIP 28 20.03.2008 17:26
PIC18F452 HELP Mihail Продукция MICROCHIP 10 31.12.2007 15:40


Часовой пояс GMT +3, время: 11:20.


Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd. Перевод: zCarot