السلام عليكم
ممكن ان تشرحو لي في هدا الكود أسفله
كيف استعمل CCP1 in Capture mode من أجل قياس المدة التي تكون فيها الاشارة عالية
لم أفهم الكود ولم اعرف اي رجل يتم فحصها
هدا الكود استعمل مع حساس hc-sr04 +pic16f877a من اجل حساب المسافة
طريقة عمله
هو ان البيك يرسل اشارة لمدخل tigger بالحساس لمدة 10 ميكروثانية
ثم ينتضر أن تصبح القيمة عالية للرجل المراقبة من طرف CCP1 والتي لم اعرفها ومن تم يحسب زمن بقاء هده الرجل على القيمة العالية
وبهدا الزمن نحسب المسافة
داتاشيت للحساس
http://www.micropik.com/PDF/HCSR04.pdf
الكود
كود:
/*
* Project name:
Test du HC-SR04
* Test configuration:
MCU: PIC16F877A
Oscillator: HS, 12.0000 MHz
Ext. Modules: Character LCD 2x16
HC-SR04
SW: mikroC PRO for PIC
*/
// LCD connections
sbit LCD_RS at RB4_bit;
sbit LCD_EN at RB5_bit;
sbit LCD_D4 at RB6_bit;
sbit LCD_D5 at RB1_bit;
sbit LCD_D6 at RB2_bit;
sbit LCD_D7 at RB3_bit;
sbit LCD_RS_Direction at TRISB4_bit;
sbit LCD_EN_Direction at TRISB5_bit;
sbit LCD_D4_Direction at TRISB6_bit;
sbit LCD_D5_Direction at TRISB1_bit;
sbit LCD_D6_Direction at TRISB2_bit;
sbit LCD_D7_Direction at TRISB3_bit;
// End LCD connections
char txt1[] = "Test du capteur";
char txt2[] = "HC-SR04";
char txt3[] = "Distance :";
char txt4[7];
unsigned long Cumul;
unsigned tWord,tOld, tNew;
char th,tl;
char edge = 0;
char capture = 0;
float temps = 0;
float distance = 0;
float distance2 = 0;
void interrupt() {
if(PIR1.CCP1IF){ //Si PIR1.CCP1IF égal à 1
if(!edge){ //Si edge égal à 0
CCP1CON = 0x04; // Mode de capture a chaque front descendant
tOld = 256*CCPR1H + CCPR1L; //garde la valeur de départ
edge = 1; //edge prend la valeur 1
}else{
tNew =256*CCPR1H + CCPR1L; //garde la valeur de fin
capture = 1; //indicateur capture términée
edge = 0; //edge prend la valeur 0
}
PIR1.CCP1IF = 0; //remise à 0 du flag (PIR1.CCP1IF)
}
}
void main() {
char i;
TRISB = 0; // PORTB en sortie
PORTB = 0; // Initialisation du PORTB
TRISA = 0; // PortA en sortie
PORTA = 0x00; // Initialisation du PORTA
TRISC = 0; // PortC en sortie
CCP1CON = 0x05; // Mode de capture a chaque front montant
TRISC.F2 = 1; // RC2 en entré
T1CON = 0x21; // timer1 ON, internal clock Fosc/4, prescaler 1:4
INTCON.GIE = 1;
INTCON.PEIE =1;
PIE1.CCP1IE = 1; // active la capture par interruption
PIR1.CCP1IF = 0; //remise à 0 du flag (PIR1.CCP1IF)
Lcd_Init(); // Initialisation du LCD
Lcd_Cmd(_LCD_CLEAR); // Effacer le LCD
Lcd_Cmd(_LCD_CURSOR_OFF); // Desactivation du curseur
Lcd_Out(1,2,txt1); // Ecrire text 1
Lcd_Out(2,6,txt2); // Ecrire text 2
Delay_ms(2000);
Lcd_Cmd(_LCD_CLEAR); // Effacer le LCD
PORTA = 0x01; // Envoi une impulsion
Delay_us(10); // de 10 microsecondes
PORTA = 0x00; // dans la broche RA1
while(1)
{
if(capture){
PIE1.CCP1IE = 0; //desactive la capture par interruption
capture = 0; // Capture prend la valeur 0
tWord = ~tOld + tNew+1; //Calculer la longueur de l'impulsion de front montant à front montant
CCP1CON = 0x05; // Mode de capture a chaque front montant
// tword contiennent longueur d'impulsion en micro seconde
temps =((float)tWord*4)/3;
distance = ((float)temps*17)/1000; //calcul de la distance en cm
floatToStr(distance,txt4);
Delay_ms(70);
PIR1.CCP1IF = 0; //remise à 0 du flag (PIR1.CCP1IF)
PIE1.CCP1IE = 1; // enable interrupt
if(distance !=distance2){
Lcd_Cmd(_LCD_CLEAR); // Effacer le LCD
Lcd_Cmd(_LCD_CURSOR_OFF); // Desactivation du curseur
Lcd_Out(1,1,txt3); // Ecrire text 3
Lcd_Out(2,8,txt4); // Afficher distance
}
distance2 = distance;
PORTA = 0x01; // Envoi une impulsion
Delay_us(10); // de 10 microsecondes
PORTA = 0x00; // dans la broche RA1
}
}
}