一個很久以前編的PIC16f1936的超聲波測距的程序。共大家參考:
1、開發環境:mplab X,proteus 8.6仿真。
2、部分程序注釋,在實物板子上有效。
3、只有測量距離,LED顯示距離,(單位是0.1mm),距離中有被屏蔽部分距離。可供參考。
4、這個網上的便宜的模塊,一個很大的短板:測距需要平整的面。對于人臉等,衣服等較差。
制作出來的實物圖如下:
QQ圖片20181206101936.jpg (31.53 KB, 下載次數: 127)
下載附件
實物顯示
2018-12-6 10:20 上傳
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
0.png (22.38 KB, 下載次數: 117)
下載附件
2018-12-6 15:17 上傳
單片機源程序如下:
- #include <xc.h>
- #include"system.h"
- #include <stdint.h> /* For uint8_t definition */
- #include <stdbool.h> /* For true/false definition */
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #define TRIG PORTCbits.RC1 //TRIG input
- #define ECHO PORTCbits.RC2 //ECHO input
- // 0, 1, 2 3 4 5 6 7 8 9
- uint8_t seg_data[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0b10111111,0b11100011,0b10000110,0b10000100};
- uint8_t seg_rom[4]={0x01,0x02,0x04,0x08};
- uint16_t disp_data=0;
- uint8_t disp_rom=0;
- uint8_t disp_num=0;
- uint8_t buffer[10];
- uint8_t time_ccpr1l;
- uint8_t time_ccpr1h;
- uint8_t eccp_up_down_flag=0; //up=0;down=1;
- uint16_t disp_number;
- uint8_t distance_ok_flag=0;
- uint8_t distance_over=0;
- void serial_send(uint8_t send_data );
- void eccp1_disable();
- void sys_init();
- void distance_test();
- void eccp1_enable();
- void eccp1_up();
- void eccp1_down();
- void data_do();
- void disp_do();
- void clear_pin()
- {
- PORTB=0xff;
- PORTA=(uint8_t)((PORTA ) & (uint8_t)(0b11110000));
- }
- /***************************************************************************
- 程序為上升沿檢測
- 上升沿檢測初始化并啟動上升沿檢測(中斷)
- **************************************************************************/
- void eccp1_up()
- {
- CCP1CON=0x00;
- CCP1CON=0x05; //04:下降沿,05:上升沿。
- CCPR1L=0;
- CCPR1H=0;
- TMR1H=0;
- TMR1L=0;
- T1CON=0x24;
- PIR1bits.CCP1IF=0;
- eccp_up_down_flag=0; //up =0 down=1;
- eccp1_enable(); //開啟上升沿檢測
- }
- /***************************************************************************
- 程序為下降沿檢測
- 下降沿檢測初始化并啟動下降沿檢測(中斷)
- **************************************************************************/
- void eccp1_down()
- {
- CCP1CON=0x00;
- CCP1CON=0x04; //04:下降沿,05:上升沿。
- CCPR1L=0;
- CCPR1H=0;
- TMR1H=0;
- TMR1L=0x09;
- T1CON=0x25;
- PIR1bits.CCP1IF=0;
- eccp_up_down_flag=1; //up =0 down=1;
- PIR1bits.CCP1IF=0;
- PIE1bits.CCP1IE=1;
- INTCONbits.GIE=1;
- }
- void eccp1_enable()
- {
- PIR1bits.CCP1IF=0;
- PIE1bits.CCP1IE=1;
- INTCONbits.GIE=1;
- }
- void eccp1_disable()
- {
- PIR1bits.CCP1IF=0;
- PIE1bits.CCP1IE=0;
- INTCONbits.GIE=0;
-
- }
- void pin_init()
- {
- TRISA=0; //RA LED輸出
- PORTA=0b11100000;
- TRISB=0x00; //RB LED輸出
- PORTB=0Xff;
- ANSELA=0; //關閉A口的ADC
- TRISC=0b00000100; //RC2=ECHO input;RC1=Trip output
- PORTC=0;
- IOCBF=0X00;
- IOCBN=0X80; //
- IOCBP=0X00;
- SRLEN=0;
- LCDEN=0;
- }
- void disp()
- {
- uint8_t PA_buffer,PB_buffer;
- if(disp_rom==disp_num) //4位顯示完畢
- {
- disp_rom=0;
- sprintf(buffer,"%05u",disp_number*17);//disp_buffer);
- disp_num=4; //顯示4位
- if(distance_over==1) //超出距離顯示“----”
- {
- disp_num=4;
- buffer[0]=0x3a;
- buffer[1]=0x3a;
- buffer[2]=0x3a;;
- buffer[3]=0x3a;;
- }
- PA_buffer=seg_rom[disp_rom];
- PB_buffer=seg_data[((unsigned)(buffer[(unsigned)disp_num-1])-0x30)];
- clear_pin();
- PORTA=(uint8_t)((PA_buffer & 0b00001111) ^ (PORTA & 0b11110000));
- PORTB=PB_buffer;
- disp_rom++;
- }
- else //4位沒有顯示完畢
- {
- PA_buffer=seg_rom[disp_rom];
- PB_buffer=seg_data[((unsigned)buffer[(unsigned)disp_num-1-disp_rom])-0x30];
- clear_pin();
- PORTA=(uint8_t)((PA_buffer & 0b00001111) ^ (PORTA & 0b11110000));
- if(disp_rom==2 && distance_over==0)
- PORTB=(uint8_t)(PB_buffer & 0b01111111);
- else
- PORTB=PB_buffer;
- disp_rom++;
- }
- }
- void Serial_init(void)
- {
- OSCCON = 0x7F; //64/16MHZ
- SYNC=0;BRGH=0; BRG16=0; //9600band
- SPBRG=25; //
- TXEN=1; //
- SPEN=1; //
- TX9=0; //
- RX9=0; //
- CREN=1; //
- INTCON=0;
- PIE1=0;
- INTCONbits.INTE=0;
- INTCONbits.IOCIE=0;
- PIE1bits.ADIE=0;
- PIE1bits.CCP1IE=0;
- PIE1bits.SSPIE=0;
- PIE1bits.TMR1GIE=0;
- PIE1bits.TMR1IE=0;
- PIE1bits.TMR2IE=0;
- PIE1bits.RCIE=0; //關閉接收中斷
- INTCONbits.PEIE=1; //
- INTCONbits.GIE=1;
-
- }
- /***************************************************************************
- 中斷子程序
- **************************************************************************/
- void interrupt isr (void)
- {
- if( CCP1IE && CCP1IF )
- {
- if(eccp_up_down_flag==0) //上升沿檢測
- {
- eccp1_down(); //進行下降沿檢測
- }
- else
- {
- eccp1_disable(); //
- time_ccpr1l = CCPR1L; //
- time_ccpr1h = CCPR1H; //
- CCPR1L=0; //
- CCPR1H=0; //
- TMR1H=0;
- TMR1L=0;
- T1CON=0x20;
- distance_ok_flag=1; //檢測完畢
- disp_number=(uint16_t)time_ccpr1h<<8 | time_ccpr1l; //distance save
- PIR1bits.CCP1IF = 0;
- }
- }
-
- }
- void serial_send(uint8_t send_data )
- {
- TXREG = send_data;
- while(TRMT==0);
- }
- void main()
- {
- uint8_t i;
- sys_init(); //system initialize
- disp_data=1234;
- sprintf(buffer,"%d",disp_data);
- disp_num=strlen(buffer); //display"1234"
- __delay_ms(100);
- while(1)
- {
- distance_test(); //test distance
- for(i=0;i<120;i++)
- {
- disp(); //display distance
- __delay_ms(1);
- }
- }
- }
- void sys_init()
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
0.png (44.85 KB, 下載次數: 131)
下載附件
2018-12-6 15:17 上傳
所有資料51hei提供下載:
超聲波測距.rar
(115.19 KB, 下載次數: 70)
2018-12-6 10:20 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
超聲波測距.pdf
(38.51 KB, 下載次數: 43)
2018-12-6 10:24 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|