蓝桥杯单片机 超声波模块和PCA模块
原理
超声波测量的原理
超声波由一个超声波模块向前方发出,并在空气中传播,在遇到障碍物时发生反射,再被另一个超声波模块接收。单片机用定时器测量超声波从发出到接收的时长,再根据声速,即可算出超声波模块到障碍物之间的距离。公式:距离=(声速 × Δ时间)÷2
。若距离单位为厘米,时间单位为微秒,距离公式为距离=Δ时间 x 0.017
。
另外,对距离进行微分等其他数学运算,还可以得到速度等其他测量值。测速公式:速度= (本次测量距离 - 上次测量距离 )÷两次测量时间间隔
。
以CT107D
竞赛板为例,控制单片机在P10
输出一段38~41kHz
的方波,八个周期,发射模块就会产生一段超声波。当接收模块接收到超声波,则会在P11
产生一个下降沿。需测量超声波发出后,到下降沿产生之间的时间长度。下图为示波器测量的P10
P11
的波形图。
PCA模块的原理
目前蓝桥杯单片机MCU型号为IAP15F2K61S2
,它有一个PCA模块可以用来实现定时、测量脉宽、PWM等功能。在使用PCA模块时,注意加载STC15F2K60S2.H
的头文件来定义特殊功能寄存器。
使用PCA模块驱动超声波的优点就在于,它由硬件控制计时,并可以自动捕获电平的变化,装载计数的值同时产生中断。CPU可以在控制发射超声波后,空闲出来进行数码管显示等其他任务。
关于PCA定时器的计数频率,可以选择SYSclk/12
,这样时间单位才为微秒,因此CMOD
寄存器应该设置为0x01
(不要以图示给出的顺序配置CPSn
位,请参考数据手册关于CMOD
的说明,来配置寄存器)。
对于超声波模块对应的P11
引脚,要使PCA工作在下降沿捕获模式,须将CAPN0
置位,将CAPP0
清零。发送超声波后,先将阵列寄存器(CL
CH
)和中断标志(CCF0
CF
)清零,再开启PCA模块计时及其中断。当P11
产生下降沿时,阵列寄存器(CL
和CH
)的值装载到模块的捕获寄存器(CCAP0L
和CCAP0H
)中,并产生中断。
中断处理时要判断是下降沿捕获(CCF0==1
)还是定时器溢出(CF==1
),注意清零中断标志、关闭PCA定时器及其中断标志。
代码
PCA定时器的范例程序
从STC-ISP
上可以直接获取PCA定时器的范例程序,在“范例程序 > STC15Fxx/STC15Lxx/STC15Wxx Series > PCA的16位捕获测量脉宽 > C”。或从STC15系列单片机用户手册,第11章11.9节
获得范例程序。
选手可在比赛中参考该代码,编写超声波驱动。范例程序如下。
/*---------------------------------------------------------------------*/
/* --- STC MCU Limited ------------------------------------------------*/
/* --- STC15F4K60S4 系列 PCA实现16位捕获举例---------------------------*/
/* --- Mobile: (86)13922805190 ----------------------------------------*/
/* --- Fax: 86-0513-55012956,55012947,55012969 ------------------------*/
/* --- Tel: 86-0513-55012928,55012929,55012966-------------------------*/
/* --- Web: www.STCMCU.com --------------------------------------------*/
/* --- Web: www.GXWMCU.com --------------------------------------------*/
/* 如果要在程序中使用此代码,请在程序中注明使用了STC的资料及程序 */
/* 如果要在文章中应用此代码,请在文章中注明使用了STC的资料及程序 */
/*---------------------------------------------------------------------*/
//本示例在Keil开发环境下请选择Intel的8058芯片型号进行编译
//若无特别说明,工作频率一般为11.0592MHz
#include "reg51.h"
#include "intrins.h"
#define FOSC 11059200L
typedef unsigned char BYTE;
typedef unsigned int WORD;
typedef unsigned long DWORD;
sfr P0M1 = 0x93;
sfr P0M0 = 0x94;
sfr P1M1 = 0x91;
sfr P1M0 = 0x92;
sfr P2M1 = 0x95;
sfr P2M0 = 0x96;
sfr P3M1 = 0xb1;
sfr P3M0 = 0xb2;
sfr P4M1 = 0xb3;
sfr P4M0 = 0xb4;
sfr P5M1 = 0xC9;
sfr P5M0 = 0xCA;
sfr P6M1 = 0xCB;
sfr P6M0 = 0xCC;
sfr P7M1 = 0xE1;
sfr P7M0 = 0xE2;
sfr P_SW1 = 0xA2; //外设功能切换寄存器1
#define CCP_S0 0x10 //P_SW1.4
#define CCP_S1 0x20 //P_SW1.5
sfr CCON = 0xD8; //PCA控制寄存器
sbit CCF0 = CCON^0; //PCA模块0中断标志
sbit CCF1 = CCON^1; //PCA模块1中断标志
sbit CR = CCON^6; //PCA定时器运行控制位
sbit CF = CCON^7; //PCA定时器溢出标志
sfr CMOD = 0xD9; //PCA模式寄存器
sfr CL = 0xE9; //PCA定时器低字节
sfr CH = 0xF9; //PCA定时器高字节
sfr CCAPM0 = 0xDA; //PCA模块0模式寄存器
sfr CCAP0L = 0xEA; //PCA模块0捕获寄存器 LOW
sfr CCAP0H = 0xFA; //PCA模块0捕获寄存器 HIGH
sfr CCAPM1 = 0xDB; //PCA模块1模式寄存器
sfr CCAP1L = 0xEB; //PCA模块1捕获寄存器 LOW
sfr CCAP1H = 0xFB; //PCA模块1捕获寄存器 HIGH
sfr CCAPM2 = 0xDC