找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 7835|回复: 7
打印 上一主题 下一主题
收起左侧

很久以前编的PIC16f1936的超声波测距的程序+Proteus仿真共享

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

制作出来的实物图如下:


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


单片机源程序如下:
  1. #include <xc.h>
  2. #include"system.h"
  3. #include <stdint.h>        /* For uint8_t definition */
  4. #include <stdbool.h>       /* For true/false definition */
  5. #include <stdio.h>
  6. #include <string.h>
  7. #include <stdlib.h>
  8. #define TRIG PORTCbits.RC1          //TRIG  input
  9. #define ECHO PORTCbits.RC2          //ECHO  input
  10. //                    0,  1,   2     3   4    5    6    7    8    9   
  11. uint8_t seg_data[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0b10111111,0b11100011,0b10000110,0b10000100};
  12. uint8_t seg_rom[4]={0x01,0x02,0x04,0x08};
  13. uint16_t disp_data=0;                              
  14. uint8_t disp_rom=0;
  15. uint8_t disp_num=0;
  16. uint8_t buffer[10];
  17. uint8_t time_ccpr1l;
  18. uint8_t time_ccpr1h;
  19. uint8_t eccp_up_down_flag=0;                        //up=0;down=1;
  20. uint16_t disp_number;
  21. uint8_t distance_ok_flag=0;
  22. uint8_t distance_over=0;
  23. void serial_send(uint8_t send_data );
  24. void eccp1_disable();
  25. void sys_init();
  26. void distance_test();
  27. void eccp1_enable();
  28. void eccp1_up();
  29. void eccp1_down();
  30. void data_do();
  31. void disp_do();
  32. void clear_pin()
  33. {
  34.     PORTB=0xff;
  35.     PORTA=(uint8_t)((PORTA ) & (uint8_t)(0b11110000));
  36. }
  37. /***************************************************************************
  38. 程序为上升沿检测
  39. 上升沿检测初始化并启动上升沿检测(中断)
  40. **************************************************************************/
  41. void eccp1_up()
  42. {
  43.     CCP1CON=0x00;
  44.     CCP1CON=0x05;      //04:下降沿,05:上升沿。
  45.     CCPR1L=0;
  46.     CCPR1H=0;
  47.     TMR1H=0;
  48.     TMR1L=0;
  49.     T1CON=0x24;
  50.     PIR1bits.CCP1IF=0;
  51.     eccp_up_down_flag=0;   //up =0 down=1;   
  52.     eccp1_enable();        //开启上升沿检测
  53. }
  54. /***************************************************************************
  55. 程序为下降沿检测
  56. 下降沿检测初始化并启动下降沿检测(中断)
  57. **************************************************************************/
  58. void eccp1_down()
  59. {
  60.     CCP1CON=0x00;
  61.     CCP1CON=0x04;      //04:下降沿,05:上升沿。
  62.     CCPR1L=0;
  63.     CCPR1H=0;
  64.     TMR1H=0;
  65.     TMR1L=0x09;
  66.     T1CON=0x25;
  67.     PIR1bits.CCP1IF=0;
  68.     eccp_up_down_flag=1;   //up =0 down=1;   
  69.     PIR1bits.CCP1IF=0;
  70.     PIE1bits.CCP1IE=1;
  71.     INTCONbits.GIE=1;
  72. }
  73. void eccp1_enable()
  74. {
  75.     PIR1bits.CCP1IF=0;
  76.     PIE1bits.CCP1IE=1;
  77.     INTCONbits.GIE=1;
  78. }
  79. void eccp1_disable()
  80. {
  81.      PIR1bits.CCP1IF=0;
  82.      PIE1bits.CCP1IE=0;
  83.      INTCONbits.GIE=0;
  84.      
  85. }
  86. void pin_init()
  87. {
  88.     TRISA=0;                //RA LED输出
  89.     PORTA=0b11100000;
  90.     TRISB=0x00;             //RB LED输出
  91.     PORTB=0Xff;            
  92.     ANSELA=0;               //关闭A口的ADC
  93.     TRISC=0b00000100;       //RC2=ECHO input;RC1=Trip output
  94.     PORTC=0;
  95.     IOCBF=0X00;
  96.     IOCBN=0X80;            //
  97.     IOCBP=0X00;   
  98.     SRLEN=0;
  99.     LCDEN=0;
  100. }
  101. void disp()
  102. {
  103.     uint8_t PA_buffer,PB_buffer;
  104.     if(disp_rom==disp_num)                    //4位显示完毕
  105.     {
  106.         disp_rom=0;        
  107.         sprintf(buffer,"%05u",disp_number*17);//disp_buffer);
  108.         disp_num=4;                           //显示4位
  109.         if(distance_over==1)                  //超出距离显示“----”
  110.         {
  111.             disp_num=4;
  112.             buffer[0]=0x3a;
  113.             buffer[1]=0x3a;
  114.             buffer[2]=0x3a;;
  115.             buffer[3]=0x3a;;
  116.         }        
  117.         PA_buffer=seg_rom[disp_rom];
  118.         PB_buffer=seg_data[((unsigned)(buffer[(unsigned)disp_num-1])-0x30)];
  119.         clear_pin();
  120.         PORTA=(uint8_t)((PA_buffer  & 0b00001111) ^ (PORTA & 0b11110000));   
  121.         PORTB=PB_buffer;  
  122.         disp_rom++;
  123.     }
  124.     else                                      //4位没有显示完毕
  125.     {
  126.         PA_buffer=seg_rom[disp_rom];
  127.         PB_buffer=seg_data[((unsigned)buffer[(unsigned)disp_num-1-disp_rom])-0x30];         
  128.         clear_pin();
  129.         PORTA=(uint8_t)((PA_buffer  & 0b00001111) ^ (PORTA & 0b11110000));
  130.         if(disp_rom==2 && distance_over==0)
  131.         PORTB=(uint8_t)(PB_buffer & 0b01111111);
  132.         else
  133.         PORTB=PB_buffer;
  134.         disp_rom++;
  135.     }         
  136. }
  137. void Serial_init(void)     
  138. {
  139.     OSCCON = 0x7F;            //64/16MHZ
  140.     SYNC=0;BRGH=0; BRG16=0;   //9600band
  141.     SPBRG=25;                //
  142.     TXEN=1;                      //
  143.     SPEN=1;                      //
  144.     TX9=0;                       //
  145.     RX9=0;                             //
  146.     CREN=1;                             //
  147.     INTCON=0;
  148.     PIE1=0;
  149.     INTCONbits.INTE=0;
  150.     INTCONbits.IOCIE=0;
  151.     PIE1bits.ADIE=0;
  152.     PIE1bits.CCP1IE=0;
  153.     PIE1bits.SSPIE=0;
  154.     PIE1bits.TMR1GIE=0;
  155.     PIE1bits.TMR1IE=0;
  156.     PIE1bits.TMR2IE=0;
  157.     PIE1bits.RCIE=0;        //关闭接收中断
  158.     INTCONbits.PEIE=1;            //
  159.     INTCONbits.GIE=1;
  160.    
  161. }
  162. /***************************************************************************
  163. 中断子程序
  164. **************************************************************************/
  165. void interrupt isr (void)
  166. {
  167.     if( CCP1IE && CCP1IF )
  168.     {
  169.         if(eccp_up_down_flag==0)    //上升沿检测
  170.         {
  171.             eccp1_down();          //进行下降沿检测        
  172.         }
  173.         else
  174.         {            
  175.             eccp1_disable();       //     
  176.             time_ccpr1l = CCPR1L;  //
  177.             time_ccpr1h = CCPR1H;  //
  178.             CCPR1L=0;              //
  179.             CCPR1H=0;              //
  180.             TMR1H=0;
  181.             TMR1L=0;
  182.             T1CON=0x20;            
  183.             distance_ok_flag=1;    //检测完毕
  184.             disp_number=(uint16_t)time_ccpr1h<<8 | time_ccpr1l;   //distance save         
  185.             PIR1bits.CCP1IF = 0;   
  186.         }      
  187.     }
  188.    
  189. }
  190. void serial_send(uint8_t send_data )
  191. {
  192.     TXREG = send_data;
  193.     while(TRMT==0);
  194. }
  195. void main()
  196. {   
  197.     uint8_t i;
  198.     sys_init();                     //system initialize   
  199.     disp_data=1234;                 
  200.     sprintf(buffer,"%d",disp_data);
  201.     disp_num=strlen(buffer);        //display"1234"
  202.      __delay_ms(100);   
  203.      while(1)
  204.     {
  205.         distance_test();            //test distance
  206.         for(i=0;i<120;i++)
  207.         {
  208.             disp();                 //display distance
  209.             __delay_ms(1);
  210.         }      
  211.     }   
  212. }
  213. void sys_init()
  214. ……………………

  215. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码


