定时器与中断1——流水灯小项目

图一

 main()

#include <REGX52.H>
#include <INTRINS.H>
#include "timer0.h"
unsigned char key();

/**
  * @brief  流水灯半秒流动;按下K1,流水灯变向
  * @param  
  * @retval  
  */
unsigned char KeyNum,LEDMode;
main(){
  P2=0xFE;
	Timer0Init();//中断初始化
	while(1){
		KeyNum=key();
		if(KeyNum){		//检测K1键是否按下;
			if(KeyNum==1) {
			  LEDMode++;
				if(LEDMode>=2) LEDMode=0;
			}
		}
	}
}
  
/**
  * @brief  定时器0中断程序;
  * @param  
  * @retval  
  */

void Timer0_Routine() interrupt 1{
	static unsigned int T0Count;
	TL0=0x18;//设置定时初始值
	TH0=0xFC;
	
	T0Count++;
	if(T0Count>=500){
		T0Count=0;
		if(LEDMode==0)
			P2=_crol_(P2,1);//每次左移一位
		if(LEDMode==1)
			P2=_cror_(P2,1);//每次右移一位
	}
}

 time0.h(测试头文件和声明的作用相同)

#ifndef __TIME0_H__
#define __TIME0_H__
void Timer0Init();
#endif
#include <REGX52.H>

/**
  * @brief  定时器初始化
  * @param  无
  * @retval 无
			程序中的变量在<REGX52.H>已有定义
  */
void Timer0Init(){	
	//*1  TMOD=0x01;//0000 0001;设置定时器0,16位定时器模式;
	//*2  TMOD=TMOD&0XF0;  //TMOD低四位清零,高四位不变;
	//	  TMOD=TMOD|0X01;		//TMOD的最后一位置零;
	//*3	
	TMOD&=0XF0;
	TMOD|=0X01;
	
	//设置TCON
	TF0=0;
	TR0=1;
	
	TH0=64535/256;//定时器寄存器高八位;定时1000ms;溢出为65535
	TL0=64535%256;//定时器寄存器低八位
	
	ET0=1;//允许中断
	EA=1;//打开全局中断
	PT0=0;
	//这三个变量的意义查看图1的下部分的中断系统电路
}

unsigned char key();

#include <REGX52.H>
void Delayms(unsigned int time);
/**
  * @brief  扫描按键是否按下,并返回按键值
  * @param  
  * @retval  按下则返回按键值,否则返回0;
  */
unsigned char key(){
	unsigned char KeyNumber=0;
	
	if(P3_1==0){Delayms(20);while(P3_1==0);Delayms(20);KeyNumber=1;}
	if(P3_0==0){Delayms(20);while(P3_0==0);Delayms(20);KeyNumber=2;}
	if(P3_2==0){Delayms(20);while(P3_2==0);Delayms(20);KeyNumber=3;}
	if(P3_3==0){Delayms(20);while(P3_3==0);Delayms(20);KeyNumber=4;}

	return KeyNumber;
}

 void Delayms(unsigned int time);

/**
  * @brief  延时  ms
  * @param  unsigned int time:延时的时间
  * @retval  
  */

void Delayms(unsigned int time){
	unsigned char i,j;
	while(time--){
		i=2;
		j=239;
		do{
			while(--j);
		}
			while(--i);
	}
}
  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,很高兴为您解答这个问题。以下是实现该功能的代码: ```c #include "stm32f10x.h" void TIM2_IRQHandler(void) { static uint8_t count = 0; // 清除定时器中断标志 TIM_ClearITPendingBit(TIM2, TIM_IT_Update); // 点亮流水灯 GPIO_SetBits(GPIOB, GPIO_Pin_5 << count); // 延时一段时间 for (volatile int i = 0; i < 500000; i++); // 熄灭流水灯 GPIO_ResetBits(GPIOB, GPIO_Pin_5 << count); // 更新计数器 count = (count + 1) % 3; if (count == 0) { // 流水灯已经闪烁了三次,停止定时器 TIM_Cmd(TIM2, DISABLE); } } int main(void) { // 使能时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); // 配置GPIO GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); // 配置定时器 TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_TimeBaseStructure.TIM_Period = 999; TIM_TimeBaseStructure.TIM_Prescaler = 7199; TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); // 使能定时器中断 TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); // 启动定时器 TIM_Cmd(TIM2, ENABLE); while (1); } ``` 在上面的代码中,我们使用了 TIM2 定时器以及 GPIOB 的 5、6、7 三个引脚来控制流水灯的闪烁。代码中的 `TIM2_IRQHandler` 函数是定时器中断处理函数,每次定时器中断时会执行其中的代码。 在 `TIM2_IRQHandler` 函数中,我们使用了一个静态变量 `count` 来记录流水灯的状态。每次定时器中断时,我们会点亮当前的 LED 引脚,然后经过一段延时后熄灭该引脚,并更新 `count` 的值。当 `count` 的值为 0 时,表示流水灯已经闪烁了三次,此时我们会停止定时器。 在 `main` 函数中,我们首先启用了 GPIOB 和 TIM2 的时钟。接着,我们配置了 GPIOB 的 5、6、7 引脚为输出模式,并配置了 TIM2 的计数器周期和预分频器,以及使能了定时器中断。最后,我们启动了定时器,并进入了一个死循环,等待定时器中断的触发。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值