6410中的PWM 定时器

原创 2013年12月02日 09:10:36
看了OK6410的手册,感觉晕晕的。 需要整理一下思路。

我觉得主要的知道下面这几个内容吧。

1. 定时器的电路结构。

2. 定时器的工作原理是什么。定时器如何来使用。{使用的时序是什么,在时间轴上各个寄存器应该如何配置}

3. 里面涉及的寄存器都有哪些。 各个寄存器的职责是什么。

1. 简单介绍 :

S3C6410X中有5个定时器,这些定时器产生内部中断。其中,Timer0和Timer1具有PWM功能,而Timer2,3,4没有此功能。

PWM具有两种操作模式:自动装载模式,一次触发模式。为实现PWM功能,芯片提供了16个功能寄存器。这些功能寄存器都连接APB总线。

定时器具有双缓冲特性,这样就能在不停止当前定时器操作的情况下,为下次定时器运行装入新的数值。尽管为定时器设置了新数值,但当前的定时操作能够成功完成。定时器从TCNTBn读取的值是为下次延时定时用的,并不影响当前定时器的运行。当TCNTn减小到0的时候,TCNTBn的值会自动复制到TCNTn中,这就是说的自动装载操作。定时器的当前计数值可以从定时计数观察寄存器中TCNTOn读取。如果TCNTn为0且从装载也为0的话则TCNTn不在进行下次操作。

2. 定时器的电路结够图: 

3. 定时器架构流程。

PCLK ---à 经过8位的预分频器【8bit prescaler0】 --à 分频器divider [1/1 1/2 1/4 1/8 1/16] -à 多路选择器 MUX -à 逻辑控制器【比较TCMPBn和TCNTBn的数值】--à (deadzone generator ) --à 时钟

计算公式:

4.  定时器的工作原理是什么。 

 

每个定时器有32位的递减计数器。递减计数器的初始值由TCNTBn来加载。 当计数器的值变为0时, 定时器产生中断信号通知cpu定时器操作完成。 当计数器的值变为0时,TCNTBn的值自动加载到递减计数器并开始下个周期的操作。 如果定时器停止工作(比如,在定时器工作模式期间清空寄存器TCONn的定时器使能位,这样对应的定时器就会停止工作),这时TCNTBn的值就不会加载到定时器。

 

而对于PWM 功能,要用到寄存器TCMPBn,当递减计数器down-counter的值和比较寄存器TCMPBn的值相同时,定时控制逻辑模块就会改变输出电平。因此比较寄存器TCMPBn决定了PWM的输出。

而且TCNTBn 和 TCMPBn寄存器具有双缓冲特性,这样就能在不停止当前定时器操作的情况下,为下次定时器运行装入新的数值。尽管为定时器设置了新数值,但当前的定时操作能够成功完成。

5. 定时器的工作时序

 

 

我说怎么在上面的第一步中突然冒出个TCNTn和TCMPn,我以为是数据手册错了,因为在PWM提供的16个寄存器中没有这两个寄存器。 那么请看下面: 

 

从上面内容看出。TCNTn和TCMPn是内部的寄存器(internal registers ).而TCNTn寄存器的值可以通过读取寄存器TCNTOn来获得。

6. 16个特殊功能寄存器

 

7.接下来看一下飞凌提供的精确控制LED的程序。【利用定时器来精确控制LED跑马灯,每隔1s轮询点亮】

 

#define rGPMCON (*(volatile unsigned*)(0x7F008820))

#define rGPMDAT (*(volatile unsigned*)(0x7F008824))

#define rGPMPUD (*(volatile unsigned*)(0x7F008828))


#define PCLK 66000000 //forS3C6410 66MHZ

#define HCLK 133000000 //forS3C6410 133MHZ


#define rTCFG0 (*(volatile unsigned*)(0x7F006000))

#define rTCFG1 (*(volatile unsigned*)(0x7F006004))


#define rTCON (*(volatile unsigned*)(0x7F006008))

#define rTCNTB0 (*(volatile unsigned*)(0x7F00600C))

#define rTCMPB0 (*(volatile unsigned*)(0x7F006010))


#define rTCNTO0 (*(volatile unsigned*)(0x7F006014))

#define rTCNTB1 (*(volatile unsigned*)(0x7F006018))

#define rTCMPB1 (*(volatile unsigned*)(0x7F00601c))


#define rTCNTO1 (*(volatile unsigned*)(0x7F006020))

#define rTCNTB2 (*(volatile unsigned*)(0x7F006024))

#define rTCNTO2 (*(volatile unsigned*)(0x7F00602c))


#define rTCNTB3 (*(volatile unsigned*)(0x7F006030))

#define rTCNTO3 (*(volatile unsigned*)(0x7F006038))

#define rTCNTB4 (*(volatile unsigned*)(0x7F00603c))


#define rTCNTO4 (*(volatile unsigned*)(0x7F006040))

#define rTINT_CSTAT (*(volatile unsigned*)(0x7F006044))


