C code của bạn em đây ạ
Code:
/*
Filename: CC5G.c
Generate a PWM signal with 40% duty cycle
on pulse-width = 5us
off pulse-width = 20ms
on CCP1 (RC2 pin) compare
and configure CCP2 (RC1 pin) for capture
*/
#include <p18cxxx.h>
#include <p18f452.h>
#include <timers.h>
#include <capture.h>
#pragma config WDT = OFF
#define PER1_LIMIT 0x0E10
#define PER2_LIMIT 0x0E10
/*
Speed of sound in air = 1130 ft/sec
TMAX = 18.5ms; TMIN = 115us
FOSC = 8MHz; Processor Clock = 2MHz
CCP Clock = 1MHz
Period = Forward + Backward Trip time
0x0E10 -> 1.8ms
0x8CA0 -> 18ms
*/
unsigned int ov_cnt1, cap1_val1, cap1_val2;
unsigned int ov_cnt2, cap2_val1, cap2_val2;
unsigned int period1, period2; // 16-bit value
unsigned int count = 0; // counter used for waiting to turn relays ON
unsigned int count2 = 0; // counter used for waiting to turn relays ON
void high_ISR( void );
void low_ISR( void );
#pragma code high_vector = 0x08 // force the following statement to
void high_interrupt( void ) { // start at 0x08
_asm
goto high_ISR
_endasm
}
#pragma code low_vector = 0x18 // force the following statement to
void low_interrupt( void ) { // start at 0x18
_asm
goto low_ISR
_endasm
}
#pragma code
#pragma interrupt high_ISR
void high_ISR( void ) {
if( PIR2bits.TMR3IF ) {
PIR2bits.TMR3IF = 0;
ov_cnt2++;
}
if( PIR1bits.TMR1IF ) {
PIR1bits.TMR1IF = 0;
ov_cnt1++;
}
}
#pragma code
#pragma interrupt low_ISR
void low_ISR( void ) {
_asm
retfie 0
_endasm
}
void vDelay( void ) {
unsigned const int MAX = 45450;
unsigned int i = 0;
for( i=0; i<MAX; i++ ) ;
}
void vDelay10us( void ) {
unsigned int i = 0;
}
void vDelay5ms( void ) {
unsigned const int MAX = 1150;
unsigned int i = 0;
for( i=0; i<MAX; i++ ) ;
}
// Delay calculations based on 8MHz crystal, 1:1 prescalar for Timer3
void main( void ) {
unsigned int i = 0;
unsigned int odd = 0;
unsigned int flag = 1; // flag for determining boat direction
int num1 = 0;
int num2 = 1;
// Configure registers for Output Compare -- a 5us trigger pulse
TRISCbits.TRISC2 = 0; // configure CCP1 pin for output
T1CON = 0x81; // turn on Timer1 in 16-bit mode, prescalar = 1
// CCP1CON = 0x09; // configure CCP1 pin to set high initially but pull low on match
// CCPR1 = TMR1H + 0x0020; // start CCP1 compare with delay equals 10
// PIR1bits.CCP1IF = 0; // clear CCP1IF flag to prevent false interrupt
OpenTimer1( TIMER_INT_OFF &
T1_16BIT_RW &
T1_PS_1_1 &
T1_OSC1EN_OFF &
T1_SYNC_EXT_OFF &
T1_SOURCE_INT );
OpenTimer3( TIMER_INT_OFF &
T3_16BIT_RW &
T3_SOURCE_INT &
T3_PS_1_1 &
T3_SYNC_EXT_OFF &
T1_CCP1_T3_CCP2 );
T1CON = 0x81; // turn on Timer1 in 16-bit mode, prescalar = 1
TRISD = 0; // set PORTD for output
TRISCbits.TRISC1 = 1; // configure CCP2 pin for input
TRISCbits.TRISC2 = 1; // configure CCP1 pin for input
INTCONbits.GIE = 0; // Disable global interrupts
RCONbits.IPEN = 1; // enable priority interrupts
PIR2bits.TMR3IF = 0;
IPR2bits.TMR3IP = 1; // promote Timer1 rollover interrupt to high priority
INTCONbits.PEIE = 1; // enable preipheral interrupt
PIE2bits.TMR3IE = 0; // disable Timer3 rollover interrupt
PIR1bits.TMR1IF = 0;
IPR1bits.TMR1IP = 1;
PIE1bits.TMR1IE = 0;
TRISB = 0x00; // configure PORTB as output
while( 1 ) {
vDelay5ms();
// if( !odd )
PORTD = 0x01;
vDelay10us();
PORTD = 0x00;
// vDelay10us();
// PORTD = 0x00;
PIE2bits.CCP2IE = 0;
CCP2CON = 0x05;
PIE2bits.CCP2IE = 1;
// PORTD = 0x00;
PIE2bits.CCP2IE = 1; // disable CCP2 capture interrupt
PIR2bits.CCP2IF = 0;
IPR2bits.CCP2IP = 1; // high priority
while( !( PIR2bits.CCP2IF ) ) ;
cap2_val1 = ReadCapture2(); // save the first captured edge
PIR2bits.CCP2IF = 0;
PIR2bits.TMR3IF = 0;
PIE2bits.TMR3IE = 1; // enable Timer3 rollover interrupt
PIE2bits.CCP2IE = 0;
CCP2CON = 0x04;
PIE2bits.CCP2IE = 1;
PORTD = 0x00;
while( !( PIR2bits.CCP2IF ) ) ; // wait for interrupt
CloseCapture2(); // disable CCP2 capture
cap2_val2 = ReadCapture2();
PIR2bits.TMR3IF = 0;
PIE2bits.TMR3IE = 0; // disable Timer3 rollover interrupt
if( cap2_val2 < cap2_val1 ) { // if timer overflows, decrease overflow count by one
ov_cnt2--;
period2 = ov_cnt2*65536 + cap2_val2 + ( 65536 - cap2_val1 );
}
else {
period2 = ov_cnt2*65536 + cap2_val2 - cap2_val1;
}
ov_cnt2 = 0; // Reset overflow counter
// vDelay5ms();
PORTD = 0x02;
vDelay10us();
PORTD = 0x00;
vDelay10us();
// PORTD = 0x00;
PIE1bits.CCP1IE = 0;
CCP1CON = 0x05;
PIE1bits.CCP1IE = 1;
// PORTD = 0x00;
PIE1bits.CCP1IE = 1; // disable CCP2 capture interrupt
PIR1bits.CCP1IF = 0;
IPR1bits.CCP1IP = 1; // high priority
while( !( PIR1bits.CCP1IF ) ) ;
cap1_val1 = ReadCapture1(); // save the first captured edge
PIR1bits.CCP1IF = 0;
PIR1bits.TMR1IF = 0;
PIE1bits.TMR1IE = 1; // enable Timer3 rollover interrupt
PIE1bits.CCP1IE = 0;
CCP1CON = 0x04;
PIE1bits.CCP1IE = 1;
while( !( PIR1bits.CCP1IF ) ) ; // wait for interrupt
CloseCapture1(); // disable CCP2 capture
cap1_val2 = ReadCapture1();
PIR1bits.TMR1IF = 0;
PIE1bits.TMR1IE = 0; // disable Timer3 rollover interrupt
if( cap1_val2 < cap1_val1 ) { // if timer overflows, decrease overflow count by one
ov_cnt1--;
period1 = ov_cnt1*65536 + cap1_val2 + ( 65536 - cap1_val1 );
}
else {
period1 = ov_cnt1*65536 + cap1_val2 - cap1_val1;
}
ov_cnt1 = 0; // Reset overflow counter
if( period1 > PER1_LIMIT & period2 > PER2_LIMIT & flag ) {
count++;
count2 = 0;
num1 &= 0;
num2 = 0;
if( count > 20 ) {
PORTB = 0x0C; // Forward
}
}
if( period1 > PER1_LIMIT & period2 > PER2_LIMIT & !flag ) {
count++;
num2 = 0;
// num1 = 0;
count2 = 0;
if( count > 20 ) {
PORTB = 0x03; // Reverse
}
}
if( period1 > PER1_LIMIT & period2 < PER2_LIMIT ) {
PORTB = 0x00;
flag = 1;
count = 0;
count2++;
if( count2 > 20 )
PORTB = 0x0C; // Forward
}
if( period1 < PER1_LIMIT & period2 > PER2_LIMIT ) {
PORTB = 0x00;
flag = 0;
count = 0;
num2++;
num1+=num2;
if( num1 > 20 ) {
PORTB = 0x03; // Reverse
}
}
if( period1 < PER1_LIMIT & period2 < PER2_LIMIT ) {
PORTB = 0x00; // Shut down
count = 0;
count2 = 0;
}
}
}