一个很久以前编的PIC16f1936的超声波测距的程序。共大家参考:
1、开发环境:mplab X,proteus 8.6仿真。
2、部分程序注释,在实物板子上有效。
3、只有测量距离,LED显示距离,(单位是0.1mm),距离中有被屏蔽部分距离。可供参考。
4、这个网上的便宜的模块,一个很大的短板:测距需要平整的面。对于人脸等,衣服等较差。
制作出来的实物图如下:
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
单片机源程序如下:
#include
#include"system.h"
#include
#include
#include
#include
#include
#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();
『本文转载自网络,版权归原作者所有,如有侵权请联系删除』