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

Posted XGLIYOUQUAN

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了实例8:stc8a8k外部中断,计算小车运行的距离相关的知识,希望对你有一定的参考价值。

一、实验目的
通过stc8a8k的外部中断,计算小车运动的距离;
熟悉外部中断的使用和设置;
熟悉光电码盘的原理和使用;
熟悉OLED的使用;
二、实验设备
stc8a8k自制开发板;
OLED屏幕,4脚;
光电码盘;
小车电机;
三、实验原理
1、光电码盘的原理
2、电机驱动原理(前面循迹已经说过,不再重复,看实例3的博客)
3、外部中断的原理和设置

1、光电码盘的原理
这个黑色的就是码盘。


需要配套测速模块进行测试。

测速和计算距离的原理:

小车电机转动,那么光电码盘转动,里面有栅格,测速模块有一边是发光,一边接受光的,当转动到空格的地方,光通过接收到,当转动到不是空格的地方,光没接收到,那么就有两个状态,接收光和没接收光,对应于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

3、外部中断的原理和设置

上面的光电测速模块的信号引脚,我们接到单片机的外部中断引脚中,我们设置它下降沿触发中断,什么是下降沿,就是原来是1,变为0,就是下降。0–1就是上升。
我们测试1–0的次数,就得到转动的格子的数。

单片机有哪些外部中断的引脚呢?
我们看看这个图。
有好多中断哦。我们选择一个,就用P33吧。P33这个中断是INT1。
怎么设置它是下降沿触发呢?
怎么打开中断开关呢?
那就要看他的寄存器了。





就这三个地方就好了。知道这几个控制着中断的模式和使能,那就方便了。

我们直接借助下载软件生成配置的程序。

#include "reg51.h"
#include "intrins.h"

sbit    P10         =   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引脚;

显示屏

四脚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个脉冲,

以上是关于实例8:stc8a8k外部中断,计算小车运行的距离的主要内容,如果未能解决你的问题,请参考以下文章

实例7:stc8a8k定时器0,定时50ms,进入中断之后,加数20次到1秒,计算时间。

实例5:寄存器操作学习:stc8a8k单片机硬件PWM的原理和代码讲解(置1清0位操作和高8位低8位拆分)

关于智能小车基于STM32和传感器码盘的测速

分类讨论的技巧

洛谷 1033自由落体

proteus-单片机-中断程序