Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: PIC16F876A капризничает
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > Все остальные микроконтроллеры > PIC
Scrambler
Доброго времени суток, коллеги!

Прошу помощи, т.к. сам уже 2 дня бьюсь и безрезультатно. Может, всезнающий All
поможет...

Одна и та же программа (за исключением инита компараторов и источника опорного
напряжения, которых нет не в "A" серии, а также значения слова конфигурации)
работает на 87x, но глючит на 876A.
Конфигурация везде идентичная: генератор HS, без WDT, с POR, без BOR, память не
защищена, без LVP.

Даташит изучал еще и еще раз, читал всякие Errata, предпринял уже, наверное, все,
что можно. Уже даже дошел до того, что запустил девайс на 2 мегагерцах (думал, мало
ли 876A не тянет 18 мегагерц).

Котнроллеры прошиваются и верифицируются на ура (и 873, и 876, и 876A). Но 873 и
876 работают полностью как задумано, а 876A глючит.

Идея проста - нужен девайс :) Вернее, целых 5.
Девайс представляет собой некую камеру с транспортером и дверцой. В него
загружаются исследуемые блоки. В камере будут 6 датчиков (среди них и цифра, и
аналог). Исходя из того, что из 6 будет как минимум 1 цифровой, я выбрал PIC16F876
для данного девайса (5 каналов АЦП). Т.к. в магазине не было 876 в соиках, взял
876A в соиках и 1 в дипе на макетку.

Итак, что мы имеем? А имеем вот что (873 и 876 валялись в закромах):

* PIC16F873 DIP28 - 1 штука
* PIC16F876 DIP28 - 1 штука
* PIC16F876A DIP28 - 1 штука
* PIC16F876A SO28 - 5 штук

* упрощенная программа - 1 штука.

В общих чертах алгоритм такой:
Есть 3 датчика положения блока и 1 кнопка. Датчики расположены вдоль линии загрузки
исследуемого объекта. Дверца закрыта.
1) При срабатывании 1-го датчика нужно открыть дверцу, запустить мотор транспортера
(внутрь), дождаться срабатывания 3-го датчика, выключить мотор и закрыть дверцу.
Если выключится 1 датчик, но не сработает второй (объект поднесли к дверце а потом
убрали) нужно также остановить мотор и закрыть дверцу.
2) Собирать информацию с датчиков, попутно посылая ее по UART'у.
3) При нажатии кнопки если активен второй датчик, открыть дверцу, запустить мотор
транспортера (наружу), ждать, пока объект выйдет из зоны действия 2-го датчика,
остановить мотор, ждать когда объект уберут, закрыть дверцу.

Дверцу я убрал, обработку датчиков и работу с UART тоже. Осталась простенькая
программка:
Обрабатываются кнопка (RB4) и датчики положения (RB5-RB7).
При срабатывании кнопки или датчика запускается таймер1, отсчитывает время дребезга
контактов. На прерывании таймера я анализирую кнопки и датчики.

