天嵌 ARM开发社区

 找回密码
 注册
查看: 1790|回复: 0

TQ210裸机编程(8)——PWM

[复制链接]
freewing 发表于 2014-6-8 01:04:07 | 显示全部楼层 |阅读模式
事实上,要使TQ210板子上的蜂鸣器发声是非常容易的,因为天嵌给TQ210的蜂鸣器为有源蜂鸣器,只要给蜂鸣器供电,蜂鸣器就会发出固定频率的声音。

TQ210板子上的蜂鸣器接在TOUT1引脚,只要给它高电平,蜂鸣器就会发声。

如下代码:





[cpp] view plaincopy
01./* 配置GPD0[1]为输出 */  
02.    GPD0CON &= ~(0xF << 4);  
03.    GPD0CON |= 1 << 4;  
04.    /* GPD0[1]输出高电平即可使蜂鸣器发声 */  
05.    GPD0DAT |= 1 << 1;  

S5PV210包含5个32位的脉宽调制定时器。这些定时器都可产生中断。每个定时器可选择输入时钟为PCLK或SCLK_PWM。




定时器的操作比较简单,下面列出操作步骤:

1、设置TCFG0寄存器:配置定时器的一级分频值

1、设置TCFG1寄存器:配置定时器的二级分频值

3、设置TCNTBn寄存器:递减计数器缓冲寄存器

3、设置TCMPBn寄存器:比较缓冲寄存器

4、设置TCON寄存器:

(1)手动更新on(执行后,CPU会把TCNTBn的值加载到递减计数器中)

(2)手动更新off、自动重载、启动定时器

当递减计数器的值减到和TCMPBn的值相等时,则翻转输出引脚极性;

当递减计数器的值减到0时,如果使能了定时器中断则产生中断,如果使能了自动重载则重载TCNTBn的值到递减计数器,开始重新计数




频率计算:

我之前的时钟配置为PCLK_PSYS=66MHz,这里就由它为定时器提供时钟源。

Timer Input Clock Frequency = PCLK / ( {prescaler value + 1} ) / {divider value}


我的配置为:prescaler value = 65

                      divider value = 8


Timer Input Clock Frequency = 66MHz / (65 + 1) / 8 = 125000
假设输出频率为n,则
TCNTB1 = 1125000 / n

比如输出1Hz,占空比为50%



TCNTB1 = 125000 / 1;
TCMPB1 = TCNTB1 / 2;




具体代码如下:

start.S





[cpp] view plaincopy
01..global _start                  /* 声明一个全局的标号 */  
02._start:  
03.  
04.    bl clock_init  
05.  
06.    bl main                     /* 跳转到C函数去执行 */  
07.  
08.halt:  
09.    b halt  

clock.c





[cpp] view plaincopy
01.#define APLLCON0        *((volatile unsigned int *)0xE0100100)  
02.#define MPLLCON         *((volatile unsigned int *)0xE0100108)  
03.#define EPLLCON0        *((volatile unsigned int *)0xE0100110)  
04.#define VPLLCON         *((volatile unsigned int *)0xE0100120)  
05.#define CLK_SRC0        *((volatile unsigned int *)0xE0100200)  
06.#define CLK_DIV0        *((volatile unsigned int *)0xE0100300)  
07.#define CLK_DIV1        *((volatile unsigned int *)0xE0100304)  
08.#define CLK_DIV2        *((volatile unsigned int *)0xE0100308)  
09.#define CLK_DIV3        *((volatile unsigned int *)0xE010030C)  
10.  
11.void clock_init()  
12.{  
13.    /* 1、设置PLL_LOCK寄存器(这里使用默认值) */  
14.    /* 2、设置PLL_CON寄存器(使用芯片手册推荐的值) */  
15.    APLLCON0    = (1 << 0) | (3 << 8) | (125 << 16) | (1 << 31);    /* FOUTAPLL = 1000MHz */  
16.    MPLLCON     = (1 << 0) | (12 << 8) | (667 << 16) | (1 << 31);   /* FOUTMPLL = 667MHz */  
17.    EPLLCON0    = (1 << 0) | (12 << 8) | (667 << 16) | (1 << 31);   /* FOUTEPLL = 96MHz */  
18.    VPLLCON     = (3 << 0) | (6 << 8) | (108 << 16) | (1 << 31);    /* FOUTVPLL = 54MHz */  
19.      
20.    /* 3、选择PLL为时钟输出 */  
21.    /* MOUT_MSYS = SCLKAPLL = 1000MHz
22.    ** MOUT_DSYS = SCLKMPLL = 667MHz
23.    ** MOUT_PSYS = SCLKMPLL = 667MHz
24.    */  
25.    CLK_SRC0 = (1 << 0) | (1 << 4) | (1 << 8) | (1 << 12);  
26.      
27.    /* 4、设置系统时钟分频值 */  
28.    /* freq(ARMCLK) = MOUT_MSYS / (APLL_RATIO + 1) = 1000MHz / (0 + 1) = 1000MHz
29.    ** freq(HCLK_MSYS) = ARMCLK / (HCLK_MSYS_RATIO + 1) = 1000MHz / (4 + 1) = 200MHz
30.    ** freq(PCLK_MSYS) = HCLK_MSYS / (PCLK_MSYS_RATIO + 1) = 200MHz / (1 + 1) = 100MHz
31.    ** freq(HCLK_DSYS) = MOUT_DSYS / (HCLK_DSYS_RATIO + 1) = 667 / (3 + 1) = 166MHz
32.    ** freq(PCLK_DSYS) = HCLK_DSYS / (PCLK_DSYS_RATIO + 1) = 166 / (1 + 1) = 83MHz
33.    ** freq(HCLK_PSYS) = MOUT_PSYS / (HCLK_PSYS_RATIO + 1) = 667 / (4 + 1) = 133MHz
34.    ** freq(PCLK_PSYS) = HCLK_PSYS / (PCLK_PSYS_RATIO + 1) = 133 / (1 + 1) = 66MHz
35.    */  
36.    CLK_DIV0 = (0 << 0) | (4 << 8) | (1 << 12) | (3 << 16) | (1 << 20) | (4 << 24) | (1 << 28);  
37.}  


