从点亮LED开始(定时器的使用)

目录

先用软件延时点个灯

效果是非常滴不错,再来个定时器点灯吧

选择还不少,先试试定时器0的模式0,即13位定时器

中断点灯

查询点灯

定时器0的模式1,即16位定时器

中断点灯

查询点灯

定时器0的模式2,即8位自动重装定时器

中断点灯

查询点灯

定时器0的模式3,即8位自动重装定时器

中断点灯

查询点灯  

流水灯演示


拿到开发板,又到了经典的点灯环节😂

先看一手原理图

 DB1对应于P1.0脚,将其电平拉低即可点亮

先用软件延时点个灯

#include <STC12C5A60S2.H>
sbit led1=P1^0;

void Delay300ms()		//@11.0592MHz
{
	unsigned char i, j, k;

	i = 13;
	j = 156;
	k = 83;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}


void main()
{
	while(1)
	{
		led1=~led1;
		Delay300ms();
		
	}
}

效果是非常滴不错,再来个定时器点灯吧

选择还不少,先试试定时器0的模式0,即13位定时器

中断点灯

#include <STC12C5A60S2.H>
sbit led1=P1^0;

unsigned int cnt;

void Timer0_Init(void)		//100微秒@11.0592MHz
{
	AUXR |= 0x80;			//定时器时钟1T模式
	TMOD &= 0xF0;			//设置定时器模式
	TL0 = 0x70;				//设置定时初始值
	TH0 = 0xDD;				//设置定时初始值
	TF0 = 0;				//清除TF0标志
	TR0 = 1;				//定时器0开始计时
}

void main()
{
	EA=1;					//开启中断
	ET0=1;					//开启定时器中断
	Timer0_Init();
	while(1)
	{
		if(cnt==10000)
		{
			led1=~led1;
			cnt=0;
		}	
	}
}


void Timer0_Isr(void) interrupt 1
{
	TL0 = 0x70;				//设置定时初始值
	TH0 = 0xDD;				//设置定时初始值
	cnt++;
	
}

查询点灯

#include <STC12C5A60S2.H>
sbit led1=P1^0;

unsigned int cnt;

void Timer0_Init(void)		//100微秒@11.0592MHz
{
	AUXR |= 0x80;			//定时器时钟1T模式
	TMOD &= 0xF0;			//设置定时器模式
	TL0 = 0x70;				//设置定时初始值
	TH0 = 0xDD;				//设置定时初始值
	TF0 = 0;				//清除TF0标志
	TR0 = 1;				//定时器0开始计时
}

void main()
{
	Timer0_Init();
	while(1)
	{
		if(TF0==1)
		{
			TL0 = 0x70;				//设置定时初始值
			TH0 = 0xDD;				//设置定时初始值
			cnt++;
			TF0=0;
		}
		if(cnt==10000)
		{
			led1=~led1;
			cnt=0;
		}
		
	}
}

上面两个的效果都是1s亮1s灭

定时器0的模式1,即16位定时器

中断点灯

换汤不换药,就是定时器初值改变了

#include <STC12C5A60S2.H>
sbit led1=P1^0;

unsigned int cnt;

void Timer0_Init(void)		//100微秒@11.0592MHz
{
	AUXR |= 0x80;			//定时器时钟1T模式
	TMOD &= 0xF0;			//设置定时器模式
	TMOD |= 0x01;			//设置定时器模式
	TL0 = 0xAE;				//设置定时初始值
	TH0 = 0xFB;				//设置定时初始值
	TF0 = 0;				//清除TF0标志
	TR0 = 1;				//定时器0开始计时
}

void main()
{
	EA=1;					//开启中断
	ET0=1;					//开启定时器中断
	Timer0_Init();
	while(1)
	{
		if(cnt==10000)
	    {
		    led1=~led1;
		    cnt=0;
	    }
	}
}


void Timer0_Isr(void) interrupt 1
{
	TL0 = 0xAE;				//设置定时初始值
	TH0 = 0xFB;				//设置定时初始值
	cnt++;
}

查询点灯

#include <STC12C5A60S2.H>
sbit led1=P1^0;

unsigned int cnt;

