新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > 6410中的PWM 定時器

        6410中的PWM 定時器

        作者: 時間:2016-11-10 來源:網絡 收藏
        看了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.定時器的電路結夠圖: 


        1. 定時器架構流程。
          • à經過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< for(j=0;j<1000;j++)


        uDelay(1000);
        }
        }


        }
        void Main(void)
        {
        GPIO_Init();
        LedTest();
        }




        備注: 這里只是使用了定時器來精確定時,并沒用用定時中斷服務。


        關鍵詞: 6410PWM定時

        評論


        技術專區

        關閉
        主站蜘蛛池模板: 武冈市| 日土县| 博乐市| 信丰县| 濉溪县| 哈尔滨市| 南雄市| 深州市| 松滋市| 酒泉市| 通化县| 睢宁县| 青川县| 石阡县| 永川市| 南宁市| 苍梧县| 巫山县| 阳新县| 清流县| 黑龙江省| 威宁| 秭归县| 苗栗市| 安宁市| 来安县| 甘肃省| 大丰市| 萨迦县| 太仆寺旗| 伊宁县| 新余市| 临潭县| 大连市| 桐柏县| 米林县| 定边县| 禄劝| 宝清县| 抚州市| 浮梁县|