您的位置:首页 > 其它

ARM学习笔记 定时系统

2013-11-12 23:33 204 查看
其实网上的一些ppt讲的也蛮详细的 我整理了下。

S3C2440X定时器的主要特性:

S3C2410有5个16位的定时器: 定时器0-3具有PWM(脉宽调制)功能。定时器4是一个内部定时器,没有输出引脚,供内部使用。定时器0有死区产生器,通常用于大电流设备控制。

有2个8位预分频器和2个4位分频器:定时器0 和定时器1 分享同一个8 位的预分频器和分频器,定时器2、3、4 分享另一个预分频器和分频器,分频器有1/2、1/4、1/8、1/16这4种分频值。定时器从分频器接收自己的时钟信号,时钟分频器从相应的预分频器接收时钟信号。

可编程PWM输出占空比:PWM(脉宽调制):就是只对一方波序列信号的占空比按照要求进行调制,而不改变方波信号的其它参数,即不改变幅度和周期,因此脉宽调制信号的 产生和传输,都是数字式的。

PWM技术的应用:借助于微处理器,使用脉宽调制方法实现模拟信号是一种非常有效的技术,广泛应用在从测量、通信到功率控制与变换的许多领域 中。

具有初值自动重装连续输出模式和单脉冲输出模式:

具有死区生成器:是一小段时间间隔,在这个时间间隔内,禁止两个开关同时处于开启状态。死区是在功率设备控制中常采用的一种技术,防止两个开关同时打开起反作用。S3C2410的timer0具有死区发生器功能,可用于控制大功率设备。

S3C2440X定时器结构图:



(1)时钟控制:系统为每个定时器设置有:预分频器、分频器。

(2)定时器组成(5部分):减法计数器 初值寄存器 比较寄存器 观察寄存器 控制逻辑等部分

S3C2440X工作原理:

定时器工作过程:装入初值、启动计数,计数结束产生中断请求,并且可以重装初值连续计数。

初值自动重装、手动装载和双缓冲:初值自动重装功能: 5个定时器都具有此功能。当计数器中值减到0后,若设置了自动重装功能,则在下一计数周期开始前将初值装入计数器重新计数。

初值手动装载功能:在启动计数前,必须使用手动装载功能将初值装入计数器,而初值自动重装仅是一次计数结束后重新装入初值。

双缓冲功能:如果定时器正在工作,此时写入新的数据到TCNTBn、或者到TCMPBn,该写入的数据不影响本次定时器的操作。当定时器到达0后下一次运行定时器时,新写入的TCNTBn、或者TCMPBn才生效。

PWM输出:寄存器TCMPB的作用:当计数器TCNT中的值减到与TCMPB的值相同时,TOUT的输出值取反。改变TCMPB的值,便改变了输出方波的占空比。

死区产生器:死区的概念:是一小段时间间隔,在这个时间间隔内,禁止两个开关同时处于开启状态。死区是在功率设备控制中常采用的一种技术,防止两个开关同时打开起反作用。S3C2410的timer0具有死区发生器功能,可用于控制大功率设备。

DMA请求模式:S3C2410中定时器的DMA功能:系统中的5个定时器都有DMA请求功能,但是在同一时刻只能设置一个使用DMA功能,通过设置其DMA模式位来实现。

DMA请求过程:定时器可以在任意时间产生DMA请求,并且保持DMA请求信号(nDMA_REQ)为低直到定时器收到ACK信号。当定时器收到ACK信号时,它使请求信号变得无效。

DMA请求与中断的关系:如果一个定时器被配置为DMA模式,该定时器不会产生中断请求了。其他的定时器会正常的产生中断。

计数时钟和输出计算:

1)定时器输入时钟频率f Tclk (即计数时钟频率) :

f Tclk=[f pclk∕(Prescaler+1)] ×分频值

式中:Prescaler,预分频值,0---255;分频值为1/2、1/4、1/8、1/16。

2)PWM输出时钟频率 :

PWM输出时钟频率= f Tclk ∕ TCNTBn

3)PWM输出信号占空比(即高电平持续时间所占信号周期的比例):

PWM输出信号占空比 = TCMPBn∕ TCNTBn

PCLK的频率为50MHz,经过预分频和分频器后,送给定时器的可能计数时钟频率

定时器专用寄存器:(明天博客有)

定时器的使用:



1、定时器初始化方法

写TCFG0,设置计数时钟的预分频值和Timer0死区宽度;

写TCFG1,选择各个定时器的分频值和DMA、中断服务;

对TCNTBn和TCMPBn分别写入计数初值和比较初值;

写TCON,设置计数初值自动重装、手动装载初值、设置反相输出;

再写TCON,清除手动装载初值位、设置正相输出、启动计数。

