枕上从妨一夜睡,灯前读尽十年诗。这篇文章主要讲述实例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=N10.2mm
文章图片
3、外部中断的原理和设置 上面的光电测速模块的信号引脚,我们接到单片机的外部中断引脚中,我们设置它下降沿触发中断,什么是下降沿,就是原来是1,变为0,就是下降。0–1就是上升。
我们测试1–0的次数,就得到转动的格子的数。
文章图片
单片机有哪些外部中断的引脚呢?
我们看看这个图。
有好多中断哦。我们选择一个,就用P33吧。P33这个中断是INT1。
怎么设置它是下降沿触发呢?
怎么打开中断开关呢?
那就要看他的寄存器了。
文章图片
文章图片
文章图片
文章图片
文章图片
就这三个地方就好了。知道这几个控制着中断的模式和使能,那就方便了。
我们直接借助下载软件生成配置的程序。
文章图片
#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);
// 显示脉冲次数}
}
推荐阅读
- RedHat的yum配置 以及提示“This system is not registered with RHN”的解决
- 实例6,stc8a8k单片机开发板4脚的OLED显示数据(I2C通信)
- MYSQL查看和新增表分区
- 实例5(寄存器操作学习:stc8a8k单片机硬件PWM的原理和代码讲解(置1清0位操作和高8位低8位拆分))
- delay.h和delay.c程序,记得分别复制,保存成delay.h和delay.c文件。11.0592M晶振频率
- Linux配置定时,使用 crontab -e 与 直接编辑 /etc/crontab 的区别
- 浏览器自动将s标签添加到html错误中
- WordPress网站页脚下方的空白
- 论坛的最佳WordPress主题()