s3c2440 的pwm应用

      PWM(Pulse Width Modulation)——脉宽调制,它是利用微控制器的数字输出来对模拟电路进行控制的一种非常有效的技术,广泛应用于测量、通信、功率控制与变换等许多领域。

      s3c2440芯片中一共有5个16位的定时器,其中有4个定时器(定时器0~定时器3)具有脉宽调制功能,因此用s3c2440可以很容易地实现PWM功能。下面就具体介绍如何实现PWM功能。

1、PWM是通过引脚TOUT0~TOUT3输出的,而这4个引脚是与GPB0~GPB3复用的,因此要实现PWM功能首先要把相应的引脚配置成TOUT输出。

2  设置定时器输出频率,这个可以参考前面博文 2440timer 的。

3、然后设置脉冲的具体宽度,它的基本原理是通过寄存器TCNTBn来对寄存器TCNTn(内部寄存器)进行配置计数,TCNTn是递减的,如果减到零,则它又会重新装载TCNTBn里的数,重新开始计数,而寄存器TCMPBn作为比较寄存器与计数值进行比较,当TCNTn等于TCMPBn时,TOUTn输出的电平会翻转,而当TCNTn减为零时,电平会又翻转过来,就这样周而复始(2440的自动重载功能)。因此这一步的关键是设置寄存器TCNTBn和TCMPBn,前者可以确定一个计数周期的时间长度,而后者可以确定方波的占空比。由于s3c2440的定时器具有双缓存,因此可以在定时器运行的状态下,改变这两个寄存器的值,它会在下个周期开始有效(2440的双缓冲)。

4、最后就是对PWM的控制,它是通过寄存器TCON来实现的,一般来说每个定时器主要有4个位要配置(定时器0多一个死区位):

启动/终止位,用于启动和终止定时器;

手动更新位,用于手动更新TCNTBn和TCMPBn,这里要注意的是在开始定时时,一定要把这位清零,否则是不能开启定时器的

输出反转位,用于改变输出的电平方向,使原先是高电平输出的变为低电平,而低电平的变为高电平;

自动重载位,用于TCNTn减为零后重载TCNTBn里的值,当不想计数了,可以使自动重载无效,这样在TCNTn减为零后,不会有新的数加载给它,那么TOUTn输出会始终保持一个电平(输出反转位为0时,是高电平输出;输出反转位为1时,是低电平输出),这样就没有PWM功能了,因此这一位可以用于停止PWM。

上面的4个配置中有3个在前面的timer博文里面提到了,输出反转用来让高低电平转换,而 TCMPBn 则设置在什么地方转换,也就是决定占空比。

      这里用pwm驱动蜂鸣器,由于timer0~3与TOUT0~TOUT3 相互对应,蜂鸣器对应的引脚是tout0,需要用timer0。而在前面一直把timer0作为系统始终使用,所以这里需要

把用timer0挪到timer1。 而timer0用来驱动蜂鸣器。

如果不用pwm 也可以把gpb0配置位输出形式,此时高电平发声,低电平停止。

部分代码如下:

	rGPBCON = (rGPBCON & ~0x3) | 0x2;

	pwm_freq = 3906;

	///Timer0 work freq 781250
	rTCNTB0 = 7812;
	rTCMPB0 = pwm_freq;

	rTCON &= ~0x1F;       
	rTCON |= 0xf;              	//死区无效,自动装载,电平反转,手动更新,定时器开启
	rTCON &= ~0x2 ;  		//手动更新位清零,PWM开始工作

	while (1)
	{
		for ( ; pwm_freq <7800; )
		{

			pwm_freq +=10;
			rTCMPB0 = pwm_freq ;          //重新赋值
			OSTimeDly(OS_TICKS_PER_SEC/4);
		}
		for( ; pwm_freq >50 ; )
		{
			pwm_freq -= 10;
			rTCMPB0 = pwm_freq;
			OSTimeDly(OS_TICKS_PER_SEC/4);
		}
		printf("Task0\r\n");
	}

具体代码可以从github上clone。


参考链接:

赵老师博文 大部分从这里抄过来的

blog.csdn.net/zhaocj/article/details/5312359

s3c2440文档。





你可能感兴趣的:(s3c2440 的pwm应用)