s3c2440的PWM应用

发布者:chang_ri最新更新时间:2016-05-30 来源: eefocus关键字: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、再设置定时器的输出时钟频率,它是以PCLK为基准,再除以用寄存器TCFG0配置的prescaler参数,和用寄存器TCFG1配置的divider参数。

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

4、最后就是对PWM的控制,它是通过寄存器TCON来实现的,一般来说每个定时器主要有4个位要配置(定时器0多一个死区位):启动/终止位,用于启动和终止定时器;手动更新位,用于手动更新TCNTBn和TCMPBn,这里要注意的是在开始定时时,一定要把这位清零,否则是不能开启定时器的;输出反转位,用于改变输出的电平方向,使原先是高电平输出的变为低电平,而低电平的变为高电平;自动重载位,用于TCNTn减为零后重载TCNTBn里的值,当不想计数了,可以使自动重载无效,这样在TCNTn减为零后,不会有新的数加载给它,那么TOUTn输出会始终保持一个电平(输出反转位为0时,是高电平输出;输出反转位为1时,是低电平输出),这样就没有PWM功能了,因此这一位可以用于停止PWM。

PWM有很多用途,在这里我利用开发板的资源,用它来驱动蜂鸣器,并通过改变脉宽来改变蜂鸣器发声的频率。下面的程序就是利用PWM来驱动蜂鸣器,脉宽从低到高,再从高到低,周而复始。我们还利用4个LED来指示频率的高低,最高时LED全亮,最低时LED全灭。并且我们用两个按钮来分别暂停蜂鸣器和重新开启蜂鸣器:
 
#define _ISR_STARTADDRESS 0x33ffff00
 
#define U32 unsigned int
typedef unsigned char BOOL;
#define TRUE       1  
#define FALSE     0
 
#define pISR_EINT0            (*(unsigned *)(_ISR_STARTADDRESS+0x20))
#define pISR_EINT1            (*(unsigned *)(_ISR_STARTADDRESS+0x24))
 
#define rSRCPND     (*(volatile unsigned *)0x4a000000)     //Interrupt request status
#define rINTMSK     (*(volatile unsigned *)0x4a000008)      //Interrupt mask control
#define rINTPND     (*(volatile unsigned *)0x4a000010)      //Interrupt request status
 
#define rGPBCON    (*(volatile unsigned *)0x56000010)      //Port B control
#define rGPBDAT    (*(volatile unsigned *)0x56000014)       //Port B data
#define rGPBUP     (*(volatile unsigned *)0x56000018) //Pull-up control B
 
#define rGPFCON    (*(volatile unsigned *)0x56000050)       //Port F control
 
#define rEXTINT0   (*(volatile unsigned *)0x56000088) //External interrupt control register 0
 
#define rTCFG0  (*(volatile unsigned *)0x51000000)      //Timer  configuration
#define rTCFG1  (*(volatile unsigned *)0x51000004)      //Timer  configuration
#define rTCON   (*(volatile unsigned *)0x51000008)      //Timer control
#define rTCNTB0 (*(volatile unsigned *)0x5100000c)       //Timer count buffer 0
#define rTCMPB0 (*(volatile unsigned *)0x51000010)      //Timer compare buffer 0
 
BOOL stop;
 
static void __irq Key1_ISR(void)         //暂停键,关闭蜂鸣器
{
       rSRCPND = rSRCPND | (0x1<<1);
       rINTPND = rINTPND | (0x1<<1);
      
       rTCON &= ~0x8;          //禁止定时器自动重载,即关闭定时器
       stop = TRUE;
}
 
