1. 硬件原理
2440有5个16位定时器,其中0、1、2、3有PWM功能,有一根输出引脚,可以产生周期性高低电平变化。定时器4没有输出引脚。
2. 芯片手册
3. mini2440电路图
4. S3C2440寄存器
定时器时钟源是PCLK,先通过2个预分频器TCFG0 TCFG1降低频率,降频后就确定了定时器工作频率。初始设定值TCMPBn(用于比较反转输出电平)、TCNTBn。TCON控制定时器启动。TCMPBn的值装入TCMPn,TCNTBn的值装入TCNTn,每个定时器周期,TCNTn减1,可以通过TCNTOn读取计数值。当和TCMPn相等时,反转电平输出。减到0时,再次反转,如果TCON设置自动加载,则重复如上步骤。
pwm.h
/*******************************************************************
* Copyright (C),2011-2012, XXX.
* FileName: pwm.h
* Author:HuangYinqing
* Version:1.0
* Date::2012-04-22
* Description:脉宽调制蜂鸣器驱动.
* Function List:
* History:
******************************************************************/
#ifndef __PWM_H__
#define __PWM_H__
#define PRESCALER0 24
#define MUX0 0x2
#define PWM_CLK ( 50000000 / (PRESCALER0+1) / ( 2 << (MUX0+1) ) )
/*函数声明*/
void PWMInit(unsigned long ulFreq);
void PWMTest(void);
#endif
pwm.c
/*******************************************************************
* Copyright (C),2011-2012, XXX.
* FileName: pwm.c
* Author:HuangYinqing
* Version:1.0
* Date::2012-04-22
* Description:脉宽调制蜂鸣器驱动.
* Function List:
* History:
******************************************************************/
#include "common.h"
#include "core.h"
#include "drv.h"
/********************************************************************
函数功能:PWM初始化。
入口参数:无。
返 回:无。
备 注:定时器频率=PCLK/(预分频+1)/分频值;
预分频24,分频8,定时器频率250kHz
********************************************************************/
void PWMInit(unsigned long ulFreq)
{
rGPBCON &= ~(0x3<<0);
rGPBCON |= 0x2<<0;
rTCFG0 &= ~(0xff<<0);
rTCFG0 |= PRESCALER0<<0; //预分频24
rTCFG1 &= ~(0xf<<0);
rTCFG1 |= MUX0<<0; //分频8
rTCNTB0 = PWM_CLK/ulFreq; //周期
rTCMPB0 = rTCNTB0>>1; //占空比50%
rTCON &= ~0x1f;
rTCON |= (1<<0)|(1<<1)|(1<<3); //自动重载,手动加载,使能定时器
rTCON &= ~(1<<1); //清除手动加载
}
/********************************************************************
函数功能:停止蜂鸣器。
入口参数:无。
返 回:无。
备 注:无。
********************************************************************/
void BuzzerStop( void )
{
rGPBCON &= ~3;
rGPBCON |= 1; //==设置输出
rGPBDAT &= ~1;
}
/********************************************************************
函数功能:设置蜂鸣器频率。
入口参数:
ulFreq:蜂鸣器频率。
返 回:无。
备 注:无。
********************************************************************/
void PWMSetFreq(unsigned long ulFreq)
{
rTCNTB0 = PWM_CLK/ulFreq;
rTCMPB0 = rTCNTB0>>1;
}
/********************************************************************
函数功能:PWM测试函数。
入口参数:无。
返 回:无。
备 注:无。
********************************************************************/
void PWMTest(void)
{
char ucKey;
unsigned long ulFreq;
while(1)
{
ucKey = Uart0GetChar();
if(ucKey == '+')
{
if(ulFreq < 2000)
{
ulFreq += 10;
PWMSetFreq(ulFreq);
}
}
if(ucKey == '-')
{
if(ulFreq > 11)
{
ulFreq -= 10;
PWMSetFreq(ulFreq);
}
}
if(ucKey == ESC_KEY)
{
BuzzerStop();
return;
}
}
}
time.h
/*******************************************************************
* Copyright (C),2011-2012, XXX.
* FileName: timer.h
* Author:HuangYinqing
* Version:1.0
* Date::2012-04-22
* Description:定时器4驱动.
* Function List:
* History:
******************************************************************/
#ifndef __TIMER_H__
#define __TIMER_H__
#define PRESCALER1 0xf9
#define MUX4 0x2
/*定时器4计数*/
extern volatile unsigned long g_ulTimer4Count;
/*函数声明*/
void Timer4Init(void);
#endif
timer.c
/*******************************************************************
* Copyright (C),2011-2012, XXX.
* FileName: timer.c
* Author:HuangYinqing
* Version:1.0
* Date::2012-04-22
* Description:定时器4驱动.
* Function List:
* History:
******************************************************************/
#include "common.h"
#include "core.h"
#include "timer.h"
/*定时器4计数*/
volatile unsigned long g_ulTimer4Count;
/********************************************************************
函数功能:定时器4中断函数。
入口参数:无。
返 回:无。
备 注:无。
********************************************************************/
static void __irq Timer4Handler(void)
{
ClearPending(BIT_TIMER4);
g_ulTimer4Count++;
}
/********************************************************************
函数功能:定时器4初始化。
入口参数:无。
返 回:无。
备 注:定时器频率=PCLK/(预分频+1)/分频值;
预分频249,分频8,定时器频率25kHz,40us,计数25,定时1ms
********************************************************************/
void Timer4Init(void)
{
rTCFG0 &= ~(0xff<<8);
rTCFG0 |= PRESCALER1<<8; //预分频249
rTCFG1 &= ~(0xf<<16);
rTCFG1 |= MUX4<<16; //分频8
rTCNTB4 = 25; //计数25
rTCON |= (1<<20) | (1<<21) | (1<<22); //自动重载,手动加载,使能定时器
rTCON &= ~(1<<21); //清除手动加载
pISR_TIMER4 = (unsigned int)Timer4Handler;
rINTMOD &= ~BIT_TIMER4;
rINTMSK &= ~BIT_TIMER4;
}