所有资料51hei提供下载:
超声波测距.rar (115.19 KB, 下载次数: 68)
超声波测距.pdf (38.51 KB, 下载次数: 42)

评分

参与人数 1黑币 +80 收起 理由
admin + 80 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:102963 发表于 2018-12-8 09:20 | 只看该作者
没法编译,缺少头文件xc.h
回复

使用道具 举报

板凳
ID:18297 发表于 2018-12-8 11:49 | 只看该作者
songxia8013 发表于 2018-12-8 09:20
没法编译,缺少头文件xc.h

使用mplab x的环境XC8的编译器编译,不要用以前的mplab ide8.70
回复

使用道具 举报

地板
ID:506519 发表于 2019-4-12 21:20 | 只看该作者
zjjhtony 发表于 2018-12-8 11:49
使用mplab x的环境XC8的编译器编译,不要用以前的mplab ide8.70

能不能用CCS编译器啊?
回复

使用道具 举报

5#
ID:18297 发表于 2019-4-13 20:24 | 只看该作者
可能需要修改库函数。为什么不用免费的mplab X呢?
回复

使用道具 举报

6#
ID:506519 发表于 2019-4-14 15:18 来自手机 | 只看该作者
zjjhtony 发表于 2019-4-13 20:24
可能需要修改库函数。为什么不用免费的mplab X呢?

这个老师要求用CCS来
回复

使用道具 举报

7#
ID:48413 发表于 2019-8-29 20:34 | 只看该作者
学习一下
回复

使用道具 举报

8#
ID:592524 发表于 2019-9-27 14:54 | 只看该作者
谢谢分享。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表