松翰SN8F5702芯片的学习记录(二)

        在学习记录一当中说到本期回介绍相关芯片的中断设置,同样的也会了解到有关中断定时器或计数器初值的算法。这里只说定时器T0,T1。关于外部中断自己看学习记录(一)的pdf文件。

定时器T0,T1中断的简要说明

        因为本人的一个习惯,不喜欢长篇大论。直接一步到位,不说其细节方面的内容了。想要自己了解的,自己搞懂怎么设置相关寄存器的看pdf文件。我这里直接给出对应定时器的寄存器设置方法。(图片解决,不在废话,请看下图)

         从上面的图片可以看到对应的寄存器设置。当你仔细看完后,在看下面的代码就很容易理解了。

void TimeInit()
{
	TMOD=0x05;//选16位向上计数
	TCON0=0x00;//选128分频
	TH0=0xff;//计算方式;2^n-(定时时间/(分频/时钟源))
	TL0=0xce;//2^16-(200us/128/32MHz)=65536-(200us/4us)
	ET0=1;//T0中断使能,可以理解为T0中断请求
	TR0=1;//开定时器,可以理解为T0中断允许
}

利用T0中断实现1S闪烁

        T0中断的初始化说完之后,就可以开始写其对应的中断要干的事情了(根具自己需求写,这里简单的运用一下);话不多说直接进入主题。

#include<SN8F5702.H>
/*
SN8F5702芯片只有P0.0-P0.7,P1.0-P1.7,P2.0-P2.1引脚
*/

sbit LED=P0^0;

#define uint unsigned int
#define uchar unsigned char
	

void GpioInit()
{
	//用户在用C语言编写的时候,必须按照这个顺序编写设置系统时钟
	CKCON  = 0x70;
	CLKSEL = 0x05;
	CLKCMD = 0x69;
  CKCON = 0x00;
	//芯片IO口的设置,P0,P1,P2
	//其中P1口有唤醒使能P1W
	P0=0x01;//输出高低电平控制,POM相应位使能
	P0M=0x01;//定义输入0输出1。
	P0UR=0x00;//内置上拉电阻控制,禁止0使能1
	
	P1=0x00;
	P1M=0x00;
	P1UR=0x00;
	P1W=0x00;//唤醒禁用0,使能1
	
	P2=0x00;
	P2M=0x00;
	P2UR=0x00;
	
}


void TimeInit()
{
	TMOD=0x05;//选16位向上计数
	TCON0=0x00;//选128分频
	TH0=0xff;//计算方式;2^n-(定时时间/(分频/时钟源))
	TL0=0x06;//2^16-(1ms/128/32MHz)=65536-(1ms/4us)=65286(ff06)
	ET0=1;//T0中断使能
	TR0=1;//开定时器
}


void main()
{
	GpioInit();
	TimeInit();
	EAL=1;//总中断控制
	while(1);
}

void Timer0_ISR(void) interrupt ISRTimer0
{
	static uint i=0;
	TH0=0xff;
	TL0=0x06;
	i++;
	if(i>=1000)
	{
		i=0;
		LED=~LED;
	}
}

        可能很多人看着也就那样,但如果你自己去看芯片的手册,自己去理解,就知道其中的艰辛。当然本次重点就在与初值的计算,跟89C51单片机不同,本人也是废了很长时间才验证得到,其他如有类似芯片可提供参考。

利用T0定时器实现次数闪灭

        同样原理,自己稍微思考就可以得到。这里只提供一个中断参考,有其他想法的自己去编写验证。

void Timer0_ISR(void) interrupt ISRTimer0
{
	static uint i=0,count=0;
	TH0=0xff;
	TL0=0x06;
	i++;
	if(i>=500)
	{
		i=0;
		LED=~LED;
		
		count++;//LED灯得闪烁,亮5次灭。
		if(count>=10)
		{
			TR0=0;
			LED=0;
		}
	}
}

利用T0定时器实现呼吸灯效果

        网上关于呼吸灯的介绍一大堆,各有各的代码,各有各的实现方式,本人这里也借用了网上的呼吸灯代码来实现。认为这段代码是比较好理解的。在验证的过程中,实现的效果不是太好,具体原因还未查明。最合适的设置定时为200us,计数100。这个可能与分频和芯片时钟有关。

