实例8(stc8a8k外部中断,计算小车运行的距离)

枕上从妨一夜睡,灯前读尽十年诗。这篇文章主要讲述实例8:stc8a8k外部中断,计算小车运行的距离相关的知识,希望能为你提供帮助。
一、实验目的
通过stc8a8k的外部中断,计算小车运动的距离;
熟悉外部中断的使用和设置;
熟悉光电码盘的原理和使用;
熟悉OLED的使用;
二、实验设备
stc8a8k自制开发板;
OLED屏幕,4脚;
光电码盘;
小车电机;
三、实验原理
1、光电码盘的原理
2、电机驱动原理(前面循迹已经说过,不再重复,看实例3的博客)
3、外部中断的原理和设置
1、光电码盘的原理
这个黑色的就是码盘。

实例8(stc8a8k外部中断,计算小车运行的距离)

文章图片

实例8(stc8a8k外部中断,计算小车运行的距离)

文章图片

需要配套测速模块进行测试。
实例8(stc8a8k外部中断,计算小车运行的距离)

文章图片

实例8(stc8a8k外部中断,计算小车运行的距离)

文章图片

测速和计算距离的原理:
实例8(stc8a8k外部中断,计算小车运行的距离)

文章图片

小车电机转动,那么光电码盘转动,里面有栅格,测速模块有一边是发光,一边接受光的,当转动到空格的地方,光通过接收到,当转动到不是空格的地方,光没接收到,那么就有两个状态,接收光和没接收光,对应于0–1--0–1--0–1
就是一个个跳变,我们计算跳变的次数,就得到小车轮子转过了多少个空格。
这个码盘,一圈360度,有20个栅格。
小车的轮子直径是67mm。那么最小一个格子的精度是
周长/20=pi直径/20=3.141592667/20=
就可以计算该码盘能检测到的最小精度为: 3.1467mm/20 =10.2 mm
我们计算多少个脉冲,假如是N,那个距离就是dis=N
10.2mm
实例8(stc8a8k外部中断,计算小车运行的距离)

文章图片

3、外部中断的原理和设置 上面的光电测速模块的信号引脚,我们接到单片机的外部中断引脚中,我们设置它下降沿触发中断,什么是下降沿,就是原来是1,变为0,就是下降。0–1就是上升。
我们测试1–0的次数,就得到转动的格子的数。
实例8(stc8a8k外部中断,计算小车运行的距离)

文章图片

单片机有哪些外部中断的引脚呢?
我们看看这个图。
有好多中断哦。我们选择一个,就用P33吧。P33这个中断是INT1。
怎么设置它是下降沿触发呢?
怎么打开中断开关呢?
那就要看他的寄存器了。
实例8(stc8a8k外部中断,计算小车运行的距离)

文章图片

实例8(stc8a8k外部中断,计算小车运行的距离)

文章图片

实例8(stc8a8k外部中断,计算小车运行的距离)

文章图片

实例8(stc8a8k外部中断,计算小车运行的距离)

文章图片

实例8(stc8a8k外部中断,计算小车运行的距离)

文章图片

就这三个地方就好了。知道这几个控制着中断的模式和使能,那就方便了。
我们直接借助下载软件生成配置的程序。
实例8(stc8a8k外部中断,计算小车运行的距离)

文章图片

#include "reg51.h" #include "intrins.h"sbitP10=P1^0; void INT1_Isr() interrupt 2 using 1 { P10 = !P10; //测试端口 }void main() { IT1 = 1; //使能INT1下降沿中断 EX1 = 1; //使能INT1中断 EA = 1; while (1); }

很简单对吧,
IT1,=1设置下降沿触发;
EX1=1,打开中断INT1的开关
EA=1,打开大中断开关。
就三条语句,单片机就按照我们的想法执行外部中断了。
后面就在中断服务函数里面执行,让P10这个口的状态,进入一次取反一次。如果接的LED,那么进入一次,LED亮灭一次。
void INT1_Isr() interrupt 2 using 1
{
P10 = !P10; //测试端口
}
说了这么多,我们测试下代码。
硬件 接线: 测速模块 VCC—5V
GND—GND
OUT(或者D0)—P33引脚;
显示屏 【实例8(stc8a8k外部中断,计算小车运行的距离)】四脚OLED
GND----------GND
VCC-----------VCC
SCL--------P74
SDA-----------P75
按键KEY-----------P35
代码如下:
//******************************************************************************/ #include "stc8a8k.h" #include "oled.h" #include "stdio.h"//显示浮点数的sprintf函数,需要 sbit key0=P3^5; unsigned char disbuf[9]; //给浮点数显示使用 unsigned int countpulse=0; //小车码盘的脉冲数 float distance=0.01; //测试小车走的距离 void delay_tms(unsigned int ms) { unsigned int i,j; for(i=ms; i> 0; i--) for(j=0; j< 1100; j++); } //INT1的中断服务函数--------------一旦发生中断,就执行这个函数,执行完之后,继续跑到之前没执行完的地方继续执行 void INT1_Isr() interrupt 2 using 1 {countpulse++; //脉冲次数加一,每次进来+1} //***************************************** void main() { IT1 = 1; //使能INT1下降沿中断 EX1 = 0; //不使能INT1中断,用按键使能 EA = 1; //打开大开关OLED_Init(); //初始化OLED OLED_Clear() ; while (1) { //按下开关,开启外部中断INT1 if(key0==0) { delay_tms(15); //延时去抖动 if(key0==0) { EX1=1; //开启外部中断INT1 } }distance=countpulse*10.2; //3.14159*67mm/20,周长除以20,得到每个格子的弧长数值 sprintf(disbuf,"%.2f",distance); OLED_ShowString(4*8,0,disbuf,16); //显示距离 OLED_ShowNum(5*8,2,countpulse,5,16); // 显示脉冲次数} }

下载代码之后,用手转动小车轮胎一圈,看下显示屏上面是不是得到20个脉冲,

    推荐阅读