久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 2364|回復: 11
打印 上一主題 下一主題
收起左側

51單片機計數器程序問題請教

[復制鏈接]
跳轉到指定樓層
樓主
我用計數器0對直流減速電機編碼器計數,編碼器每651個脈沖代表電機轉動一圈,主函數通過計數器0的溢出標志位TR0變為1的次數,對電機的圈數進行累加、顯示,但不知為什么,顯示一直都是零,是計數器0一直就沒有觸發中斷?還是程序設計有問題?求高手指點指點,謝謝!
單片機源程序如下:
#include "reg52.h"

typedef unsigned int u16;        //對系統默認數據類型進行重定義
typedef unsigned char u8;

//定義LED1管腳
sbit LED1=P2^0;

#define SMG_A_DP_PORT        P0        //使用宏定義數碼管段碼口

//定義數碼管位選信號控制腳
sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;



/*******************************************************************************
* 函 數 名       : delay_10us
* 函數功能                 : 延時函數,ten_us=1時,大約延時10us
* 輸    入       : ten_us
* 輸    出             : 無
*******************************************************************************/
void delay_10us(u16 ten_us)
{
        while(ten_us--);      
}

//共陰極數碼管顯示0~F的段碼數據
u8 gsmg_code[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
                                0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};


/*******************************************************************************
* 函 數 名       : smg_display
* 函數功能                 : 動態數碼管顯示
* 輸    入       : 無
* 輸    出             : 無
*******************************************************************************/
void smg_display(u8 dat[])
{
        u8 i=0;

        for(i=0;i<8;i++)
        {
                   switch(i)//位選
                {
                        case 0: LSC=1;LSB=1;LSA=1;SMG_A_DP_PORT=gsmg_code[dat[0]];break;
                        case 1: LSC=1;LSB=1;LSA=0;SMG_A_DP_PORT=gsmg_code[dat[1]];break;
                        case 2: LSC=1;LSB=0;LSA=1;SMG_A_DP_PORT=gsmg_code[dat[2]];break;
                        case 3: LSC=1;LSB=0;LSA=0;SMG_A_DP_PORT=gsmg_code[dat[3]];break;
                        case 4: LSC=0;LSB=1;LSA=1;SMG_A_DP_PORT=gsmg_code[dat[4]];break;
                        case 5: LSC=0;LSB=1;LSA=0;SMG_A_DP_PORT=gsmg_code[dat[5]];break;
                        case 6: LSC=0;LSB=0;LSA=1;SMG_A_DP_PORT=gsmg_code[dat[6]];break;
                        case 7: LSC=0;LSB=0;LSA=0;SMG_A_DP_PORT=gsmg_code[dat[7]];break;
                }
                delay_10us(20);//延時一段時間,等待顯示穩定
                SMG_A_DP_PORT=0x00;//消音
        }
}


/*******************************************************************************
* 函 數 名       : time0_init
* 函數功能                 : 定時器0中斷配置函數,通過設置TH和TL即可確定定時時間
* 輸    入       : 無
* 輸    出             : 無
*******************************************************************************/
void counter0_init(void)
{
        TMOD|=0X05;//選擇為計數器0模式,工作方式1
        TH0=0XFD;        //給計數器賦初值
        TL0=0X71;      
        ET0=1;//打開計數器0中斷允許
        EA=1;//打開總中斷
        TR0=1;//打開計數器
        IT0=0;//下降沿觸發               
}

/*******************************************************************************
* 函 數 名       : main
* 函數功能                 : 主函數
* 輸    入       : 無
* 輸    出             : 無
*******************************************************************************/
void main()
{      
        u16 roll;
        u8 rollb8[8];

        counter0_init();//計數器0中斷配置

        while(1)
        {                       
                if(TF0==1)
                {
                        roll++;
                        TF0=0;
                }
                rollb8[3]=roll/10000;                        //讀取萬位數
                rollb8[4]=roll%10000/1000;                //讀取千位數
                rollb8[5]=roll%1000/100;                  //讀取百位數
                rollb8[6]=roll%100/10;                           //讀取十位數
                rollb8[7]=roll%10;                                     //讀取個位數
                smg_display(rollb8);                        //調用數碼管顯示
                                               
        }               
}

void conter0() interrupt 1 //定時器0中斷函數
{
        TH0=0XFD;        //給計數器賦初值
        TL0=0X71;
}
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏2 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:1005338 發表于 2022-4-24 22:28 | 只看該作者
調試后發現,確定是計數器0溢出后,TF0不會自動置1,這到底是什么原因?
回復

使用道具 舉報

板凳
ID:624769 發表于 2022-4-24 22:58 來自觸屏版 | 只看該作者
你開了中斷,tf0會自動清0,你要做個標志位,在中斷里置1,然后主程序判斷這個標志位。
回復