#include<SN8F5702.H>
/*
SN8F5702芯片只有P0.0-P0.7,P1.0-P1.7,P2.0-P2.1引脚
*/

sbit LED=P0^0;

#define uint unsigned int
#define uchar unsigned char
	
uint i,k;


void GpioInit()
{
	//用户在用C语言编写的时候,必须按照这个顺序编写设置系统时钟
	CKCON  = 0x70;
	CLKSEL = 0x05;
	CLKCMD = 0x69;
  CKCON = 0x00;
	//芯片IO口的设置,P0,P1,P2
	//其中P1口有唤醒使能P1W
	P0=0x01;//输出高低电平控制,POM相应位使能
	P0M=0x01;//定义输入0输出1。
	P0UR=0x00;//内置上拉电阻控制,禁止0使能1,IO口为输出模式是建议禁止
	
	P1=0x00;
	P1M=0x00;
	P1UR=0x00;
	P1W=0x00;//唤醒禁用0,使能1
	
	P2=0x00;
	P2M=0x00;
	P2UR=0x00;
	
}

void TimeInit()
{
	TMOD=0x05;//选16位向上计数
	TCON0=0x00;//选128分频
	TH0=0xff;//计算方式;2^n-(定时时间/(分频/时钟源))
	TL0=0xce;//2^16-(400us/128/32MHz)=65536-(400us/4us)=65436(ff9e)
	ET0=1;//T0中断使能
	TR0=1;//开定时器
}


uint Tcount=0, dutyfactor=0, direct=0;
void ledbreath()
{
	if(Tcount >= 100)
	{
		Tcount=0;
		if(direct==0)
		{
			dutyfactor++;
		}
		else if(direct == 1)
		{
			dutyfactor--;
		}
	}
	else Tcount++;
	if(dutyfactor <= 0)
	{
		direct=0;
	}
	else if(dutyfactor >= 100)
	{
		direct=1;
	}
	if(Tcount < dutyfactor)
	{
		LED=0;
	}
	else
	{
		LED=1;
	}
}
void main()
{
	GpioInit();
	TimeInit();
	EAL=1;//总中断控制
	LED=0;
	while(1);
}

void Timer0_ISR(void) interrupt ISRTimer0
{
	TH0=0xff;
	TL0=0xce;
	ledbreath();
}

或者这个也还不错,不过没有用定时器

#include<SN8F5702.H>
/*
SN8F5702芯片只有P0.0-P0.7,P1.0-P1.7,P2.0-P2.1引脚
*/

#define uint unsigned int
#define uchar unsigned char
#define ulong unsigned long

sbit LEDR=P0^5;

#define PWM_CYCLE 255//周期

uint a,k;

void delay(uchar j)
{
	for(a=j;a>0;a--)
	for(k=0;k<20;k++);
}

void GpioInit()
{
	//用户在用C语言编写的时候,必须按照这个顺序编写设置系统时钟
	CKCON  = 0x70;
	CLKSEL = 0x05;
	CLKCMD = 0x69;
  CKCON = 0x00;
	//芯片IO口的设置,P0,P1,P2
	//其中P1口有唤醒使能P1W
	P0=0x20;//输出高低电平控制,POM相应位使能
	P0M=0x20;//定义输入0输出1。
	P0UR=0x00;//内置上拉电阻控制,禁止0使能1,IO口为输出模式是建议禁止
	
	P1=0x00;
	P1M=0x00;
	P1UR=0x00;
	P1W=0x00;//唤醒禁用0,使能1
	
	P2=0x00;
	P2M=0x00;
	P2UR=0x00;
	
}

void pwmduty(uint duty)
{
	LEDR=1;
	delay(duty);
	LEDR=0;
	delay(PWM_CYCLE-duty);
}
uint duty_cycle=0;
void main()
{
	GpioInit();
	//LEDR=0,LEDG=0,LEDB=0;
	
	while(1)
	{
		WDTR = 0x5A; 
		for(duty_cycle=0;duty_cycle<PWM_CYCLE;duty_cycle++)
		{
			pwmduty(duty_cycle);
		}
		for(duty_cycle=PWM_CYCLE;duty_cycle>0;duty_cycle--)
		{
			pwmduty(duty_cycle);
		}
	}
}

下次介绍ADC得采样与相关计算

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值