利用定时器1实现流水灯

单片机实验1

题目: 利用定时器1实现流水灯,先从左至右,再从右至左,1s从左到右,1s从右到左(不采用延时函数的方式实现)

思路

首先要求使用定时器1,且定时1s,那么先将基础的初始化函数完成,计算初值为1ms.在服务函数中定义一个计数变量count并且让count自增,当count=1000时即达到要求的1s.接着题目要求led灯

先从左至右,再从右至左移动,这一功能通过使用左移函数与右移函数来完成,具体看示例程序

#include <reg51.h>
#include <intrins.h>

#define led P2

typedef unsigned char u8;
typedef unsigned int  u16;

u16 i,j;     //定义两个控制左移和右移的控制变量
void Time1Init(); //声明定时器1的初始化函数

void main()
{
	i   = 0;   //i用来控制左移 赋初值0
	j   = 8;   //j用来控制右移 赋初值8
	led = 0xfe;  //先点亮最左边的led灯
	Time1Init();
	while(1);
}

/*定时器1的初始化,设置初值为1ms*/
void Time1Init()
{
	TMOD |= 0x01;
	TH1   = 0xfc;
	TL1   = 0x18;
	
	EA    = 1;
	ET1   = 1;
	TR1   = 1;
}

/*配置定时器1的服务函数*/
void Time1Start() interrupt 3
{
	u16 count = 0;      //定义计数变量
	TH1   = 0xfc;
	TL1   = 0x18;
	count++;
	if(count == 1000) //达到1s
	{
		count = 0;    
		
		/*
		判断灯是否从左边开始,如果是led灯开始右移
		加上逻辑与的原因是防止漏掉灯在中间的情况		
		*/
		if(j==8 && i<8)	
		{
			led = _crol_(led,1);
		
		/*
		每移动一次就让控制左移的函数加1,直到第八个led灯
		如果到达第八个led灯,说明已经到达最右边,重新赋值
		*/
			i=i+1;
			if(i==8)
			{
				j = 0;
			}
		}
		/*原理同上*/
		if(i==8 && j<8)  
		{
			led = _cror_(led,1);
			j = j+1;
			if(j==8)
			{
				i = 0;
			}
		}
	}
}
  • 14
    点赞
  • 96
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
汇编语言可以利用定时器的不同工作方式实现流水灯控制。以下是一种实现方式: 首先,需要设置定时器的工作模式为模式1,即16位自动重载计数器。同时,需要设置定时器的时钟源和计数初值,以获得1钟的计时周期。 ``` MOV TMOD, #01 ; 设置定时器0为模式1,即16位自动重载计数器 MOV TH0, #0Bh ; 设置计数器初值为0x0BDC,以获得1钟的计时周期 MOV TL0, #0DCh ``` 接下来,需要开启定时器并设置中断,以便在定时器计数完成时触发中断服务程序。同时,需要设置一个存储流水灯状态的变量,以便在中断服务程序中更新流水灯的状态。 ``` SETB TR0 ; 开启定时器0 SETB ET0 ; 开启定时器0的中断 MOV LED, #01h ; 初始化流水灯状态为00000001 ``` 最后,需要编写定时器0中断服务程序。在中断服务程序中,需要将流水灯状态左移一位,并将最高位设置为原来的最低位,以实现流水灯的效果。 ``` TIMER0_ISR: CLR TF0 ; 清除定时器0中断标志 MOV A, LED ; 将流水灯状态存入累加器A MOV C, A.7 ; 将最高位存入进位标志C RLC A ; 将流水灯状态左移一位 MOV A.0, C ; 将进位标志C赋值给最低位 MOV LED, A ; 将更新后的流水灯状态存入变量 RETI ; 返回中断 ``` 完整的汇编代码如下: ``` ORG 0000h MOV TMOD, #01 ; 设置定时器0为模式1,即16位自动重载计数器 MOV TH0, #0Bh ; 设置计数器初值为0x0BDC,以获得1钟的计时周期 MOV TL0, #0DCh SETB TR0 ; 开启定时器0 SETB ET0 ; 开启定时器0的中断 MOV LED, #01h ; 初始化流水灯状态为00000001 MAIN_LOOP: SJMP MAIN_LOOP ; 主循环 TIMER0_ISR: CLR TF0 ; 清除定时器0中断标志 MOV A, LED ; 将流水灯状态存入累加器A MOV C, A.7 ; 将最高位存入进位标志C RLC A ; 将流水灯状态左移一位 MOV A.0, C ; 将进位标志C赋值给最低位 MOV LED, A ; 将更新后的流水灯状态存入变量 RETI ; 返回中断 END
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值