void Timer0_Init(void)		//100微秒@11.0592MHz
{
	AUXR |= 0x80;			//定时器时钟1T模式
	TMOD &= 0xF0;			//设置定时器模式
	TMOD |= 0x01;			//设置定时器模式
	TL0 = 0xAE;				//设置定时初始值
	TH0 = 0xFB;				//设置定时初始值
	TF0 = 0;				//清除TF0标志
	TR0 = 1;				//定时器0开始计时
}

void main()
{
	Timer0_Init();
	while(1)
	{
		if(TF0==1)
		{
			TL0 = 0xAE;				//设置定时初始值
			TH0 = 0xFB;				//设置定时初始值
			cnt++;
			TF0=0;
		}
		if(cnt==10000)
		{
			led1=~led1;
			cnt=0;
		}
		
	}
}

定时器0的模式2,即8位自动重装定时器

板载晶振为11.0592MHz对计时精度有所影响,选择影响最低的22us延时,误差0.12%

中断点灯

#include <STC12C5A60S2.H>
sbit led1=P1^0;

unsigned int cnt;


void Timer0_Init(void)		//22微秒@11.0592MHz
{
	AUXR |= 0x80;			//定时器时钟1T模式
	TMOD &= 0xF0;			//设置定时器模式
	TMOD |= 0x02;			//设置定时器模式
	TL0 = 0x0D;				//设置定时初始值
	TH0 = 0x0D;				//设置定时重载值
	TF0 = 0;				//清除TF0标志
	TR0 = 1;				//定时器0开始计时
	ET0 = 1;				//使能定时器0中断
}

void main()
{
	EA=1;					//开启中断
	ET0=1;					//开启定时器中断
	Timer0_Init();
	while(1)
	{
		if(cnt==45454)
		{
			led1=~led1;
			cnt=0;
		}
	}
}


void Timer0_Isr(void) interrupt 1
{
	cnt++;
}

查询点灯

#include <STC12C5A60S2.H>
sbit led1=P1^0;

unsigned int cnt;

void Timer0_Init(void)		//22微秒@11.0592MHz
{
	AUXR |= 0x80;			//定时器时钟1T模式
	TMOD &= 0xF0;			//设置定时器模式
	TMOD |= 0x02;			//设置定时器模式
	TL0 = 0x0D;				//设置定时初始值
	TH0 = 0x0D;				//设置定时重载值
	TF0 = 0;				//清除TF0标志
	TR0 = 1;				//定时器0开始计时
}


void main()
{
	Timer0_Init();
	while(1)
	{
		if(TF0==1)
		{
			cnt++;
			TF0=0;
		}
		if(cnt==45454)
		{
			led1=~led1;
			cnt=0;
		}
		
	}
}

定时器0的模式3,即8位自动重装定时器

 这是定时器0独有

中断点灯

#include <STC12C5A60S2.H>
sbit led1=P1^0;
sbit led2=P1^1;
unsigned int cnt0,cnt1;


void Timer0_Init(void)		//22微秒@11.0592MHz
{
	AUXR |= 0x80;			//定时器时钟1T模式
	TMOD &= 0xF0;			//设置定时器模式
	TMOD |= 0x03;			//设置定时器模式
	TL0 = 0x0D;				//设置定时初始值
	TH0 = 0x86;				//11us
	TF0 = 0;				//清除TF0标志
	TR0 = 1;				//定时器0开始计时
	ET0 = 1;				//使能定时器0中断
}

void main()
{
	EA=1;					//开启中断
	ET1=1;					//开启定时器1中断
	TR1=1;					//开启定时器1
	/*需要注意的是,此处定时器0工作模式为3,TH的8位定时器占用了定时器 1的TR与TF*/
	Timer0_Init();
	while(1)
	{
		if(cnt0==45454)
		{
			led1=~led1;
			cnt0=0;
		}
		if(cnt1==22727)
		{
			led2=~led2;
			cnt1=0;
		}
	}
}
void Timer0_Isr(void) interrupt 1
{
	TL0 = 0x0D;
	cnt0++;
}
void Timer1_Isr(void) interrupt 3
{
	TH0 = 0x86;
	cnt1++;
}

