<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          NEC V850 之 定時(shí)器TMM0

          作者: 時(shí)間:2016-12-03 來(lái)源:網(wǎng)絡(luò) 收藏
          時(shí)鐘的事情搞定了,下面就是和時(shí)間有關(guān)系的定時(shí)器了。看了下有3個(gè)定時(shí)器分別是AA,AB,M。其中M是最簡(jiǎn)單的一個(gè),只有一個(gè)功能就是計(jì)數(shù)。感覺(jué)和STM32的systick有異曲同工之妙。就是為操作系統(tǒng)留的心跳時(shí)鐘啊。所以先搞他吧。

          先說(shuō)說(shuō)這個(gè)TMM的時(shí)鐘特性吧,有一個(gè)16位的比較寄存器(TM0CMP0),最大計(jì)數(shù)范圍就是0~65535了。另外定時(shí)器TMM0不支持自動(dòng)重裝初值,所以在中斷服務(wù)函數(shù)里除了要清標(biāo)志位還要重新裝入初值。然后這個(gè)定時(shí)器機(jī)器簡(jiǎn)單只有一個(gè)可屏蔽中斷就是溢出中斷。

          本文引用地址:http://www.ex-cimer.com/article/201612/325100.htm

          下面說(shuō)下他的計(jì)數(shù)時(shí)間的計(jì)算方法。關(guān)于系統(tǒng)時(shí)鐘和內(nèi)部設(shè)備時(shí)鐘在上一篇博文里說(shuō)過(guò)了,系統(tǒng)時(shí)鐘如果是32MHz,那么內(nèi)部設(shè)備時(shí)鐘也是32MHz,如果想分頻只有在具體的外設(shè)分頻器處分頻。

          系統(tǒng)時(shí)鐘是32MHz;

          TMM0分頻系數(shù)為不分頻,則TMM0的時(shí)鐘是32MHz;

          一個(gè)時(shí)鐘定時(shí)器記一次數(shù),則記一次數(shù)的時(shí)間是1 / 32MHz = 0.03125 us;

          假如我現(xiàn)在需要定時(shí)1ms就是1000us,需要的計(jì)數(shù)次數(shù)就是 1000us / 0.03125us = 32000 次。

          所以應(yīng)該給比較寄存器(TM0CMP0)賦值(32000 - 1)次,因?yàn)樵诙〞r(shí)器計(jì)時(shí)開(kāi)始時(shí)需要消耗3~4個(gè)時(shí)鐘周期,所以我們不減去1,直接給比較寄存器賦值32000次,做為誤差補(bǔ)償,但是隨著計(jì)時(shí)時(shí)長(zhǎng)的增加,誤差會(huì)在一定程度上積累。大家要根據(jù)具體需要來(lái)進(jìn)行設(shè)置校準(zhǔn)。

          現(xiàn)在我們知道在系統(tǒng)時(shí)鐘為32MHz時(shí),TMM0不分頻的最大計(jì)時(shí)為65536 * 0.03125 = 2.048 ms,如果我們需要定時(shí)的時(shí)長(zhǎng)比較長(zhǎng),就需要對(duì)TMM0的時(shí)鐘進(jìn)行分頻,如果我們需要的定時(shí)時(shí)長(zhǎng)為1s,

          系統(tǒng)時(shí)鐘是32MHz;

          TMM0分頻系數(shù)設(shè)置為512分頻,則TMM0的時(shí)鐘是 32000000Hz / 512 = 62500Hz;

          定時(shí)器記一次數(shù)的時(shí)間就是 1 / 62500Hz = 0.000016s = 16 us;

          我們需要的定時(shí)時(shí)長(zhǎng)是1s,需要的計(jì)數(shù)次數(shù)為 1s = 1000000us / 16us = 62500 次。

          定時(shí)器的定時(shí)范圍是有最大值的,同時(shí)要注意的是,他也是有最小值的,這就是他的I/O口翻轉(zhuǎn)速率,經(jīng)過(guò)測(cè)試,70f3630這款MCU在定時(shí)器TMM0下,最小計(jì)數(shù)單元為5us,如果再低就意味著I/O口的翻轉(zhuǎn)速率更高,則會(huì)得到比較大的誤差值,下面有一個(gè)對(duì)照表來(lái)列舉一組測(cè)試說(shuō)明,并會(huì)附圖。

          計(jì)算定時(shí)時(shí)長(zhǎng)比較寄存器(TM0CMP0)值實(shí)際測(cè)量時(shí)長(zhǎng)備注
          1us32 (TMM0 = fxx)2.0625us附圖1
          5us160 (TMM0 = fxx)5.063us附圖2
          10us320 (TMM0 = fxx)10.031us
          30us960 (TMM0 = fxx)30.001us
          50us1600 (TMM0 = fxx)50.06us
          1ms32000(TMM0 = fxx)1.000ms附圖3
          1s62500(TMM0 = fxx/512)999.9ms
          上面這個(gè)表說(shuō)明了,在定時(shí)時(shí)長(zhǎng)很小的時(shí)候誤差很大,在定時(shí)時(shí)長(zhǎng)很大的時(shí)候,雖然相對(duì)誤差小,但是也有比較大的絕對(duì)誤差,所以這其中的數(shù)值補(bǔ)償要根據(jù)實(shí)際情況具體問(wèn)題具體分析。下面來(lái)看下附圖:


          說(shuō)完了理論,來(lái)說(shuō)說(shuō)代碼部分。操作TMM0需要用到3個(gè)寄存器分別是
          • 可屏蔽中斷控制寄存器(定時(shí)器M ) TM0EQIC0
          • TMM0 比較寄存器0 TM0CMP0
          • TMM0 控制寄存器0 TM0CTL0

          程序操作上有3部分,分別是 開(kāi)始定時(shí)器 , 關(guān)閉定時(shí)器 , 定時(shí)器初始化。

          • 開(kāi)始定時(shí)器(TMM0_Start)
            1. 清TMM0中斷標(biāo)志位,設(shè)置寄存器 TM0EQIC0 的第7位 TM0EQIF0 為 0 ;
            2. 允許響應(yīng)TMM0中斷,設(shè)置寄存器 TM0EQIC0 的第6位 TM0EQMK0 為 0;
            3. 開(kāi)定時(shí)器使能端,設(shè)置寄存器TM0CTL0 的第7位 TM0CE 為 1 。
          • 關(guān)閉定時(shí)器(TMM0_Stop)
            1. 關(guān)定時(shí)器使能端,設(shè)置寄存器TM0CTL0 的第7位 TM0CE 為 0;
            2. 禁止響應(yīng)TMM0中斷,設(shè)置寄存器 TM0EQIC0 的第6位 TM0EQMK0 為 1;
            3. 清TMM0中斷標(biāo)志位,設(shè)置寄存器 TM0EQIC0 的第7位 TM0EQIF0 為 0 。
          • 定時(shí)器初始化(TMM0_Init)
            1. 關(guān)閉定時(shí)器,執(zhí)行TMM0_Stop;
            2. 設(shè)置中斷優(yōu)先級(jí),設(shè)置寄存器 TM0EQIC0 的后3位 ,確定TMM0的中斷優(yōu)先級(jí);
            3. 設(shè)置定時(shí)器分頻系數(shù),設(shè)置寄存器 TM0CTL0 的后3位,確定TMM0的運(yùn)行時(shí)鐘;
            4. 設(shè)置比較寄存器初值,設(shè)置寄存器 TM0CMP0的值,確定觸發(fā)溢出中斷的計(jì)數(shù)次數(shù)。

          有了上面的準(zhǔn)備,下面我們?cè)趍ain函數(shù)里先初始化定時(shí)器然后再調(diào)用開(kāi)始定時(shí)器,一定不要忘記開(kāi)總中斷;然后在中斷服務(wù)程序里寫(xiě)入用戶(hù)代碼加上重新賦初值和清標(biāo)志位的操作就可以了,這樣定時(shí)器就能夠正常工作了,下面是部分代碼,請(qǐng)參閱:

          代碼出處:timer.c

          /*******************************************************************************
          * Function Name : TMM0_Start
          * Description : 開(kāi)始TMMO計(jì)數(shù)
          * Input : None
          * Output : None
          * Return : None
          *******************************************************************************/
          void TMM0_Start( void )
          {
          TM0EQIF0 = 0; // 設(shè)置TM0EQIC0 的第7位中斷標(biāo)志位位 0 ,清除定時(shí)器M0的中斷響應(yīng)標(biāo)志
          TM0EQMK0 = 0; // 設(shè)置TM0EQIC0 的第6位中斷屏蔽位為 0 ,允許產(chǎn)生定時(shí)器M0中斷
          TM0CE = 1; // 設(shè)置TM0CTL0 的最高位TM0CE為 1 ,定時(shí)器計(jì)數(shù)啟動(dòng)
          }

          /*******************************************************************************
          * Function Name : TMM0_Stop
          * Description : 停止TMM0計(jì)數(shù)
          * Input : None
          * Output : None
          * Return : None
          *******************************************************************************/
          void TMM0_Stop( void )
          {
          TM0CE = 0; // 設(shè)置TM0CTL0 的最高位TM0CE為 0 ,禁止定時(shí)器時(shí)鐘啟動(dòng)
          TM0EQMK0 = 1; // 設(shè)置TM0EQIC0 的第6位中斷屏蔽位為 1 ,禁止產(chǎn)生定時(shí)器M0中斷
          TM0EQIF0 = 0; // 設(shè)置TM0EQIC0 的第7位中斷標(biāo)志位位 0 ,清除定時(shí)器M0的中斷響應(yīng)標(biāo)志
          }

          /*******************************************************************************
          * Function Name : TMM0_Init
          * Description : TMM0初始化
          * Input : None
          * Output : None
          * Return : None
          *******************************************************************************/
          void TMM0_Init( void )
          {
          TMM0_Stop(); // 首先禁止定時(shí)器

          TM0EQIC0 |= 0x07; // 設(shè)置TM0EQIC0 的低3位 中斷優(yōu)先級(jí)值 全為1,為最低中斷優(yōu)先級(jí)
          TM0CTL0 = TMM_INTERNAL_CLOCK0 ; // 設(shè)置TMOCTL0 的低3位TMM0預(yù)分頻器值 全為0 ,不分頻
          TM0CMP0 = 32000; // 設(shè)置TM0CMP0 定時(shí)器計(jì)數(shù)比較寄存器 的值為32000,初值定時(shí)為1ms
          }

          /*******************************************************************************
          * Function Name : TMM0_ChangeTimerCondition
          * Description : 修改定時(shí)器計(jì)數(shù)變量值
          * Input : None
          * Output : None
          * Return : None
          *******************************************************************************/
          void TMM0_ChangeTimerCondition( unsigned short regvalue )
          {
          TM0CMP0 = regvalue; // 設(shè)置TM0CMP0 定時(shí)器計(jì)數(shù)比較寄存器
          }

          /*******************************************************************************
          * Function Name : MD_INTTM0EQ0
          * Description : 定時(shí)器TMM0溢出中斷服務(wù)函數(shù)
          * Input : None
          * Output : None
          * Return : None
          *******************************************************************************/
          #pragma vector = INTTM0EQ0_vector
          __interrupt void MD_INTTM0EQ0(void)
          {
          P9L_bit.no4 = ~P9L_bit.no4 ; // 端口P94翻轉(zhuǎn),LED閃爍

          TM0CMP0 = 32000; // 定時(shí)器TMM0不支持自動(dòng)重裝初值,一定要在執(zhí)行完用戶(hù)程序后重裝初值
          TM0EQIF0 = 0; // 清除定時(shí)器中斷標(biāo)志位
          }

          在高亮處更改TMM0分頻系數(shù)。

          代碼出處:main.c

          void main( void )
          {
          SystemClkInit(); // 初始化系統(tǒng)時(shí)鐘為32MHz
          /* PCL setting */
          PCLM = CG_PCL_DISABLE; // 關(guān)閉可編程時(shí)鐘輸出

          __DI(); // 關(guān)閉總中斷
          PMC9L_bit.no4 = 0 ; // 設(shè)置P94為輸入輸出口模式
          PM9L_bit.no4 = 0 ; // 設(shè)置P94端口方向?yàn)檩敵?br />TMM0_Init(); // 定時(shí)器TMM0初始化
          __EI(); // 打開(kāi)總中斷

          TMM0_Start(); // 定時(shí)器TMM0開(kāi)始計(jì)數(shù)

          while (1);
          }

          最后把相關(guān)寄存器的datasheet截圖上傳下:



          關(guān)鍵詞: NECV850定時(shí)器TMM

          評(píng)論


          技術(shù)專(zhuān)區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();