View previous topic :: View next topic |
Author |
Message |
Alex Guest
|
measure a pulse. |
Posted: Wed Aug 18, 2004 8:19 am |
|
|
hi all,
I am working on a Tx/Rx transmitter with my PIC.
I already have aurel module to [spam].
But i need to send byte one by one.
I need to reconize byte i receive...
i work with a 18F452 and clock is 20 Mhz
the same 18F452 emit and receive the signal.
this pulse is about 100µs long.
i would like to measure a pulse with the timer2.
is it possible?
i try this ...
400µs = (1/clock) * 4 * MODE * (PERIODE +1) * POSTSCALE
mode T2_DIV_BY_16
periode is around 124
postscale 1
i have calculate the value in Hex to correspond with mine
but it doesn't match the correct time.
thx for help.
Code: |
#define BIT_0_Hmin 0x1F
#define BIT_0_H 160
#define BIT_0_Hmax 0x45
#define BIT_0_Lmin 0x1F
#define BIT_0_L 300
#define BIT_0_Lmax 0x7C
#define BIT_1_Hmin 0x4E
#define BIT_1_H 300
#define BIT_1_Hmax 0x7C
#define BIT_1_Lmin 0x1F
#define BIT_1_L 160
#define BIT_1_Lmax 0x7C
#int_timer2
void clock_t2() {
}
void check_bit(int16 etat_haut, int16 etat_bas) {
// test pour un bit 0
if ( (BIT_0_Hmin < etat_haut) && (BIT_0_Hmax > etat_haut) ) {
if ( (BIT_0_Lmin < etat_bas) && (BIT_0_Lmax > etat_bas) ) {
output_high(PIN_D4);
//delay_ms(100);
//output_low(PIN_D5);
buffer[pt_buffer--] = 0; // bit 0 confirmé
} // fin if
}// fin if
// test pour un bit 1
else if ( (BIT_1_Hmin < etat_haut) && (BIT_1_Hmax > etat_haut) ) {
if ( (BIT_0_Lmin < etat_bas) && (BIT_1_Lmax > etat_bas) ) {
output_high(PIN_D5);
//delay_ms(100);
//output_low(PIN_D4);
buffer[pt_buffer--] = 1; // bit 1 confirmé
} // fin if
}//fin if
else {
buffer[pt_buffer--] = 2; // erreur bit
output_high(PIN_D6);
}
if(pt_buffer == 0)
trame_recu = true;
}
#int_rb
void fct_detect() {
int current;
static int last = 0;
set_tris_b(0xF0);
current = input_b();
// Test si changement d'etat sur front montant
B7_Vide = test_low_high(last, current, 7);
B7_fin = test_high_low(last, current, 7);
// B7 -> Vide
// Reception
if(B7_Vide) {
if (etat_haut) {
etat_bas = get_timer2();
check_bit(etat_haut, etat_bas);
bit_tmp = 0;
etat_bas = 0;
etat_haut = 0;
}
B7_Vide = false;
set_timer2(0);
}
if (B7_fin) {
B7_fin = false;
etat_haut = get_timer2();
set_timer2(0);
}
// l'etat current du port b est sauvegarde
last = current;
}
|
|
|
|
dvsoft
Joined: 28 Nov 2003 Posts: 46
|
|
Posted: Fri Aug 20, 2004 12:34 am |
|
|
bonjour,
Ton code n'est pas tres facile a lire
Peut tu expliquer ce que tu fait exactement, c'est plus facile pour te donner de l'aide.
Alain |
|
|
Alex Guest
|
oups ... |
Posted: Fri Aug 20, 2004 4:26 am |
|
|
Désolé je me rend pas compte car je suis dedans toute la journée
La je défini les valeurs pour l'etat haut et bas des bit à 0 et bit à 1.
les valeur min et max sont en hexa et correspondent au calcul précend.
400 µs le timer compte jusqu'a 124
100 µs le timer compte jusqu'a 31 soit 0x1F en hexa
etc ...
Code: |
#define BIT_0_Hmin 0x1F
#define BIT_0_H 160
#define BIT_0_Hmax 0x45
#define BIT_0_Lmin 0x1F
#define BIT_0_L 300
#define BIT_0_Lmax 0x7C
#define BIT_1_Hmin 0x4E
#define BIT_1_H 300
#define BIT_1_Hmax 0x7C
#define BIT_1_Lmin 0x1F
#define BIT_1_L 160
#define BIT_1_Lmax 0x7C
|
mon timer 2 compte ... je n'arrive jamais a l'interruption overflow
Code: |
#int_timer2
void clock_t2() {
}
|
Sert pour ma reception AM.
je test la durée de mes etats haut et bas.
je stock le bit recu dans un buffer ...
MON PB : quand j'emet sur la pin C3 et recois sur B7
j'utilise delay_us() avec la valeur
la fonction ci-dessous trouve que des bits erronés
J'ai pensé a deux choses ...
- 1er : je me suis planté dans mes calculs ...
- 2eme : je peux pas tester avec un seul pic (temp trop cours) .
Code: |
void check_bit(int16 etat_haut, int16 etat_bas) {
// test pour un bit 0
if ( (BIT_0_Hmin < etat_haut) && (BIT_0_Hmax > etat_haut) ) {
if ( (BIT_0_Lmin < etat_bas) && (BIT_0_Lmax > etat_bas) ) {
buffer[pt_buffer--] = 0; // bit 0 confirmé
} // fin if
}// fin if
// test pour un bit 1
else if ( (BIT_1_Hmin < etat_haut) && (BIT_1_Hmax > etat_haut) ) {
if ( (BIT_0_Lmin < etat_bas) && (BIT_1_Lmax > etat_bas) ) {
buffer[pt_buffer--] = 1; // bit 1 confirmé
} // fin if
}//fin if
else {
buffer[pt_buffer--] = 2; // erreur bit
}
if(pt_buffer == 0)
trame_recu = true;
}
|
Détection d'un front montant ou descendant (interruption sur port b)
lancement du timer 2 pour calculer la longueur de l'etat haut puis bas.
Code: |
#int_rb
void fct_detect() {
int current;
static int last = 0;
set_tris_b(0xF0);
current = input_b();
// Test si changement d'etat sur front montant
B7_Vide = test_low_high(last, current, 7);
B7_fin = test_high_low(last, current, 7);
// Action si front montant
if(B7_Vide) {
if (etat_haut) {
etat_bas = get_timer2();
check_bit(etat_haut, etat_bas);
etat_bas = 0;
etat_haut = 0;
}
B7_Vide = false;
set_timer2(0);
}
// Action si front descendant
if (B7_fin) {
B7_fin = false;
etat_haut = get_timer2();
set_timer2(0);
}
// l'etat current du port b est sauvegarde
last = current;
}
|
ca devrais etre mieux ... |
|
|
dvsoft
Joined: 28 Nov 2003 Posts: 46
|
|
Posted: Fri Aug 20, 2004 2:30 pm |
|
|
bonsoir,
Si j'ai bien compris, tu cherche à mesurer la periode sur la pin 7 du port B
1- pourquoi ne pas utiliser le module CCP du PIC ?
2- Regarde le code generer par le compilateur pour verifier le temps d'execution en comptant le nombre d'instructions
J'utiliser tres souvent les modules CCP1 et CCP2 pour mesurer des frequences, sans aucun PB
Bon courrage
Alain |
|
|
Guest
|
|
Posted: Sun Aug 22, 2004 2:33 am |
|
|
je ne cherche pas a mesurer la frequence....
je cherche a mesurer l'etat haut, puis l'etat bas de chaque bit.
----- ------
---| |-------|
T1 T2
tu comprends mieux ?
peut on le faire avec le CCP ? |
|
|
Sethz Guest
|
|
Posted: Sun Aug 22, 2004 2:36 am |
|
|
je ne cherche pas a mesurer la frequence....
je cherche a mesurer l'etat haut, puis l'etat bas de chaque bit.
___-----_____----- (representation d'un bit)
...... T1 ...T2
je cherche à mesurer t1 puis t2.
tu comprends mieux ?
peut on le faire avec le CCP ? |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Sun Aug 22, 2004 2:08 pm |
|
|
Wouldn't it be nice if everyone in this world would speak French? Than I would have a clue what this discussion is about.
Besides being impolite you are now excluding many other people who might contribute to, or benefit from, your question. |
|
|
dvsoft
Joined: 28 Nov 2003 Posts: 46
|
|
Posted: Mon Aug 23, 2004 12:52 am |
|
|
hello,
I presente my exuste has all the members of the forum, to have to use French
it is of my fault
Alain |
|
|
dvsoft
Joined: 28 Nov 2003 Posts: 46
|
|
Posted: Mon Aug 23, 2004 12:56 am |
|
|
hello,
look at the question Square Wave Data Logging
Alain |
|
|
Alex Guest
|
|
Posted: Mon Aug 23, 2004 3:14 am |
|
|
Sorry, for my poor english.
first exuse me for frensh speak
I would like to mesure lenght of the high stat (T1) and lenght of the low stat (T2).
___-----_____-----
...... T1 ...T2
does my code can make it ?
could i do it with ccp ? |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Mon Aug 23, 2004 3:55 am |
|
|
Yes, you can do this. There are several ways to do it, using the CCP is one of them.
Using interrupts is another options, but you mentioned your pulse to be 100us. This makes it difficult to use interrupts as the standard interrupt dispatcher from CCS requires almost 20us on a PIC18 running 20MHz. The interrupt handler would introduce a timing error of about 20%. You could however write your own optimized dispatcher, or even better, use the high priority interrupts (FAST keyword).
Still, I think using the CCP module will be more accurate and easier to implement. |
|
|
alex Guest
|
|
Posted: Tue Aug 24, 2004 10:02 am |
|
|
Thx ... i will try the ccp. |
|
|
|