2、定时器停止运行方法

写TCON,禁止计数初值自动重装。(一般不使用运行控制位停止运行)

定时器操作例子:

1、使能自动装载功能,TCNTBn设为160(50+110),TCMPBn设为110,置为手动更新标志,把TCNTBn,TCMPBn的值装入TCNTn,TCMPn。TOUTn翻转功能关闭,然后把TCNTBn设为80(40+40),TCMPBn设为40,这是为下一次装载设置的。

2、使能定时器开始计时位,清零手动更新位,定时器开始向下计时。

3、当TCNTn的值和TCMPn的值相等时,TOUTn从低变高。

4、当TCNTn等于0时,产生中断,TCNTBn,TCMPBn重新装载进TCNTn,TCMPn,这次的值是80和40,TOUTn从高变低。

5、在定时器中断程序中,TCNTBn和TCMPBn的值设置成80(20+60)和60,这是为下一次装载准备的。

6、当TCNTn的值和TCMPn相等时,TOUTn从低变高。

7、当TCNTn等于0,产生中断,TCNTBn,TCMPBn重新装载进TCNTn,TCMPn,这次的值是80和60.

8、在定时器中断程序中,关闭定时器自动装载和中断功能。

9、当TCNTn的值和TCMPn相等时,TOUTn从低变高。

10、TCNTn等于0,TCNTn不在自动装载,定时器停止计时。

11、不会有中断产生。

经过测试:使用外部时钟输入时输入给定时器的频率信号仅与外部时钟的频率有关,与预分频寄存器的值无关。输出任意频率PWM方波代码如下:



void start_timer2(void)

{

ulong val, tmp, m, n;

val = __raw_readl(S3C2410_TCFG0) & (~S3C2410_TCFG_PRESCALER1_MASK);

val |= (0 << S3C2410_TCFG_PRESCALER1_SHIFT);

__raw_writel(val, S3C2410_TCFG0);

tmp = __raw_readl(S3C2410_TCFG0);

printk("S3C2410_TCFG0=0x%x\n", tmp);

/*设置分频寄存器的值*/

val = __raw_readl(S3C2410_TCFG1) & (~S3C2410_TCFG1_MUX2_MASK);

// val |= S3C2410_TCFG1_MUX2_TCLK1;

val |= S3C2410_TCFG1_MUX2_DIV16;

__raw_writel(val, S3C2410_TCFG1);

tmp = __raw_readl(S3C2410_TCFG1);

printk("S3C2410_TCFG1=0x%x\n", tmp);

/*使能自动重载位*/

tmp = __raw_readl(S3C2410_TCON);

val = __raw_readl(S3C2410_TCON) & (~(0xf << 12));

val |= S3C2410_TCON_T2RELOAD;

__raw_writel(val, S3C2410_TCON);

tmp = __raw_readl(S3C2410_TCON);

printk("S3C2410_TCON22222222222=0x%x\n", tmp);

/*设置TCNTB和TCMPB寄存器*/

// __raw_writel(TIMERCOUNT, S3C2410_TCNTB(2));

// __raw_writel(TIMERCOUNT / 4, S3C2410_TCMPB(2));

__raw_writel(799, S3C2410_TCNTB(2));

__raw_writel(399, S3C2410_TCMPB(2));

m = __raw_readl(S3C2410_TCNTB(2));

n = __raw_readl(S3C2410_TCMPB(2));

printk("S3C2410_TCNTB=0x%x,S3C2410_TCMPB=0x%x\n", m, n);

/*置位手动更新位*/

val = __raw_readl(S3C2410_TCON) & (~(0x3 << 12));

val |= S3C2410_TCON_T2MANUALUPD;

__raw_writel(val, S3C2410_TCON);

tmp = __raw_readl(S3C2410_TCON);

printk("S3C2410_TCON--S3C2410_TCON_T3MANUALUPD=0x%x\n", tmp);

/*设置起始位置位反相位,关闭手动更新位*/

val = __raw_readl(S3C2410_TCON) & (~(0x3 << 12));

val |= (S3C2410_TCON_T2START | S3C2410_TCON_T2INVERT);

// val |= S3C2410_TCON_T2START;

tmp = __raw_writel(val, S3C2410_TCON);

printk("S3C2410_TCON========0x%x\n", tmp);

}

在初始化函数中s3c2410_gpio_cfgpin(S3C2410_GPB2, S3C2410_GPB2_TOUT2);

s3c2410_gpio_pullup(S3C2410_GPB2, 0);

通过设置TCNTB和TCMPB寄存器得到PWM,前者调整频率(pclk经过预分频、分频之后除以(TCNTB+1)即可得到输出频率)。后者调整占空比(当TCNTB的值和TCMPB相等时就会翻转)。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: