实例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个脉冲,

  • 4
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
根据提供的引用内容,stc8g定时器外部计数的代码如下所示: ```c #include <reg52.h> void Timer2_Init(void) { AUXR &= ~0X08; //设置为定时器 AUXR |= 0x04; //工作时钟不分频 T2L = 0x48; T2H = 0x77; AUXR |= 0X10; //启动定时器2计数 IE2 |= 0X04; //使能定时器2中断 EA = 1; //打开总中断 } void Timer0_Init(void) { TMOD = 0x00; //配置工作模式 AUXR |= 0x80; //工作时钟不分频 TL0 = 0x48; TH0 = 0x77; TR0 = 1; //启动定时器0计数 ET0 = 1; //使能定时器0中断 EA = 1; //打开总中断 } void Timer1_Init(void) { TMOD = 0x00; //配置工作模式 AUXR |= 0x40; //工作时钟不分频 TL1 = 0x48; TH1 = 0x77; TR1 = 1; //启动定时器0计数 ET1 = 1; //使能定时器0中断 EA = 1; //打开总中断 } void main() { Timer2_Init(); // 初始化定时器2 Timer0_Init(); // 初始化定时器0 Timer1_Init(); // 初始化定时器1 while (1) { // 在这里编写你的代码 } } ``` 以上代码是一个示例,用于初始化stc8g的定时器2、定时器0和定时器1,并打开总中断。你可以在`while(1)`循环中编写你的代码,实现定时器外部计数的功能。请根据你的具体需求进行修改。 #### 引用[.reference_title] - *1* *2* *3* [STC8学习5 - 定时器](https://blog.csdn.net/m0_51371386/article/details/127706634)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值