GNU ARM汇编-(9)s3c2440的PWM

GNU ARM汇编--(九)s3c2440的PWM

        依旧从datasheet开始看起,锻炼下阅读英文技术手册的能力

PWM TIMER
概述
    s3c2440有5个16bit的定时器.Timer0,1,2和3有PWM功能.Timer4是没有输出管脚的内部定时器.Timer0有一个dead-zone产生器,用于大电流设备.
    Timer0和1共用一个8bit的预分频器,而timer2,3,4共用另外一个8bit的预分频器.每一个定时器都有一个时钟除法器,可以产生5个不同的除法信号(1/2,1/4,1/8,1/16和TCLK).每一个定时器从时钟除法器接收各自的时钟信号,除法器从各自的8bit预分频器接收时钟.8bit的预分频器是可编程控制的,将PCLK除成要加载的值,存在TCFG0和TCFG1中.
    当定时器启用时定时器计数缓冲寄存器(TCNTBn)将初始值加载到down-counter中.定时器比较缓冲寄存器(TCMPBn)将初始值加载到比较寄存器中与donw-counter的值比较.当频率变化时TCNTBn和TCMPBn的双缓冲属性保证定时器产生稳定的输出.
    每个定时器有自己的16bit down-counter,由定时器时钟驱动.当down-counter为0,定时器中断请求产生来通知CPU定时器操作以及完成了.当定时器的计数器为0,相关的TCNTBn的值会自动的加载到down-counter中来继续下一次操作.然而,当定时器停止,比如在定时器运行中清除TCONn的定时器使能位,TCNTBn不会重加载到计数器中.
    TCMPBn的值被用于PWM.当down-counter的值与比较寄存器的值吻合时,定时器控制逻辑会改变输出电平.所以比较寄存器决定PWM输出的打开时间.


属性
    5个16bit的定时器
    两个8bit的预分频器&两个4bit的除法器
    输出波形可编程控制
    自动重加载模式或one-shot pulse mode
    dead-zone产生器


PWM TIMER OPERATION
Prescaler&Divider


BASIC TIMER OPERATION
    一个定时器(除了5)有TCNTBn,TCNTn,TCMPBn和TCMPn.当定时器为0时TCNTBn和TCMPBn加载到TCNTn和TCMPn中.当TCNTn为0,如果中断开启的话就会产生一个中断请求.
    
AUTO RELOAD&DOUBLE BUFFERING
    PWM定时器有一个双缓冲功能,保证下次定时器操作时重加载的值改变时无需停止当前的定时器操作.所以新的定时器的值设定,当前的定时器操作也可以成功完成.
    定时器的值可以写到TCNTBn中,定时器的当前计数值可以从TCNTOn中读到.TCNTBn被读取的值,不表明计数器的当前状态,而是下一次定时器持续期间的重加载值.
    当TCNTn为0,自动重加载操作会复制TCNTBn到TCNTn中.如果TCNTn为0,而自动重加载的使能位为0,那么TCNTn不会再操作了.


TIMER INITIALIZATION USING MANUAL UPDATE BIT AND INVERTER BIT
    当down-counter为0,定时器的自动重加载操作就会动作.所以user要预先定义TCNTn的初始值.在这种情况下,初始值通过手动更新位进行加载.下面的步骤描述如何启动一个定时器:
    1.向TCNTBn和TCMPBn中些初始值
    2.设置定时器的手动更新位.推荐配置inverter on/off bit(不管用不用)
    3.设置定时器的开始位来启动定时器(同时清除手动更新位)
    如果定时器被强行停止,TCNTn保持计数器的值而且不会从TCNTBm中重加载.如果要设置一个新值,要执行手动更新.
    注意:不论何时TOUT inverter on/off bit被更改,在定时器运行时TOUTn的逻辑值都会改变.因此,最好在配置手动更新位的时候配置inverter on/off bit.
    TIMER OPERATION
GNU ARM汇编-(9)s3c2440的PWM
上面的图是下面操作的结果:

1.使能自动重加载功能.设置TCNTBn为160(50+110),TCMPBn为110.设置手动更新位并配置反转位(on/off).手动更新位将TCNTn和TCMPn的值更新到TCNTBn和TCMPBn中.   接下来设置TCNTBn为80(40+40),TCMPBn为40,它们决定下一次重加载的值.

2.设置开始位,手动更新位设为0.关闭反转器,打开自动重加载.在等待时间后定时器开始计数

3.当TCNTn和TCMPn有相同的值时,TOUTn的逻辑电平由低变为高

4.当TCNTn为0时,中断请求产生,TCNTBn的值被加载到一个临时寄存器.在下次定时器周期,TCNTn会重载临时寄存器的值.

5.在中断服务例程中,TCNTBn设为80(20+60),TCMPBn设置为60,同样用于下一次周期.

6.当TCNTn和TCMPn有相同的值时,TOUTn的逻辑电平由低变为高

7.当TCNTn为0,TCNTn自动加载TCNTBn的值,触发中断请求.

8.在中断服务例程中自动重加载和中断请求被禁用,停止定时器

9.当TCNTn与TCMPn有相同值,TOUTn的逻辑电平由低变为高

10.即使TCNT0为0,因为自动重加载被禁用了所以TCNTn不会再重加载,定时器停止了

