por chipselect » 11 Nov 2009 10:34
Estou com um problema na UART do PIC, tem um caracter que ele não recebe direito (0x80) e alguns falham ocasionalmente (0x10, 0xC2, 0x08).
O maior problema é o 0x80, porque os demais (0x10, 0xC2...) a flag FERR é ativa e eu consigo tratar o erro, mas o 0x80 recebe "normalmente" como 0x00... parece que o PIC perde o start bit, acha que o primeiro 1 ainda é space e que o primeiro bit 0 é start bit e o resto ele, de alguma forma, encara como 7 bits 0 e 1 stop bit correto)
Demais caracteres recebe normalmente, principalmente 0xAA
Microcontrolador: PIC16F914
Teste efetuado:
PC enviando o mesmo caracter a cada 0,1 segundos para teste.
O microcontrolador somente envia o que recebe de volta (echo).
Compilador: Hitec PICC em Lite Mode
Fiz o teste para cada caracter problemático e para alguns caracteres que não deram problemas (como 0xaa, 0x55, 0xff)
Código de inicialização:
[code]
__CONFIG(INTIO & WDTDIS & PWRTEN & MCLREN & UNPROTECT & UNPROTECT & BORDIS & IESODIS & FCMDIS & DEBUGDIS);
// Peripheral initialization function
void init(void){
/***** Common Code ****
* Timer 1 interrupt enabled.
* Timer 2 interrupt disabled.
* Usart TX interrupt disabled.
* Usart RX interrupt enabled.
*/
PIE1 = 0b00100001;
/*
* Timer 0 interrupt disabled.
* Peripheral interrupts enabled
* Global interrupt disabled during initialization
*/
INTCON = 0b01000000;
/*
* Timer 0 is prescaled by 1:2
* Timer 0 is clocked internally.
*/
OPTION = 0b00000000;
/***** 16F914 Code ****
* Internal oscillator set to 8MHz
*/
OSCCON = 0b01110000;
/***** Timer 1 Code ****
* Timer is active and running
* Timer prescaler is 1:8
* Timer 1 gate control is not selected
* Gate control signal is not inverted
*/
T1CON = 0b00110001;
/***** Timer 2 Code ****
* Prescale ratio is 1:1
* Timer 2 is suspended
* Postscale ratio set to 1:1
*/
T2CON = 0b00000000;
/*
* Period register set to 0xFF
*/
PR2 = 0b11111111;
/***** Usart Code ****
* High speed baud rate generator enabled
* Usart in Asynchronous mode
* Usart transmission enabled
* TX in eight bit format
*/
TXSTA = 0b00100100;
/*
* Usart reception enabled
* RX in eight bit format
* Usart module enabled
*/
RCSTA = 0b10010000;
/*
* Baud rate is 9600
*/
SPBRG = 0b00110011;
//SPBRG = 0b00101111;
ei(); // Global interrupts enabled
}
[/code]
Código da rotina de interrupção para testes:
[code]
void interrupt my_isr(void){
if (RCIF){
if (FERR){
c = RCREG;
TXREG = 0x22;
} else {
c = RCREG;
TXREG = c;
}
}
if((TXIE)&&(TXIF)){
TXIF=0; // clear event flag
}
}
[/code]
Poderia ser a variação do oscilador interno que faz com que a UART do pic sofra variações no seu baudrate, mas isso não explica porque a uart consegue receber 0xAA sem falhar e 0x80 falhando a maior parte das vezes sem dar frame error.
No laço main tem só um "if (OERR) {CREN=0;CREN=1;}" mas o overrun não deveria acontecer no teste porque os dados são enviados em intervalos mínimos de 0,1 segundos a 9600bps (9600,8,n,1).
Fiz o mesmo teste utilizando outro microcontrolador que não da Microchip e funcionou perfeitamente com o mesmo sw de teste do pc... logo o meu erro tá no pic e não no pc.
Alguém já passou por algum problema similar? Seria o caso de afirmar que a UART do PIC é um esterco e não funciona direito com oscilador interno e usar logo um outro micro?
O problema é que estou corrigindo um projeto de hw que usa esse pic, e mudar o micro é tipo jogar fora o projeto do cara e fazer tudo de novo...