6410中的PWM 定时器

转自:http://blog.163.com/brave_smile_heart/blog/static/1872381712012312113726807/

6410中的PWM 定时器  

2012-04-12 11:49:07|  分类: ARM-linux|字号 订阅

6410中的PWM 定时器

看了OK6410的手册,感觉晕晕的。  需要整理一下思路。 

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

1.       定时器的电路结构。 

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

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

 

1.       简单介绍 :

S3C6410X中有5器,些定部中。其中,Timer0和Timer1具有PWM功能,而Timer2,3,4有此功能

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

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

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

6410中的PWM 定时器_第1张图片
 

3.       定时器架构流程。

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

  计算公式:6410中的PWM 定时器 - Melchior - Melchiors Home

 

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

6410中的PWM 定时器 - Melchior - Melchiors Home
 

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

6410中的PWM 定时器 - Melchior - Melchiors Home
 

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

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

5.  定时器的工作时序

6410中的PWM 定时器_第2张图片
 
6410中的PWM 定时器_第3张图片

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

6410中的PWM 定时器 - Melchior - Melchiors Home
 

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

6.       16个特殊功能寄存器

6410中的PWM 定时器_第4张图片

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)

6410中的PWM 定时器 - Melchior - Melchiors Home

//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<time;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(); 



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

你可能感兴趣的:(6410中的PWM 定时器)