Je reviens vers vous car je sèche complètement (2 nuits blanches!).
Voici ce que j'attends de mon code:
produire une onde carrée de fréquence variable.
Pour ce faire j'utilise les interruptions du timer1 (16 bits).
Je règle la fréquence en pré-positionnant le compteur du timer1 (0 = freq min; 2^16 = freq max) via ma variable TMR1preset.
La fréquence produite a un "Duty Cycle" et un comportement complètement erratique. A MOINS d'ajouter la ligne suivante if TMR1preset >= 65535 then qui, apriori, ne sert à rien puisque je ne mets aucune action après le "then". A ce moment là ça fonctionne (trouvé par hazard)!
J'ai ralenti la fréquence de scan des ADC ADCON1 := %00010000;
Autre question plus générale dans la foulée: si je mets RABPU à 0 via OPTION_REG := 0;, les pull-ups sont-ils activés ou non?? (il y a une barre au dessus du paramètre -> inverse la logique?) voir attachement.
voici les CONFIG WORDS:
et le code:
Code : Tout sélectionner
program DVCO_test;
{
Variable square wave frequency generation controlled by analog voltage
Timer1 interrupts used to generate frequency
chip: PIC16F687 running at 8 Mhz internal oscillator (INTOSC)
all other CONFIG WORDS disabled
}
{ Declarations section }
var
TMR1preset: word; // used to set position of Timer1 counter
procedure Interrupt;
begin
if PIR1.TMR1IF = 1 then // Interrupt from timer 1?
begin
PORTB.6 := PORTB.6 xor 1; // toggle pin
TMR1H := Hi(TMR1preset);
TMR1L := Lo(TMR1preset);
PIR1.TMR1IF := 0;
end;
end;
begin
{ Main program }
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 := %00000001; // PORTA.0 = input
TRISB := %00000000;
TRISC := %00000000;
ANSEL := %00000001; // enable analog channels 0
ANSELH := %00000000; // enable analog channel
OPTION_REG := 0; // reset OPTION register
// pull-ups disabled
INTCON := 0; // reset intcon register
INTCON.GIE := 1; // enable global interrupts
INTCON.PEIE := 1; // enable peripheral interrupts
T1CON := 0;
T1CON.TMR1CS := 0; // reset T1CON register
// Timer1 clock source select = internal (FOSC/4)
T1CON.T1CKPS0 := 0; // Timer 1 prescale 1:1
T1CON.T1CKPS1 := 0; //
TMR1H := 0; // reset Timer1 counter
TMR1L := 0; // reset Timer1 counter
PIR1.TMR1IF := 0; // clear Timer1 interrupt flag
T1CON.TMR1ON := 1; // activate Timer1
PIE1 := 0; // reset PEIE register
PIE1.TMR1IE := 1; // enable Timer1 interrupts
PIR1 := 0; // reset PIR1 register
ADC_Init; // initialize adc module
ADCON1 := %00010000; // ADC acquisition clock = FOSC/8
delay_ms(500);
PORTA := 0; // reset port states
PORTB := 0;
PORTC := 0;
PORTB.6 := 0; // to be sure!
TMR1preset := 0; // variable reset
while true do
begin
TMR1preset := (ADC_Get_Sample(0))*64;
// read ADC channel 0 and multiply by 64 to obtai
// (almost) full 16 bit span from 10 bit span.
// 1023 * 64 = 65472 (almost 65535)
if TMR1preset >= 65535 then // without this line output behaviour is strange.
end;
end.
Je vous ai sorti les pages avec les registres concernés:
MERCI POUR VOTRE AIDE!!