main.c





[cpp] view plaincopy
01.#define GPD0CON             *((volatile unsigned int *)0xE02000A0)  
02.#define GPD0DAT             *((volatile unsigned int *)0xE02000A4)  
03.  
04.#define TCFG0               *((volatile unsigned int *)0xE2500000)  
05.#define TCFG1               *((volatile unsigned int *)0xE2500004)  
06.#define TCON                *((volatile unsigned int *)0xE2500008)  
07.#define TCNTB1              *((volatile unsigned int *)0xE2500018)  
08.#define TCMPB1              *((volatile unsigned int *)0xE250001C)  
09.#define TCNTO1              *((volatile unsigned int *)0xE2500020)  
10.  
11.int main()  
12.{  
13.#if 0  
14.    /* 配置GPD0[1]为输出 */  
15.    GPD0CON &= ~(0xF << 4);  
16.    GPD0CON |= 1 << 4;  
17.    /* GPD0[1]输出高电平即可使蜂鸣器发声 */  
18.    GPD0DAT |= 1 << 1;  
19.#endif  
20.    /* 配置GPD0[1]为定时器1输出:TOUT1 */  
21.    GPD0CON &= ~(0xF << 4);  
22.    GPD0CON |= 2 << 4;  
23.  
24.    /*
25.    ** 配置定时器输入频率
26.    ** Timer Input Clock Frequency = PCLK / ( {prescaler value + 1} ) / {divider value}  
27.    ** = 66MHz / (65 + 1) / 8 = 125000
28.    ** 假设输出频率为n,则
29.    ** TCNTB1 = 1125000 / n
30.    */  
31.    TCFG0 = 65;  
32.    TCFG1 = 3 << 4;  
33.  
34.    /* 产生1Hz,占空比为50%的输出频率 */  
35.    TCNTB1 = 125000 / 1;  
36.    TCMPB1 = TCNTB1 / 2;  
37.  
38.    TCON = (1 << 9);  /* 手动更新on */  
39.    TCON = (1 << 8) | (1 << 11);    /* 启动定时器/手动更新off/自动重载 */  
40.  
41.    while (1);  
42.      
43.    return 0;  
44.}  




Makefile






[cpp] view plaincopy
01.beeper.bin: start.o clock.o main.o  
02.    arm-linux-ld -Ttext 0xD0020010 -o key.elf $^  
03.    arm-linux-objcopy -O binary key.elf $@  
04.    arm-linux-objdump -D key.elf > key.dis  
05.      
06.%.o : %.c  
07.    arm-linux-gcc -c $< -o $@  
08.%.o : %.S  
09.    arm-linux-gcc -c $< -o $@  
10.      
11.clean:  
12.    rm *.o *.elf *.bin *.dis  

烧写过程见《TQ210裸机编程(5)——系统时钟配置》

转载请注明来源:http://blog.csdn.net/zjhsucceed_329/
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

i.MX8系列ARM cortex A53 M4 工控板上一条 /1 下一条

Archiver|手机版|小黑屋|天嵌 嵌入式开发社区 ( 粤ICP备11094220号 )

GMT+8, 2024-4-24 19:37 , Processed in 1.078125 second(s), 18 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表