Итак, вот в чем выражается глюк:
При срабатывании 1-го датчика заводится двигатель. Если объект убрать -
останавливается. Тут все без вопросов. Если объект продвинуть до транспортера, то,
стоит объекту доехать до 2-го датчика, мотор останавливается и контроллер перестает
на что-либо реагировать (зависает?). Если объект вытащить и снова поднести к 1
датчику - мотор уже не включится. :(
Если же питание на контроллер подать в момент, когда объект уже загружен, по кнопке
он его выплюнет, все нормально. Потом даже снова даст вставить, но опять "довезет"
только до 2-го датчика.
Кнопка и 3 датчик - это просто кнопки, включенные между землей и ногами
котнроллера. Датчики 1 и 2 - оптические с открытым стоком на выходе. Pull-up
резисторы на PORTB включены.

Компилятор HI-TECH PICC COMPILER (Microchip PIC) V8.05PL2

Код
#include <pic.h>


#define M_OUT            RB1
#define M_IN            RB2

#define BLOCK_OUT()        { M_OUT=1; M_IN=0; }
#define BLOCK_IN()            { M_OUT=0; M_IN=1; }
#define BLOCK_HOLD()        { M_OUT=0; M_IN=0; }

#define BTN            RB4
#define SENS1            RB5
#define SENS2            RB6
#define SENS3            RB7

#define TRISA_CONST        0b00000011
#define TRISB_CONST        0b11110000
#define TRISC_CONST        0b00000000

#define PORTA_CONST        0b00100000
#define PORTB_CONST        0b00000000
#define PORTC_CONST        0b00100000


bit bEject;
bit bKeypress;



void init_all();
void ScanSensors();




void main()
{
    GIE=0;
    init_all();

    bEject=0;
    bKeypress=0;

    GIE=1;

    while(1)
    {
        ScanSensors();
    }
}

void interrupt ISRproc()
{
    char t;

    // Debounce completed
    if(TMR1IF && TMR1IE)
    {
        bKeypress=1;
        TMR1IE=0;
    }

    // Button pressed
    if(RBIF)
    {
        if(!TMR1IE)
        {
            TMR1L=0;
            TMR1H=0;
            TMR1IF=0;
            TMR1IE=1;
        }

        t=PORTB;  // чтение порта B, чтобы сбросить mismatch condition
        RBIF=0;
    }

}



void init_all()
{
    TRISA=TRISA_CONST;
    PORTA=PORTA_CONST;
    TRISB=TRISB_CONST;
    PORTB=PORTB_CONST;
    TRISC=TRISC_CONST;
    PORTC=PORTC_CONST;

    OPTION=0b00000000;        // PU en, internal T0 1:2, page 23
    INTCON=0b01001000;        // periph, RB int en, page 24
    PIE1=0b00000000;    
    PIR1=0x00;
    PR2=50;
    PIE2=0b00000000;        // no ints, page 27
    PIR2=0x00;
    T1CON=0b00000001;        // T1 en, 1:1, internal, page 57
    T2CON=0b00000000;
    CCP1CON=0x00;
    CCP2CON=0x00;            // CCP mods dis, page 64
    SSPCON=0x00;            // SSP dis, page 73
    TXSTA=0;
    RCSTA=0;
    SPBRG=0;
    ADCON0=0b11000001;        // Fosc/32, CH0, ADC en, page 127
    ADCON1=0b00000100;        // LJ, Fosc/32, 3:0, page 128
#ifdef _16F876A
    CMCON=0b00000111;        // CM dis, page 135-136
    CVRCON=0x00;            // VR dis, page 141
#endif
}


void ScanSensors()
{
    if(!bKeypress)
        return;
    bKeypress=0;

    if(bEject)
    {
        if(SENS2!=0)
        {
            BLOCK_HOLD();
            bEject=0;
            return;
        }
    }
    else
    {
        if(BTN==0)
        {
            if(SENS2==0)
            {
                bEject=1;
                BLOCK_OUT();
                return;
            }
        }
        if(SENS3==0)
        {
            BLOCK_HOLD();
            return;
        }
        if(SENS1==0)
        {
            BLOCK_IN();
            return;
        }
    }

    if(SENS1!=0 && SENS2!=0 && SENS3!=0)
    {
        BLOCK_HOLD();
    }
}


В чем может быть загвоздка, подскажите, пожалуйста.
Может ли быть дело в контроллере?
Scrambler
Новые вести с поля битвы...

Я просто в шоке, дорогие коллеги.

Перепаял макетную плату немного - включил датчик 2 через джампер.

Итак:
1) Размыкаем джампер - отключаем датчик 2 от RB6. Подносим блок - включается
двигатель. Ставим блок на транспортер - он доезжает до задней стенки, замыкает
датчик 3, мотор останавливается.
2) Замыкаем джампер - подключаем датчик 2 к RB6. Нажимаем кнопку. Мотор включается,
объект доезжает до момента выключения датчика 2 и останавливается.
3) Размыкаем джампер. Вынимаем блок и снова подносим к датчику 1. Мотор включается.
...
...
...

Поменял местами 1 и 2 датчики - результат тот же самый - при постоянно замкнутом
джампере виснет, а если на время загрузки джампер размыкать, то все ок.

То есть, получается, зависание происходит при срабатывании датчика 2, но только при
каких-то условиях. Но при каких?
Неужели контроллер зависает, если, например, появляется 0 на RB6, но только при
условии что RB5=0, BR7=1 и т.д. ?
Бред какой-то...
LordN
на микрочипе.ру, в конфе, был чей-то спич про такой или подобный глюк с RB6. точно не помню, но вроде лечится включением пулл-апа на этой ноге и посл.сопротивлением.
Alex B._
http://www.microchip.ru/phorum/read.php?f=...117356&t=117356

Вешайте 22-100 pF на RB6 на землю и забудьте
ssps
Тоже около этой темы:
Превезли два чипа PIC16F876A так я не понял что у них с ногой RB6 - постояно выставлена логическая единица (около 5v)
Как не пытался включать или выключать - именно RB6 не реагирует.
Перешел на PIC16F877A - все нормально - все порты работают как надо.
По даташитам тоже ничего не нашел про это.
Кто-нибудь сталкивался с этим?
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.