je développe avec mikroPascal un module d'affichage (3 x 7 segments) multiplexés (ils s'allument tour à tour). Cet affichage reçoit ses données via UART.
Les interruptions du timer0 cadencent l'affichage alterné et les données à afficher. L'interrution UART s'occupe de réceptioner les données. Les deux interruptions (timer0 et UART) fonctionnent bien chacune de leur côté mais dès qu'elles sont ensemble dans le code, les interruptions du module UART pilote aussi les interruptions du timer0. En clair, les afficheurs s'allument tour à tour au rythme des données reçues, alors que ça devrait être indépendant... Autre info: la led du PORTC.6 ne clignote plus dès qu'une donnée est reçue et la boucle "while true" semble bloquée jusqu'au prochain reset.
Je sais que les procédures d'interruptions sont chargées, mais quand je sors des éléments vers la boucle principale, l'affichage ne fonctionne plus bien ou les données UART ne sont plus récupérées correctement... ou alors le problème se trouve ailleurs...
Le PIC en question est un 16F687 oscillateur interne à 8 Mhz.
Merci pour votre lecture et aide éventuelle!!
Code : Tout sélectionner
program DISPLAYV2;
{ Declarations section }
var
iValue: word;
iDisp: byte;
txt: string[5];
RxStatus: byte;
RxData: byte;
function DispChar(charnum: byte): byte;
begin
case charnum of
0 : result := %11000000;
1 : result := %11111001;
2 : result := %10100100;
3 : result := %10110000;
4 : result := %10011001;
5 : result := %10010010;
6 : result := %10000010;
7 : result := %11111000;
8 : result := %10000000;
9 : result := %10010000;
end;
end;
procedure Disp_Refresh;
var
toDisp: byte;
begin
PORTC.5 := 0; // display 1 off
PORTA.4 := 0; // display 2 off
PORTA.5 := 0; // display 3 off
case iDisp of
1 : begin
toDisp := iValue mod 10; // unités
PORTC.5 := 1; // display 1 on
end;
2 : begin
toDisp := (iValue div 10) mod 10; // dizaines
if iValue >= 10 then
PORTA.4 := 1; // display 2 on
end;
3 : begin
toDisp := (iValue div 100) mod 10; // centaines
if toDisp <> 0 then
PORTA.5 := 1; // display 3 on
end;
end;
toDisp := DispChar(toDisp);
PORTA.2 := toDisp.0;
PORTC.0 := toDisp.1;
PORTB.6 := toDisp.2;
PORTB.4 := toDisp.3;
PORTC.2 := toDisp.4;
PORTA.1 := toDisp.5;
PORTA.0 := toDisp.6;
PORTC.1 := toDisp.7;
end;
procedure Interrupt;
begin
if INTCON.T0IF = 1 then // timer 0 overflow
begin
INTCON.T0IF := 0; // reset flag to enable further interrupts
Inc(iDisp);
if iDisp = 4 then
iDisp := 1;
Disp_Refresh;
PORTC.7 := PORTC.7 xor 1
end;
if PIR1.RCIF = 1 then // interruption réception donnée module UART
begin
RxStatus := RCSTA; // détection erreur flux de données reçues
RxData := RCREG; // lire ce registre pour reset UART Interrupt flag
if (RxStatus and %00000110) = 0 then // si pas d'erreur
begin
UART1_Read_Text(txt, '*', 10);
if txt[0] = 'z' then
PORTC.4 := PORTC.4 xor 1;
if txt[0] <> 'z' then
iValue := StrToword(txt)
else
begin // si erreur on efface!
Clearbit(RCSTA , CREN);
Setbit(RCSTA, CREN);//
end;
end;
end;
end;
procedure mainInit;
begin
OSCCON.SCS := 1; // Internal oscillator is used for system clock
OSCCON.IRCF0 := 1; // 8 Mhz Internal Clock
OSCCON.IRCF1 := 1; // 8 Mhz Internal Clock
OSCCON.IRCF2 := 1; // 8 Mhz Internal Clock
CM1CON0 := 0; // comparator C1 off
CM2CON0 := 0; // comparator C2 off
TRISA := %00001000;
TRISB := %00100000; // RB5 = RX = USART IN
TRISC := %00000000;
ANSEL := %00000000; // disable analog channels
ANSELH := %00000000; // disable analog channels
//ADC_Init; // initialize adc module
INTCON.GIE := 1; // global Interrupts enable
INTCON.PEIE := 1; // peripheral interrupts enable
OPTION_REG.T0CS := 0; // source: internal FOSC/4 for timer 0
OPTION_REG.PSA := 0; // prescale assigned to timer 0
OPTION_REG.PS0 := 1; //
OPTION_REG.PS1 := 0; // 1:64
OPTION_REG.PS2 := 1; //
INTCON.T0IE := 1; // enable timer 0 interrupts
INTCON.T0IF := 1; // reset timer 0 flag
delay_ms(100); // stabilize
///////////////USART
TXSTA.TX9 :=0;
TXSTA.TXEN := 1;
RCSTA.CREN := 1;
RCSTA.SPEN :=1;
PIE1.RCIE := 1; // enable uart RX interrupts
PIE1.TXIE := 0; // no TX interrupt
UART1_init(9615); // initialize UART module for RS232 display
delay_ms(200); // stabilize
// display off
PORTA.0 := 1;
PORTA.1 := 1;
PORTA.2 := 1;
PORTC.0 := 1;
PORTB.6 := 1;
PORTB.4 := 1;
PORTC.2 := 1;
PORTC.1 := 1;
end;
begin
{ Main program }
mainInit;
iDisp := 1;
iValue := 0;
while true do
begin
PORTC.6 := PORTC.6 xor 1;
delay_ms(200);
end;
end. 

