Прошу помощи, т.к. сам уже 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();
}
}
#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();
}
}
В чем может быть загвоздка, подскажите, пожалуйста.
Может ли быть дело в контроллере?