使用道具 舉報

地板
ID:1005338 發表于 2022-4-24 23:41 | 只看該作者
188610329 發表于 2022-4-24 22:58
你開了中斷,tf0會自動清0,你要做個標志位,在中斷里置1,然后主程序判斷這個標志位。

不好意思,我是初學,沒太理解你的意思,請您再幫忙指點一下:
先開的中斷,然后開始while死循環,等待計數器溢出,溢出后TF0不就應該自動置1嗎?TF0不就是溢出的標志位嗎?
回復

使用道具 舉報

5#
ID:624769 發表于 2022-4-25 00:07 來自觸屏版 | 只看該作者
niejiangong 發表于 2022-4-24 23:41
不好意思,我是初學,沒太理解你的意思,請您再幫忙指點一下:
先開的中斷,然后開始while死循環,等待 ...

tf0==1之后,就會立刻執行中斷程序,中斷程序會自動清0標志tf0,即,你只要開了定時器0的中斷,你就永遠讀不到tf0==1。tf會等于1一瞬間,但是你永遠看不到,當你去判斷的時候,tf0一定已經變0了,明白了么?
回復

使用道具 舉報

6#
ID:1005338 發表于 2022-4-25 12:03 | 只看該作者
188610329 發表于 2022-4-25 00:07
tf0==1之后,就會立刻執行中斷程序,中斷程序會自動清0標志tf0,即,你只要開了定時器0的中斷,你就永遠 ...

非常感謝您的耐心指點!我還有疑惑:
一、既然開了定時器0的中斷,無法讀到TF0==1,那這個TF0標志位不是失去存在的意義了嗎?
二、有沒有什么辦法來利用這個TF0標志位呢?
三、如果TF0不能用,通常用哪個寄存器來做標志位比較好?是不是需要定義一個全局變量?
回復

使用道具 舉報

7#
ID:213173 發表于 2022-4-25 14:35 | 只看該作者
niejiangong 發表于 2022-4-25 12:03
非常感謝您的耐心指點!我還有疑惑:
一、既然開了定時器0的中斷,無法讀到TF0==1,那這個TF0標志位不是 ...

使用定時器分查詢方式和中斷方式。如果用查詢方式,TF0是要軟件清0。使用中斷方式TF0由硬件自動清0。兩者不可以同時使用。在樓主此應用中不宜使用查詢方式。因為電機轉速可能超過主循環周期,就有可能丟失數據。給你把程序改了,你試試。
  1. #include "reg52.h"

  2. typedef unsigned int u16;        //對系統默認數據類型進行重定義
  3. typedef unsigned char u8;

  4. //定義LED1管腳
  5. sbit LED1=P2^0;

  6. #define SMG_A_DP_PORT P0        //使用宏定義數碼管段碼口

  7. //定義數碼管位選信號控制腳
  8. sbit LSA=P2^2;
  9. sbit LSB=P2^3;
  10. sbit LSC=P2^4;

  11. //共陰極數碼管顯示0~F的段碼數據
  12. u8 gsmg_code[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
  13.                   0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
  14. u16 count=0;
  15. u8  rollb8[8];
  16. /*******************************************************************************
  17. * 函 數 名       : delay_10us
  18. * 函數功能       : 延時函數,ten_us=1時,大約延時10us
  19. * 輸    入       : ten_us
  20. * 輸    出       : 無
  21. *******************************************************************************/
  22. /*
  23. void delay_10us(u16 ten_us)
  24. {
  25.         while(ten_us--);      
  26. }*/
  27. /*******************************************************************************
  28. * 函 數 名       : smg_display
  29. * 函數功能       : 動態數碼管顯示
  30. * 輸    入       : 無
  31. * 輸    出       : 無
  32. *******************************************************************************/
  33. void smg_display()
  34. {
  35.         static u8 i=0;
  36.         u8 j=0;
  37.         u16 k;//緩沖變量
  38.         k=count;       
  39.         for(j=0;j<5;j++)
  40.         {
  41.                 rollb8[j]=k%10;//由低位到高位分解保存
  42.                 k/=10;
  43.         }
  44.         SMG_A_DP_PORT=0x00;//段消隱
  45.         P2&=0xe3;//位清除
  46.         P2|=i<<2;//送位碼
  47.         SMG_A_DP_PORT=gsmg_code[rollb8[i]];//送段碼
  48.         i=++i%5;//循環計數
  49. }
  50. /*******************************************************************************
  51. * 函 數 名       : time0_init
  52. * 函數功能       : 定時器0中斷配置函數,通過設置TH和TL即可確定定時時間
  53. * 輸    入       : 無
  54. * 輸    出       : 無
  55. *******************************************************************************/
  56. void counter0_init(void)
  57. {
  58.         TMOD|=0X05;//選擇為計數器0模式,工作方式1
  59.         TH0=0XFD;  //給計數器賦初值65536-651
  60.         TL0=0X75;      
  61.         TF0=0;
  62.         TR0=1;        //打開計數器
  63.         ET0=1;        //打開計數器0中斷允許
  64.         EA=1;        //打開總中斷
  65. //        IT0=0;        //下降沿觸發               
  66. }
  67. /*******************************************************************************
  68. * 函 數 名       : main
  69. * 函數功能       : 主函數
  70. * 輸    入       : 無
  71. * 輸    出       : 無
  72. *******************************************************************************/
  73. void main()
  74. {      
  75.         counter0_init();//計數器0中斷配置
  76.         while(1)
  77.         {                       
  78.                 smg_display();
  79.         }
  80. }

  81. void conter0() interrupt 1 //定時器0中斷函數
  82. {
  83.         TH0=0xfd;        //給計數器賦初值
  84.         TL0=0x75;
  85.         count++;
  86.         if(count>50000)//限制最大數
  87.                 count=0;
  88. }
復制代碼




回復

使用道具 舉報

8#
ID:624769 發表于 2022-4-25 14:52 來自觸屏版 | 只看該作者
niejiangong 發表于 2022-4-25 12:03
非常感謝您的耐心指點!我還有疑惑:
一、既然開了定時器0的中斷,無法讀到TF0==1,那這個TF0標志位不是 ...

1)  tf0標志,是定時器中斷觸發的重要標志,怎么會沒有意義?
2) 你不開中斷(et0=0),就能讀到tf0==1了。
3) 在板凳的回復已經說了,聲明一個全局標志位,在中斷里置1,主程序里面判斷這個標志來取代判斷tf0。
回復