查询点灯  

#include <STC12C5A60S2.H>
sbit led1=P1^0;
sbit led2=P1^1;
unsigned int cnt0,cnt1;


void Timer0_Init(void)		//22微秒@11.0592MHz
{
	AUXR |= 0x80;			//定时器时钟1T模式
	TMOD &= 0xF0;			//设置定时器模式
	TMOD |= 0x03;			//设置定时器模式
	TL0 = 0x0D;				//设置定时初始值
	TH0 = 0x86;				//11us
	TF0 = 0;				//清除TF0标志
	TR0 = 1;				//定时器0开始计时
	ET0 = 1;				//使能定时器0中断
}

void main()
{
	EA=1;					//开启中断
	ET1=1;					//开启定时器1中断
	TR1=1;					//开启定时器1
	/*需要注意的是,此处定时器0工作模式为3,TH的8位定时器占用了定时器 1的TR与TF*/
	Timer0_Init();
	while(1)
	{
		if(TF0==1)
		{
			TF0=0;
			TL0 = 0x0D;
			cnt0++;
		}
		if(TF1==1)
		{
			TF1=0;
			TH0 = 0x86;
			cnt1++;
		}
		if(cnt0==45454)
		{
			led1=~led1;
			cnt0=0;
		}
		if(cnt1==22727)
		{
			led2=~led2;
			cnt1=0;
		}
	}
}

二者的现象基本是两个灯按1:2频率闪烁 ,但中断与查询法有细微不同,可能是查询过多占用的问题。

定时器 1和定时器0差不多,不再赘述

流水灯演示

#include <STC12C5A60S2.H>

void Delay500ms()		//@11.0592MHz
{
	unsigned char i, j, k;

	i = 22;
	j = 3;
	k = 227;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}

void main()
{
	char i;
	while(1)
	{
		P1=0x01;
		for(i=0;i<8;i++)
		{
			P1=P1<<1;
			if(P1==0x00)
			P1=0x01;
			Delay500ms();
		}		
	}	
}

工程资料获取:(126条消息) 点亮led大全套,内含定时器点灯,分中断与查询,配套博客文档资源-CSDN文库

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以STM32为例,使用库函数HAL库实现定时器6定时点亮LED的代码如下: ```c #include "stm32f1xx_hal.h" TIM_HandleTypeDef htim6; void SystemClock_Config(void); static void MX_GPIO_Init(void); static void MX_TIM6_Init(void); int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_TIM6_Init(); while (1) { // 等待定时器触发中断 } } void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { if (htim == &htim6) // 判断是否为定时器6触发的中断 { HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13); // 点亮LED } } void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; __HAL_RCC_PWR_CLK_ENABLE(); __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { Error_Handler(); } RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) { Error_Handler(); } } static void MX_TIM6_Init(void) { TIM_MasterConfigTypeDef sMasterConfig = {0}; htim6.Instance = TIM6; htim6.Init.Prescaler = 7199; htim6.Init.CounterMode = TIM_COUNTERMODE_UP; htim6.Init.Period = 4999; if (HAL_TIM_Base_Init(&htim6) != HAL_OK) { Error_Handler(); } sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; if (HAL_TIMEx_MasterConfigSynchronization(&htim6, &sMasterConfig) != HAL_OK) { Error_Handler(); } HAL_TIM_Base_Start_IT(&htim6); // 开始计数并启动定时器6中断 } static void MX_GPIO_Init(void) { GPIO_InitTypeDef GPIO_InitStruct = {0}; __HAL_RCC_GPIOC_CLK_ENABLE(); GPIO_InitStruct.Pin = GPIO_PIN_13; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); } ``` 在上述代码中,`MX_TIM6_Init()`函数初始化了定时器6的计数器值、预分频器值和自动重装载值,使得定时器6的溢出时间为500ms。`HAL_TIM_Base_Start_IT(&htim6)`函数开启了定时器6的中断,并启动了计数器。每当定时器6计数器溢出时,会触发中断,`HAL_TIM_PeriodElapsedCallback()`函数中的代码会被执行,其中通过`HAL_GPIO_TogglePin()`函数来驱动LED点亮

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值