一个很久以前编的PIC16f1936的超声波测距的程序。共大家参考:
1、开发环境:mplab X,proteus 8.6仿真。
2、部分程序注释,在实物板子上有效。
3、只有测量距离,LED显示距离,(单位是0.1mm),距离中有被屏蔽部分距离。可供参考。
4、这个网上的便宜的模块,一个很大的短板:测距需要平整的面。对于人脸等,衣服等较差。
制作出来的实物图如下:
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
单片机源程序如下:
- #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黑下载附件…………
复制代码
所有资料51hei提供下载:
超声波测距.rar
(115.19 KB, 下载次数: 70)
超声波测距.pdf
(38.51 KB, 下载次数: 43)
|