使用道具 舉報

9#
ID:1005338 發表于 2022-4-25 17:21 | 只看該作者
wulin 發表于 2022-4-25 14:35
使用定時器分查詢方式和中斷方式。如果用查詢方式,TF0是要軟件清0。使用中斷方式TF0由硬件自動清0。兩者 ...

我試了一下,完全正確!水平太高了。
回復

使用道具 舉報

10#
ID:149451 發表于 2022-4-26 17:18 | 只看該作者
wulin 發表于 2022-4-25 14:35
使用定時器分查詢方式和中斷方式。如果用查詢方式,TF0是要軟件清0。使用中斷方式TF0由硬件自動清0。兩者 ...

菜鳥暈了,求指點。
樓主說是“對直流減速電機編碼器計數”,那么旋轉編碼端子沒定義,是因為用了“TMOD|=0X05;//選擇為計數器0模式,工作方式1”,編碼器端子自然要接入P3.2,不用在程序里表明了?
回復

使用道具 舉報

11#
ID:161164 發表于 2022-4-27 11:52 | 只看該作者
w1179benp 發表于 2022-4-26 17:18
菜鳥暈了,求指點。
樓主說是“對直流減速電機編碼器計數”,那么旋轉編碼端子沒定義,是因為用了“TMOD ...

P3.4才對

回復

使用道具 舉報

12#
ID:1005338 發表于 2022-5-22 12:56 | 只看該作者
w1179benp 發表于 2022-4-26 17:18
菜鳥暈了,求指點。
樓主說是“對直流減速電機編碼器計數”,那么旋轉編碼端子沒定義,是因為用了“TMOD ...

編碼器的端子直接接入P3.4,不用表明
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 欧美视频区| 天堂资源最新在线 | 中文字幕av一区 | aa级毛片毛片免费观看久 | 黄色精品 | 国产精品不卡 | 欧美精品区 | 国产视频中文字幕在线观看 | 精品国产乱码久久久久久中文 | 久久久久久国模大尺度人体 | 99久久影院| 天天射色综合 | 欧美激情欧美激情在线五月 | 一区二区三区视频在线 | 国产在线精品一区二区 | 久久99国产精一区二区三区 | www.久久| 久久五月婷 | 特黄色毛片| 免费的av | 久久精品久久久 | 亚洲人人 | 天天干天天插 | 911精品国产| 色综合天天网 | 国产视频第一页 | 精品一区二区三区四区 | 国产95在线| 91精品国产综合久久婷婷香蕉 | 在线观看涩涩视频 | 国产精品一区二区不卡 | 国产原创在线观看 | 国产一级片久久久 | 玖玖精品| 亚洲人成网亚洲欧洲无码 | 我我色综合 | 欧美久久一级 | 成人免费淫片aa视频免费 | 亚洲www啪成人一区二区 | 欧美精品1区2区 | 最新高清无码专区 |