2013年1月8日 星期二

DIY - PIC:PIC18F4550 超聲波測距 Range Finder 程式 (一百六十七)


DIY - PICPIC18F4550 超聲波測距 Range Finder 程式 (一百六十七)

Microchip PIC18F4550 微控制器蕊片有兩個 CCPCapture/Compare/PWM,捕捉/ 比較/PWM)模組,CCP (捕捉/比較 / PWM) 模組是允許用戶在時間和控制不同的事件。 每個模組包含一個 16 位元寄存器,它可以用作 16 位捕捉寄存器、16 位比較寄存器或 PWM /從占空比寄存器。在 PIC18F4550 引腳器件中,CCP1 為增強型 CCP 模組,該模組具有標準捕捉和比較模式以及增強型 PWM 模式。

Capture - 在捕捉模式下,允許外置設備的一個事件時間期限。該電路提供了深入了解當前狀態寄存器,它不斷地改變一些它的價值。在這種情況下,它是定時器 TMR1寄存器。

PIC18F4550 超聲波測距 Range Finder 電路程式利用 CCP 模塊(Capture 捕獲模式)準確地測量信號的接收時間在 RC2 (Pin 17) 端口引腳。當一個上沿信號觸發 CCP 模塊,定時器1 (Timer1) 便開始計時,直至下沿信號再觸發 CCP 模塊時,便停止定時器1 (Timer1) ,並取出被存儲在一個 CCP 寄存器或定時器1 (Timer1) 的數值。

筆者的 PIC PIC18F4550 石英振盪器是 20MHz (0.05us) ,選擇定時器1 (Timer1) Prescaler 11,所以定時器1 (Timer1) 的時鐘周期是 0.2us (4 × 0.05us) 數值,可用公式計算出距離:

距離=s × t/ 2m
距離=  (343200mm/s × (Timer1數值  × 0.2us)) / 2  @室溫  20ºC

需要的距離除以2的往返距離即從發射機到對象然後再返回。
聲音在空氣中的速度是有少許變 330m/s  (33000cm/s) 0ºC在室溫  20ºC 343.2m / s (343200mm/s)。聲音大約行走 1cm 需要 1/34000= 29.4us

參考往返時間與 US-020 實際時間比較:
參考往返時間
距離
定時器 (Timer1)
往返時間 / 時間
t = 588us
10cm  (100mm)
3105
620 / 310us
t = 1176us
20cm  (200mm)
5980
1196 / 598us
t = 5.8ms
1m     (1000mm)
29467
58934 / 29467us

主程式:
void main(void)
{          
    char LCD_name[] ="BWS US-020  v1.0";
    char LCD_name2[]="                ";

    // Ultrasonic Varaible
    unsigned int CCP1_dist;

TRISB = 0b00101111;                 // Setup RB0=1=Input  DS1820 Temperature Sensor  
                                        //                              
                                                          // Setup RB2=1=Input  PS2 KB Clock
                                                          // Setup RB3=1=Input  PS2 KB Data
                                                          // Setup RB4=0=Output Ultrasonic Trig
                                                          // Setup RB5=1=Input  Debug Switch

    TRISC = 0b10111111;                 // Setup RC2=1=Input  Ultrasonic Echo
                                                          // Setup RC6=0=Output RS232(TX)
                                                          // Setup RC7=1=Input  RS233(RX)

    // Set up RC2 (CCP1 Pin=17) Interrupt I/O Setting
    OpenCapture1(C1_EVERY_RISE_EDGE & CAPTURE_INT_ON);

    OpenTimer1(TIMER_INT_OFF &
                          T1_16BIT_RW &
                          T1_SOURCE_INT &
                          T1_SOURCE_CCP &
                          T1_PS_1_1);

    INTCONbits.GIEH = 1;        // Global Interrupt Enable 1=Enable,0=Diable
    INTCONbits.PEIE =1;         // Peripheral Interrupt Enable 1=Enable,0=Diable


//--------------------------------------------
// START HERE is the main program
//--------------------------------------------
while(1)   
{

        // CCP1 Interrupt ON
        CCP1_start = 1;
        INTCONbits.GIEH = 1;            // Global Interrupt Enable 1=Enable,0=Diable

        // Ultrasonic Trigger ON
LATBbits.LATB4 = 1;               // RB4=1 TRIG=ON
        Delay10TCYx(6);                    // Delay:10us 10x(4x0.05us) = 5*2us=10us

LATBbits.LATB4 = 0;               // RB4=0 TRIG=OFF

LATAbits.LATA4 = 1;              // RA4=1 LED=ON Scope=50ms
Delay10KTCYx(50);             // Delay:100ms 10,000x(4x0.05us) = 50*2ms=100ms

        if(INTCONbits.GIEH == 0)
        {
           CCP1_dist = Read_CCP1_T1/29.94;
           sprintf(glb_Buf,"D=%4imm=%6u",CCP1_dist,Read_CCP1_T1); // Put Temp into Buf
           LcdSetLine2();
           putsXLCD(glb_Buf);             // Display Content
        } // End if CCP1 T1 Finished
                                                                     
    } // End While 1

} // End Main Program

CCP1中斷副程式:
void CCP1_isr(void)
{

     if(CCP1_start == 1) {                                              // Check FIRST interrup
        WriteTimer1(00);                                                 // Init Timer1 = 0
        OpenCapture1(C1_EVERY_FALL_EDGE &   // Set to Falling Edge Interrupt
                                 CAPTURE_INT_ON);               // Interrupt Enable
        CCP1_start  = 0;
        edge_detect = 0;
        PIR1bits.CCP1IF = 0;                    // Clear CCP1 Interrupt Flag
        INTCONbits.GIEH = 1;                //*Global Interrupt Enable 1=Enable,0=Diable
     }
     else
     {
       // High to Low Pulse Time ONLY
       if(edge_detect == 0) {                                              // Fall Edge detected

          Read_CCP1_T1 = ReadCapture1();                     // Read Int from CCP1 
          OpenCapture1(C1_EVERY_RISE_EDGE &
                                   CAPTURE_INT_ON);
          edge_detect = 1;
          edge_end    = 1;
          PIR1bits.CCP1IF = 0;                                           // Clear CCP1 Interrupt Flag
    
       } // End of edge_detected=0
      } // End If CCP1 start

 //} // End If CCP1IF=1 Move to High_isr

} // End CCP1_isr

主要技術參數
電氣參數
US-020超聲波測距模組
工作電壓
DC 5V
靜態電流
3mA
工作溫度
0~+70
輸出方式
GPIO
感應角度
小於15
探測距離
2cm - 700cm
探測精度
0.3cm+1%
由於超聲波測距模塊 US-020 的靈敏度,接收放大器的增益和噪聲性能,傳輸的發送功率和持續時間的最大距離是有限的。對於該電路的最大的距離為 3m 左右。從理論可以測量的最大距離為 40ms*340m=13.66.8m(半的往返時間延遲),但實踐中這是由信號調整電路的限制,更改信號調整電路會得到更多的範圍。

相關網址

沒有留言:

張貼留言