stc8h8k64u 定时器配合独立按键控制流水灯模式+定时器实现数码管0-9显示

定时器配合独立按键控制流水灯模式

#include <STC8H.H>
#include<INTRINS.H>


unsigned int mode = 0;
void delay(void)	//@12.000MHz
{
	unsigned char data i, j, k;

	_nop_();
	_nop_();
	i = 10;
	j = 31;
	k = 147;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}

int getnum()
{
	unsigned int b = 0;
	if(P34 == 0)
	{
		delay();
		while(P34 == 0)
		{
			;
		}
		delay();
		b = 1;
		return b;
	}
	
	if(P35 == 0)
	{
		delay();
		while(P35 == 0)
		{
			;
		}
		delay();
		b = 2;
		return b;
	}
	
	return b;
	
}

void Timer0_Init(void)		//1毫秒@12.000MHz
{
	//可以具体操作某定时器的四位而不影响另外一个定时器的配置
	TMOD &= 0xF0;
	TMOD |= 0x01;
	TL0 = 0x18;				//设置定时初始值
	TH0 = 0xFC;				//设置定时初始值
	TF0 = 0;				//清除TF0标志
	TR0 = 1;				//定时器0开始计时
	ET0 = 1;
    EA = 1;
    PT0 = 0;	
}

void main()
{
	unsigned   n = 0;
	unsigned int num = 0;
	
	P0M0 = 0x00; P0M1 = 0x00; 
	P1M0 = 0x00; P1M1 = 0x00; 
	P2M0 = 0x00; P2M1 = 0x00; 
	P3M0 = 0x00; P3M1 = 0x00; 
	P4M0 = 0x00; P4M1 = 0x00; 
	P5M0 = 0x00; P5M1 = 0x00; 
	P6M0 = 0x00; P6M1 = 0x00; 
	P7M0 = 0x00; P7M1 = 0x00; 
 
	P40 = 0;
	
	P6 = 0xfe;
    Timer0_Init();
	while(1)
	{
		n = getnum();
		switch(n)
		{
			case 1:
				mode = 1;
			    break;
			case 2:
				mode = 2;
			    break;
			default:
				break;
		}
	}
}


void Timer0_Isr(void) interrupt 1
{
	static unsigned int count = 0;
	TL0 = 0x18;				//设置定时初始值
	TH0 = 0xFC;	
	count++;
	if(count >= 500)
	{
		count = 0;
		if(mode == 1)
		{
			P6 = _crol_(P6,1);
		}
		if(mode == 2)
		{
			P6 = _cror_(P6,1);
		}
	}
	
}
  •  定时器的配置

void Timer0_Init(void)		//1毫秒@12.000MHz
{
	//可以具体操作某定时器的四位而不影响另外一个定时器的配置
	TMOD &= 0xF0;
	TMOD |= 0x01;
	TL0 = 0x18;				//设置定时初始值
	TH0 = 0xFC;				//设置定时初始值
	TF0 = 0;				//清除TF0标志
	TR0 = 1;				//定时器0开始计时
	ET0 = 1;
    EA = 1;
    PT0 = 0;	
}

stc8h8k64u 单片机共有五个定时器(详情参考使用手册),首先我们先配置定时器模式寄存器(TMOD),在这里我们这使用定时器T0,所以给TMOD赋0000 0001,TL0,TH0两个八位寄存器在16位模式合在一起使用,定时器1us自增一次,16位的最高值位65535,我们这里将这两个寄存器的初始值设置为64535,也就是1ms中断一次,TF0位溢出进位标志,先将其请0,TR0为定时器开始计时标志,1为开始计时,ET0则为允许中断,1表示允许中断,EA和PT0则是打开中断里的两个通路(也可以不配置) 

  • 相关寄存器 

  • 逻辑实现 

void Timer0_Isr(void) interrupt 1
{
	static unsigned int count = 0;
	TL0 = 0x18;				//设置定时初始值
	TH0 = 0xFC;	
	count++;
	if(count >= 500)
	{
		count = 0;
		if(mode == 1)
		{
			P6 = _crol_(P6,1);
		}
		if(mode == 2)
		{
			P6 = _cror_(P6,1);
		}
	}
	
}

在这个中断函数里,由于我们上面设置了定时器为1ms,所以我们使用一个静态变量(调用完函数不会销毁),来控制你想打要实现的定时,比如我这里的count >= 500就是0.5s,然后通过主函数获取独立按键按下,获取流水灯的模式(正向和反向),这里的_crol_(左移)_cror_(右移),为库函数,包含头文件#include<INTRINS.H>即可使用,这两个函数的优点在于使得P6口在1111 1110 - 1111 1110之间循环。

数码管显示0-9循环

#include <STC8H.H>
#include<INTRINS.H>

unsigned int num = 0;
unsigned int arr[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xBF};
void delay(void)	//@12.000MHz
{
	unsigned char data i, j, k;

	_nop_();
	_nop_();
	i = 10;
	j = 31;
	k = 147;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}



void Timer0_Init(void)		//1毫秒@12.000MHz
{
	//可以具体操作某定时器的四位而不影响另外一个定时器的配置
	TMOD &= 0xF0;
	TMOD |= 0x01;
	TL0 = 0x18;				//设置定时初始值
	TH0 = 0xFC;				//设置定时初始值
	TF0 = 0;				//清除TF0标志
	TR0 = 1;				//定时器0开始计时
	ET0 = 1;
    EA = 1;
    PT0 = 0;	
}

void main()
{
	P0M0 = 0x00; P0M1 = 0x00; 
	P1M0 = 0x00; P1M1 = 0x00; 
	P2M0 = 0x00; P2M1 = 0x00; 
	P3M0 = 0x00; P3M1 = 0x00; 
	P4M0 = 0x00; P4M1 = 0x00; 
	P5M0 = 0x00; P5M1 = 0x00; 
	P6M0 = 0x00; P6M1 = 0x00; 
	P7M0 = 0x00; P7M1 = 0x00; 
 
	P40 = 0;
	
	P7 = ~0x01;
    Timer0_Init();
	while(1)
	{
		P6 = arr[num];
	}
}


void Timer0_Isr(void) interrupt 1
{
	static unsigned int count = 0;
	TL0 = 0x18;				//设置定时初始值
	TH0 = 0xFC;	
	count++;
	if(count >= 600)
	{
		count = 0;
		if(num < 9)
		{
			num++;
		}
		else
		{
			num = 0;
		}
	}
	
}

 这里我是使用了一个数组存储了数码管显示0-9的十六进制数,显示的位置固定为第一个数码管,在中断函数中当0.6s到了,对全局变量num++(num来作为数组的下标),控制num在0-9以内,因为在主函数里p6 = arr[num],且在while死循环里,当num改变时p6口也随之改变。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值