系统时钟和定时器——PWM定时器
S3C2440 CPU核的工作电压为1.2V时,主频可以达到300MHz;工作电压为1.3V时,主频可以达到400MHz。开发板为12MHz,需要通过时钟控制逻辑的PLL提高系统时钟。
本文引用地址:https://www.eepw.com.cn/article/201611/316624.htmS3C2440有两个PLL:MPLL和UPLL。UPLL专用于USB设备,MPLL用于设置FCLK、HCLK、PCLK。


其中 m=MDIV+8, p=PDIV+2, s=SDIV
CLKDIVN寄存器:用于设置FCLK、HCLK、PCLK 三者比例。各种时钟比例对应的寄存器设置如下图所示:




程序分析如下:(这程序是赵春江老师的程序)
#include "2440addr.h"
#define U32 unsigned int
typedef unsigned char BOOL;
#define TRUE 1
#define FALSE 0
BOOL stop;
static void __irq Key3_ISR(void) /*暂停键,关闭蜂鸣器*/
{
rSRCPND = rSRCPND | (0x1<<2); /*定义EINT2*/
rINTPND = rINTPND | (0x1<<2);
rTCON &= ~0x8; /*禁止定时器自动重载,即关闭定时器0111*/
stop = TRUE;
}
void __irq Key2_ISR(void) /*重启键,开启蜂鸣器*/
{
rSRCPND = rSRCPND | 0x1; /*定义EINT0*/
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 0001 0101 0101 0101 0101 0110*/
rGPBUP = 0x7ff; /*0111 1111 1111关闭上拉使能*/
rGPFCON = 0xaaaa; /*F口为EINT,给按钮 1010 1010 1010 1010*/
/*按钮的一些必要配置*/
rSRCPND = 0x0f; /*中断设置*/
rINTMSK = ~0x0f;
rINTPND =0x0f;
rEXTINT0 = 0x2222; /*EINT0/EINT1均设置为下降沿触发*/
freq = 2500;
rTCFG0 &= 0xFFFF00;
rTCFG0 |= 0x31; /*prescal 是49 3*16+1=49 timer0 and timer1*/
rTCFG1 &= ~0xF; /*低四位清零 divider value=1/2,因为PCLK为50MHz,所以50MHz/50/2=500kHz/
rTCNTB0 = 5000; /*定时器计数初始值*/
rTCMPB0 = freq; /*定时器比较值*/
rTCON &= ~0x1F;
rTCON |= 0xf; /*死区无效,自动装载,电平反转,手动更新,定时器开启*/
rTCON &= ~0x2 ; /*手动更新位清零,PWM开始工作*/
pISR_EINT0 = (U32)Key2_ISR;
pISR_EINT2 = (U32)Key3_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随着频率的高低,时灭时亮。灯亮的数目4-3-2-1*/
if(freq == 100)
rGPBDAT = ~0x560; /*0001 1110 0000 取反之后1110 0001 1111*/
if(freq == 1300)
rGPBDAT = ~0x160; /*1110 0000取反之后 0001 1111*/
if(freq == 2500)
rGPBDAT = ~0x60; /*0110 0000取反之后 1001 1111*/
if(freq == 3700)
rGPBDAT = ~0x20; /*0010 0000取反之后 1101 1111*/
if(freq == 4900)
rGPBDAT = ~0x0; /*0000取反之后 1111111111*/
}
/*频率递减*/
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 = ~0x560;
if(freq == 1300)
rGPBDAT = ~0x160;
if(freq == 2500)
rGPBDAT = ~0x60;
if(freq == 3700)
rGPBDAT = ~0x20;
if(freq == 4900)
rGPBDAT = ~0x0;
}
}
}
TOUT输出的波形是:

评论