void uDelay(int usec)

{

unsigned int val=(PCLK)/1000000-1; //val = 65

 

//configure prescaler and divider

rTCFG0&=~(0xff<<8); //0000_0000_1111_1111 TCFG0[15:8-7:0]

rTCFG0|=0<<8; //0000_0000_0000_0000 | 0000_0000_1111_1111 prescalar0 = 255 timer0,timer1 的prescalar value= 255 timer2,3,4的prescalar1 value = 0

 

rTCFG1&=~(0xf<<8); // 0000_1111_1111 TCFG1 [7:0] = 1111_1111 TCFG1[11:8] = 0000(select mux for timer2 . divider value = 1 );

rTCFG1|=0<<8;

 

//compute :

//timer input clock frequency = PCLK /({prescaler value + 1})/{divider value}

// timer2 input clock frequency = 66M /(1)/(1)= 66M hz

 

//configure timer counter buffer and enable timer2

rTCNTB2=val;

 

rTCON&=~(0xf<<12); // 0000_1111_1111_1111

rTCON|=0xb<<12; // 1011_0000_0000_0000 |0000_1111_1111_1111 = 1011_1111_1111_1111

rTCON&=~(2<<12); // 1101_1111_1111_1111 &1011_1111_1111_1111 = 1001_1111_1111_1111

【// TCON(Timer control register)

 

//1001 : 表示 : auto-reload , start timer2】

//TCON[15]=1 auto-reload

//TCON[14] Reserved bits

//TCON[13]=0 no operatin , =1,update TCNTB2 TCMPB2

//TCON[12]=0 stop , =1 ,start timer2

 

 

//rTCON&= 0x9fff; //这样不就可以了吗 ,为什么要花三条语句来写。

while(usec--){

while(rTCNTO2 >= val>>1);

while(rTCNTO2 < val>>1);

};


}


void msDelay(int time)


{

volatile unsigned int i,j;

for(i=0;i<2000000;i++)

for(j=0;j

}


void GPIO_Init(void)


{

rGPMCON =0x11111;

rGPMPUD =0x00;


rGPMDAT =0X1F;

}


void LedTest(void)

{

volatile unsigned int i ,j;


while(1)

{

for(i=0;i<4;i++)


{

rGPMDAT =~(1<<i);

for(j=0;j<1000;j++)


uDelay(1000);

}

}


}

void Main(void)

{

GPIO_Init();

LedTest();

}



备注: 这里只是使用了定时器来精确定时,并没用用定时中断服务。

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

mini6410利用定时器1把GPE2 和GPE4口输出可调PWM

mini6410 定时器中断驱动io口利用GPE2和GPE4口定时器用定时器1-------------------------------------------------------------...
  • gfocean
  • gfocean
  • 2011年03月13日 09:22
  • 2563

OK6410之蜂鸣器驱动软件分析---PWM定时器

#include #include #include #include #include #include #include #include #include #...

S3c6410 linux内核移植(8)---添加pwm驱动,控制lcd背光亮度

一般LCD的背光LED是通过PWM控制,调节PWM的占空比即可调整背光亮度。比如S3C6410的GPF15,即PWM1,可连接LCD的背光控制接口,进行背光控制。内核中pmw配置函数位于”arch/a...
  • heyong_
  • heyong_
  • 2012年03月16日 15:58
  • 1396

S3C6410 PWM驱动(三) --- 源代码

/***********wzk_pwm.c**********/ #include "wzk_pwm.h" //init dev void init_pwm(void) { unsig...

S3C6410 PWM驱动(二) --- 原理分析

1.相关寄存器 (1)TCFG0:时钟预定标器和死区结构。 (2)TCFG1:时钟多路复用器和 DMA 模式的选择。 (3)TCON:定时器控制寄存器。 (4)TCNTB0:定时器 0 计数缓...

idea6410的蜂鸣器驱动(非PWM)

//-------------------------------------------------------------------------------------------- // 作...

OK6410&nbsp;linux系统遇到的BUG总结

经过一段时间使用OK6410 256M RAM 2G nand Flash碰见了不少问题。 所以特意开本贴一起交流。大家有什么BUG解决的可以跟上本帖。求助的请另开贴。勿跟本帖。谢谢。请谅解!!! 希...

S3C6410之PWM介绍

在分析PWM驱动的实现之前,我们需要看看6410的芯片手册中有关PWM章节,知道PWM的产生方式和控制方法,知道相关的一些寄存器才能知道设置那些寄存器,都应该赋什么值,下面就是其中的一部分,主要是芯片...

深入理解ARM体系架构(S3C6410)---PWM实例

深入理解ARM体系架构(S3C6410)---PWM实例 分类: 嵌入式arm篇2012-03-24 12:30 2088人阅读 评论(3) 收藏 举报 本系列文章由muge0...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:6410中的PWM&nbsp;定时器
举报原因:
原因补充:

(最多只允许输入30个字)