11.没有中断请求产生了


PULSE WIDTH MODULATION(PWM)
GNU ARM汇编-(9)s3c2440的PWM
    通过使用TCMPBn来实现PWM功能.PWM的频率由TCNTBn来决定.
    减少TCMPBn的值可以有更高的PWM值.增加TCMPBn的值可以有更低的PWM值.如果输出反转使能了,增加和减少操作也要反转.
    双缓冲功能允许在ISR中将下一次PWM的TCMPBn的值在当前PWM的周期的任何一个时间点被写入.


OUTPUT LEVEL CONTROL
GNU ARM汇编-(9)s3c2440的PWM
    假定反转功能时关闭的,下面的步骤描述如何保证TOUT是高还是低:
    1.关闭自动重加载位.TOUTn时高电平,当TCNTn为0时定时器停止.
    2.通过清除定时器的开始位来停止定时器.如果TCNTn<=TCMPn,输出高;如果TCNTn>TCMPn,输出低.
    3.可以通过TCON的反转开关来决定TOUT是否反转.反转器会移除额外的电流来适应输出电平.

PWM的各个寄存器描述

(注:因为TQ2440的板子是用TOUT0来控制蜂鸣器的,所以有些寄存器就不关注了)

定时器配置寄存器0(TCFG0)

定时器输入时钟周期 = PCLK/(prescaler + 1)/(divider value)

{prescaler} = 0~255

{divider value} = 2,4,8,16

Register            Address              R/W                           Description

TCFG0          0x51000000           R/W                       配置两个8的预分频器


TCFG0                               Bit                                           Description

Dead zone length             [23:16]                         死区的长度,长度等于timer0的单位长度

Prescaler1                        [15:8]                           这个是给Timer2 3 4用的

Prescaler0                        [7:0]                             这个是给Timer0 1用的


定时器配置寄存器1(TCFG1)

Register            Address                         R/W                                        Description 

TCFG1           0x51000004                     R/W                               5路MUX和DMA模式选择寄存器


TCFG1                  Bit                                       Description                

DMA mode          [23:20]                           选择DMA请求通道

                                                                  0000=No select  0001=Timer0 0010=Timer1  

                                                                  0011=Timer2 0100=Timer3  0101=Timer4 

MUX4                  [19:16]                           为PWM Timer4选择复用输入

                                                                   0000=1/2 0001=1/4 0000=1/8

                                                                   0011=1/16  01xx=External TCLK1

MUX3                  [15:12]                            为PWM Timer3选择复用输入

                                                                    0000=1/2 0001=1/4 0000=1/8

                                                                    0011=1/16  01xx=External TCLK1

MUX2                  [11:8]                              为PWM Timer2选择复用输入

                                                                    0000=1/2 0001=1/4 0000=1/8

                                                                    0011=1/16  01xx=External TCLK1

MUX1                  [7:4]                               为PWM Timer1选择复用输入

                                                                    0000=1/2 0001=1/4 0010=1/8

                                                                    0011=1/16  01xx=External TCLK1

MUX0                  [3:0]                               为PWM Timer0选择复用输入

                                                                    0000=1/2 0001=1/4 0010=1/8

                                                                    0011=1/16  01xx=External TCLK1


Timer控制寄存器     
Register                  Address              R/W                  Description
TCON                     0x51000008        R/W             定时器控制寄存器

TCON                                        Bit                       Descrption         
Dead zone enable                     [4]                      决定死区的操作 0=disable 1=enable
Timer0 auto reload on/off          [3]                      决定Timer0的自动重载 0=one-shot 1=auto reload
Timer0 output inverter on/off     [2]                      决定Timer0的输出电平反转开关0=关闭 1=打开TOUT0的反转
Timer0手动更新(注意)               [1]                      决定Timer0的手动更新位0=不操作  1=更新TCNTB0&TCMPB0
Timer0开始/停止                        [0]                      决定Timer0的开始/关闭0=停止  1=开启
注意:在下次写之前要被清除

Timer0 COUNT BUFFER REGISTER & COMPARE BUFFER REGISTER(TCNTB0/TCMPB0)
Register                      Address                          R/W                                         Description
TCNTB0                     0x5100000c                    R/W                                         Timer0计数缓冲寄存器
TCMPB0                     0x51000010                   R/W                                          Timer0比较缓冲寄存器

TCMPB0                                                  Bit                                              Description
定时器比较缓冲寄存器                            [15:0]                                   为Timer0设置比较缓冲值
TCNTB0                                                   Bit                                              Description
定时器计数缓冲寄存器                            [15:0]                                    为Timer0设置计数缓冲值

Timer0计数观察寄存器(TCNTO0)
Register                          Address                  R/W                                         Description
TCNTO0                         0x51000014             R                                     Timer0计数观察寄存器

按照datasheet的一些说明和步骤,给出汇编代码:


从代码中有这样的设定:
定时器的输入时钟为@定时器输入时钟周期 = PCLK/(prescaler + 1)/(divider value)
@clk = 100M/(249+1)/8=25k


TCNTB0设为200,而TCMPB0为50,则TOUT0输出占空比为25%的方波,方波的周期为200/clk=8ms

如果有示波器,倒可以验证一下这个结果.如果有对朋友觉得这个方波估计的不对,欢迎指出,谢谢!