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

文章详细介绍了使用STM8微控制器(以STC12C5A60S2为例)进行点灯操作的不同方法,包括软件延时、定时器0的四种模式下的中断和查询点灯方式,以及流水灯演示。每种方法都提供了代码示例,展示了如何通过设置定时器模式和处理中断来实现LED灯的定时开关,同时讨论了不同模式下的计时精度和中断查询的影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

先用软件延时点个灯

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

选择还不少,先试试定时器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大全套,内含定时器点灯,分中断与查询,配套博客文档资源-优快云文库

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值