×
单片机 > 单片机程序设计 > 详情

编的PIC16f1936的超声波测距的程序

发布时间:2020-08-21 发布时间:
|

一个很久以前编的PIC16f1936的超声波测距的程序。共大家参考:
1、开发环境:mplab X,proteus 8.6仿真。
2、部分程序注释,在实物板子上有效。
3、只有测量距离,LED显示距离,(单位是0.1mm),距离中有被屏蔽部分距离。可供参考。
4、这个网上的便宜的模块,一个很大的短板:测距需要平整的面。对于人脸等,衣服等较差。

制作出来的实物图如下:
 

仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
 

单片机源程序如下:

#include

#include"system.h"

#include         /* For uint8_t definition */

#include        /* For true/false definition */

#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();



『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
ARM 汇编的必知必会