实验名称: PWM 控制实验
实验目的: 熟悉ADS使用,熟悉pwm 的相关控制,实现按键改变蜂鸣器频率
实验原理:
GPB0可以设置成TOUT0,使用PWM的控制改变输出频率
实验步骤:
Main.c 代码如下:
#define GPBCON (*(volatile unsigned *)0x56000010)
#define GPBDAT (*(volatile unsigned *)0x56000014)
#define GPBUP (*(volatile unsigned *)0x56000018)
#define GPFCON (*(volatile unsigned *)0x56000050)
#define GPFDAT (*(volatile unsigned *)0x56000054)
#define GPFUP (*(volatile unsigned *)0x56000058)
#define TCFG0 (*(volatile unsigned *)0x51000000)
#define TCFG1 (*(volatile unsigned *)0x51000004)
#define TCON (*(volatile unsigned *)0x51000008)
#define TCNTB0 (*(volatile unsigned *)0x5100000C)
#define TCMPB0 (*(volatile unsigned *)0x51000010)
void timer0_ini(unsigned int temp)
{
GPBCON &=~3; //GPB0设成TOUT0
GPBCON|=2;
TCFG0 &=~0xff;
TCFG0|=15; //prescaler=15+1
TCFG1&=~0x0f;
TCFG1|=2; //mux=1/8
TCNTB0=(100000000)/temp;
TCMPB0=TCNTB0>>1; //50%
/*TCFG0=0x00000018; //precscaler=24
TCFG1=0x0; //divider value 2 输入时钟频率= PCLK/(precscaler+1)/devider
// 25000/(24+1)/2=100
TCNTB0=0x0001; // 输出时钟频率=输入频率/TCNTB0
TCMPB0=0x0002; // 输出占空比=TCMPB0/TCNTB08 */
TCON&=~0x1f; //后5为清零,不影响其他位
TCON|=0xb; //自动装载,不反向,手动更新,开启timer0
TCON&=~2; //清除更新位
}
void key_ini()
{
GPFCON=0xfcc0;//GPF0,1,2,4设为输入,其他RESERVED
GPFUP=0xff;//不上拉
}
void Main()
{ unsigned int temp=100;
key_ini();
timer0_ini(temp);
while(1)
{
if((0x02&GPFDAT)==0)
{
if(temp<1000)
temp+=50;
timer0_ini(temp);
} //GPF1-->K1,低电平 按下
if((0x10&GPFDAT)==0)
{
if(temp>100)
temp-=50;
timer0_ini(temp);
} //GPF4-->K2
}
}
实验心得:
最初本次实验失败,程序运行结果是蜂鸣器以很低的频率响。按键没有效果,调试显示相关的寄存器值都改变,按键值也能读入,temp也可以改变,但是蜂鸣器频率一直不变。后来检查按键时才发现错误,我原来是这么写的:
if((0x02&GPFDAT)==0)
{if(temp<1000) temp+=50;} //GPF1-->K1,低电平 按下
if((0x10&GPFDAT)==0)
{if(temp>100) temp-=50;} //GPF4-->K2
timer0_ini(temp);
本意是只要有按键按下,temp改变,就可以改变频率。但是这是在while内,没有按键时,会不停调用timer0_ini(temp),这样可能影响pwm的频率。