void __irq Key4_ISR(void)          //重启键,开启蜂鸣器
{
       rSRCPND = rSRCPND | 0x1;
       rINTPND = rINTPND | 0x1;
      
       stop = FALSE;
}
 
 
void delay(int a)
{
       int k;
       for(k=0;k               ;
}
 
void Main(void)
{
       int freq;
      
       rGPBCON = 0x155556;        //B0为TOUT0,B5~B8为输出,给LED
       rGPBUP  = 0x7ff;
       rGPFCON = 0xaaaa;             //F口为EINT,给按钮
       //按钮的一些必要配置
       rSRCPND = 0x07;
       rINTMSK = ~0x07;
       rINTPND =0x07;
       rEXTINT0 = 0x22;
      
       freq = 2500;
      
       rTCFG0 &= 0xFFFF00;
       rTCFG0 |= 0x31;    //prescal 是49
       rTCFG1 &= ~0xF;    //1/2,因为PCLK为50MHz,所以50MHz/50/2=500kHz
       rTCNTB0 = 5000;
       rTCMPB0 = freq;
       rTCON &= ~0x1F;       
       rTCON |= 0xf;              //死区无效,自动装载,电平反转,手动更新,定时器开启
       rTCON &= ~0x2 ;  //手动更新位清零,PWM开始工作
      
       pISR_EINT0 = (U32)Key4_ISR;
       pISR_EINT1 = (U32)Key1_ISR;
 
       stop = FALSE;
      
       rGPBDAT = ~0x60;              //两个LED亮
      
       while(1)
       {
              //频率递增
              for ( ; freq<4950 ; )
              {
                     freq+=10;
                     rTCMPB0 = freq;          //重新赋值
                     delay(20000);
                    
                     while (stop == TRUE)          //暂停
                     {
                            delay(1000);
                            if (stop ==FALSE)        //判断是否重启
                            {
                                   rTCON &= ~0x1F;
                                   rTCON |= 0xf;
                                   rTCON &= ~0x2 ;               //恢复PWM功能
                            }
                     }
                     //4个LED随着频率的高低,时灭时亮
                     if(freq == 100)
                            rGPBDAT = ~0x1e0;
                     if(freq == 1300)
                     rGPBDAT = ~0xe0;
                     if(freq == 2500)
                            rGPBDAT = ~0x60;
                     if(freq == 3700)
                            rGPBDAT = ~0x20;
                     if(freq == 4900)
                            rGPBDAT = ~0x0;
                           
              }
             
              //频率递减
              for( ; freq>50 ; )
              {
                     freq-=10;
                     rTCMPB0 = freq;
                     delay(20000);
                     while (stop == TRUE)
                     {
                            delay(1000);
                            if (stop ==FALSE)
                            {
                                   rTCON &= ~0x1F;
                                   rTCON |= 0xf;
                                   rTCON &= ~0x2 ;
                            }
                     }
                     if(freq == 100)
                            rGPBDAT = ~0x1e0;
                     if(freq == 1300)
                            rGPBDAT = ~0xe0;
                     if(freq == 2500)
                            rGPBDAT = ~0x60;
                     if(freq == 3700)
                            rGPBDAT = ~0x20;
                     if(freq == 4900)
                            rGPBDAT = ~0x0;
              }
       }    
}
 
这里还需要说明几点:

1、开发板上的蜂鸣器是高电平发声,低电平停止,而TOUT0定时无效时,是高电平输出,因此为了使PWM无效时,蜂鸣器不发声,我把输出电平进行了反转处理(置TCON中的输出反转位);

2、在这里,我是通过按键把stop标志变量置为FALSE来跳出while循环,重新开始蜂鸣,但不知什么原因,如果在while循环内不加一段等待时间,则永远不能跳出循环体,因此我不得不加了一个delay函数,让它等待一段时间。关于这个问题,我还给不出一个满意的解释,也不知是哪里出了问题!
关键字:s3c2440  PWM应用 引用地址:s3c2440的PWM应用

上一篇:s3c2440定时器中断的应用
下一篇:s3c2440外部中断操作

推荐阅读最新更新时间:2024-03-16 14:55

GNU ARM汇编--(十)s3c2440的RTC
RTC 概述 在系统电源关掉时RTC可以在备份电池的支持下来工作.RTC可以使用STRB/LDRB指令传输8bit的BCD值到CPU.数据包括秒,分,时,日期,天,月和年.RTC工作在外部32.768KHz的晶振下,而且有报警功能. 属性 BCD:秒,分,时,日期,天,月和年 闰年产生器 报警功能:报警中断 从power-off模式唤醒 独立的电源管脚(RTCVDD) 为RTOS kernel time tick支持毫秒级的tick. 闰年产生器 闰年产生器通过BCDDATA,BCDMON和BCDYEAR来决定每个月最后一天的日期.一个8bit的计数器只能表示两个BCD码,所以无法决定'
[单片机]
PWM控制技术在逆变电路中的应用
1 引言 在电力电子技术发展史上,逆变电路占据非常重要的一环,而PWM控制技术在逆变电路又处于核心地位,如何将PWM控制技术应用到逆变电路当中是摆在广大科技工作者面前一大难题。针对这个问题,本文首先阐述了PWM控制技术的基本原理,然后详细地研究了单极性SPWM和双极性SPWM实现方法,最后将PWM控制技术和单相桥式逆变电路结合起来分析并应用,并通过仿真实验验证了PWM控制技术在逆变电路的成功应用。 2 PWM控制技术的基本原理及实现方法 2.1 PWM控制技术的基本原理介绍 根据信号与系统知识可知,冲量相同而形状不一样的窄脉冲加在惯性环节上时,其输出作用相同。如图1(a)、(b)和(c)所示的三个波形分别为矩形波脉冲、三
[嵌入式]
s3c2440——Nandflash
简介:   Nandflash与计算机的硬盘类似,用于保存系统运行所必须的操作系统、用户数据、运行过程等各类数据。并且在Nandflash中的数据在掉电后仍可永久保存。 一、目标芯片(K9F1208U0M)   1、此芯片为三星公司生产的容量为64MB。(下图为网上图片、非本人原创)。由下图可以看出,1page = 528byte(其中Data feild = 512bytes、spare = 16bytes)。 1 block = 32 pages = 32 * 528byte。其中可以存储数据的是 (32 * 512byte) = 16KB。然而此芯片有4096个block。所以此芯片的容量可以计算得出:(4096 * 3
[单片机]
<font color='red'>s3c2440</font>——Nandflash
S3C2440下linux按键驱动编写及测试程序
驱动程序tang2440_buttons.c #include linux/module.h #include linux/kernel.h #include linux/fs.h #include linux/init.h #include linux/delay.h #include linux/poll.h #include linux/irq.h #include asm/irq.h #include linux/interrupt.h #include asm/uaccess.h #include mach/regs-gpio.h #include mach/hardware.h #include linux/platf
[单片机]
反汇编解析S3C2440汇编点灯
代码 首先回顾代码 /* *点亮LED:GPF4 */ .text //表明它是代码段 .global _start _start: /*配置GPF4为输出引脚 *把0x100写到地址0x56000050上,熄灭led */ ldr r1, =0x56000050 /*将这个地址存放到r1中*/ ldr r0, =0x100 /*或者使用 mov r0, #0x100 将0x100放入r0 */ str r0, /*将r0的值写入到r1的地址中*/ /*设置GPF4输出高电平 *把0x00写到地址0x56000054上,点亮led */ ldr r1, =0x56000054
[单片机]
反汇编解析<font color='red'>S3C2440</font>汇编点灯
基于S3C2440和嵌入式Linux的扩展串口设计
  现场总线等技术的广泛使用,串口通讯在各种场合的应用越来越广泛。在集中控制系统中,需要在多个串口间进行通信,而在一般计算机上,只有1~3个串口,为了实现对多点的控制,需要对串口进行扩展。   ARM芯片是目前在嵌入式系统中应用比较广泛的一种芯片,由于可以运行操作系统,以及拥有包括LCD、串口通讯、网络通讯、存储芯片等大量外围接口芯片的支持,使得ARM广泛应用于检测、通讯、控制等领域。   本文以ARM 920T核的S3C24449芯片作为微控制器,在TQ2440开发板进行串口扩展,利用开发板上的系统总线接口和通用输入输出接口分别与扩展串口相连,达到同时与多台串口设备并行通信的目标。   1 硬件介绍   1.1
[电源管理]
基于<font color='red'>S3C2440</font>和嵌入式Linux的扩展串口设计
S3C2440时钟体系分析
FCLK 时钟用于CPU HCLK时钟用于AHB bus 外设 PCLK 时钟用于 APB bus 外设 S3C2440 有两个锁相环(PLLs), 一个用于FCLK,HCLK,PCLK 另一个专门用于USB 模块 时钟控制逻辑可以在没有PLL的情况下制作慢速时钟,并通过软件将时钟连接/断开与每个外围模块的连接,从而降低了功耗。 通过在片内集成的2个锁相环:MPLL和UPLL,可对输入的Fin=12MHz的晶振频率进行倍频。S3C2440使用了三个倍频因子MDIV、PDIV和SDIV来设置倍频,通过寄存器MPLLCON和UPLLCON可设置倍频因子。其中MPLLCON寄存器用于设置处理器内核时钟主频FCLK,其输入输
[单片机]
<font color='red'>S3C2440</font>时钟体系分析
单端PWM控制器NCP1205及其应用
摘要:NCP1205是安森美公司采用先进技术生产的一种单端脉冲宽度调制控制器。该控制器可保证在任何负载/线路条件下的完全继续传导模式DCM和准谐振QR操作,同时,该器件还组合了一个真正的电流模式控制调制器和一个退磁检测器。文中介绍了NCP1205 PWM控制芯片的基本结构、工作原理和主要特点,给出了它的典型应用电路。 关键词:QR;I/CO;频率软折弯;PWM控制器;NCP1205 1 概述 NCP1205是安森美公司生产的一种先进的单端PWM控制器。其应用领域主要包括:较大功率笔记本电脑用AD/DC适配器、脱机电池充电器和DVD、CD唱机、TVS、机顶盒(STB)等系统的开关电流(SMPS)及USB中的辅助电源等
[电源管理]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved