欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136

標題: 單片機60s倒計時程序為什么不能顯示? [打印本頁]

作者: hjx5548    時間: 2024-5-19 07:40
標題: 單片機60s倒計時程序為什么不能顯示?
//60s倒計時
#include"stc8.h"
#include "intrins.h"

#define  uint unsigned int
#define  uchar unsigned char   

#define  SEG P1

sbit SCON1 = P3^7;            
sbit SCON2 = P3^6;   

sbit KEY = P3^2;

uchar count=0;
char num=60,ge,shi;
uchar flag;

uchar code table[]={      
        0x03,/*0*/
        0x9F,/*1*/
        0x25,/*2*/
        0x0D,/*3*/
        0x99,/*4*/
        0x49,/*5*/
        0x41,/*6*/
        0x1F,/*7*/
        0x01,/*8*/
        0x09,/*9*/};

void T0_init()                                //5毫秒@11.0592MHz
{
        AUXR &= 0x7F;                        //定時器時鐘12T模式
        TMOD &= 0xF0;                        //設置定時器模式
        TMOD |= 0x01;                        //設置定時器模式
        TL0 = 0x00;                                //設置定時初始值
        TH0 = 0xEE;                                //設置定時初始值
        TF0 = 0;                                //清除TF0標志
        TR0 = 1;                           
        ET0 = 1;                                //使能定時器0中斷
        EA = 1;
}

void IO_init()
{
    P3M0 = 0x00; P3M1 = 0x00;
    P1M0 = 0xff; P1M1 = 0x00;

}

void TM0_Isr() interrupt 1 //5毫秒
{
        TL0 = 0x00;                                //設置定時初始值
        TH0 = 0xEE;                                //設置定時初始值
        flag++;
        if (flag=20)
        {
        flag=0;
                num--;
                if (flag=0)
        {
        flag=60;
        }
}
}

void main()
{
IO_init();
T0_init() ;
        while (1)
  {
                SEG=0xff;
                shi=num/10;
                ge=num%10;
                switch (count)
    {
            case0:SCON1 = 0;SCON2=1; SEG = table[ge];
                    break;
            case1:SCON1 = 1;SCON2=0; SEG = table[shi];
                    break;
            default:
                    break;
    }
                count++;
                if (count>1)count=0;
  }

}

作者: xiaobendan001    時間: 2024-5-19 10:19
每當flag++到20時,flag = 0然后立刻flag=60,然后flag++以后就得等他++到255再變0,重復++到20時再變60,再重復。就是大概flag計數215次num--一次,1075ms減一次,應該可以啊。為啥不顯示?是不顯示還是不計時?另外,SEG=0XFF是想消隱,但是你這是共陰的,因為你的SCON是設置的標準IO,那么只能共陰極了。共陰極的段碼要給0x00才行消隱,你這0xff不是一直亮著嗎?還有掃描切換不要放到主循環,這掃描速度得有多快啊。一個位的顯示時間可能太短了。消隱也可以把兩個SCON都置1。
作者: cy009    時間: 2024-5-19 11:23
原程序有多處錯誤:1.  if (flag=20),應改為 if (flag==200)
2.  動態刷新時間太快,需合理設置count++的時間間隔
3.  case0、case1應為case 0、case 1
……
程序修改如下,僅供參考:
void TM0_Isr() interrupt 1 //5毫秒
{
        TL0 = 0x00;           //設置定時初始值
        TH0 = 0xEE;           //設置定時初始值
        flag++;
        if(flag==200)
        {
                flag=0;
                num--;
                if (num==0)
                {
                    num=60;
                       }
         }

        //動態掃描刷新周期為10毫秒
        count++;
             if (count>1)
             {
                       count=0;
             }
}

void main()
{
        IO_init();
        T0_init() ;
        while(1)
          {
                shi=num/10;
                ge=num%10;
                SCON1 = 1;  SCON2 = 1;  //消隱
                switch(count)
                    {
                            case 0:  SCON1 = 1;  SCON2 = 0;  SEG = table[ge];  break;
                            case 1:  SCON1 = 0;  SCON2 = 1;  SEG = table[shi]; break;
                            default: break;
                    }
          }
}



作者: hjx5548    時間: 2024-5-19 13:43
xiaobendan001 發表于 2024-5-19 10:19
每當flag++到20時,flag = 0然后立刻flag=60,然后flag++以后就得等他++到255再變0,重復++到20時再變60, ...

共陽數碼管

51hei圖片_20240518215731.png (53.96 KB, 下載次數: 35)

51hei圖片_20240518215731.png

作者: hjx5548    時間: 2024-5-19 13:44
xiaobendan001 發表于 2024-5-19 10:19
每當flag++到20時,flag = 0然后立刻flag=60,然后flag++以后就得等他++到255再變0,重復++到20時再變60, ...

void TM0_Isr() interrupt 1 //5毫秒
{
        TL0 = 0x00;                                //設置定時初始值
        TH0 = 0xEE;                                //設置定時初始值
        flag++;
        if (flag=20)
        {
        flag=0;
                num--;
                if (num=0)
        {
        num=60;
        }
}
}
作者: hjx5548    時間: 2024-5-19 13:48
xiaobendan001 發表于 2024-5-19 10:19
每當flag++到20時,flag = 0然后立刻flag=60,然后flag++以后就得等他++到255再變0,重復++到20時再變60, ...

//倒計時
#include"stc8.h"
#include "intrins.h"

#define  uint unsigned int
#define  uchar unsigned char   

#define  SEG P1

sbit SCON1 = P3^7;            
sbit SCON2 = P3^6;   
  
sbit KEY = P3^2;

uchar count=0;
char num=60,ge,shi;
uchar flag;

uchar code table[]={      
        0x03,/*0*/
        0x9F,/*1*/
        0x25,/*2*/
        0x0D,/*3*/
        0x99,/*4*/
        0x49,/*5*/
        0x41,/*6*/
        0x1F,/*7*/
        0x01,/*8*/
        0x09,/*9*/};

void T0_init()                                //5毫秒@11.0592MHz
{
        AUXR &= 0x7F;                        //定時器時鐘12T模式
        TMOD &= 0xF0;                        //設置定時器模式
        TMOD |= 0x01;                        //設置定時器模式
        TL0 = 0x00;                                //設置定時初始值
        TH0 = 0xEE;                                //設置定時初始值
        TF0 = 0;                                //清除TF0標志
        TR0 = 1;                           
        ET0 = 1;                                //使能定時器0中斷
        EA = 1;
}

void IO_init()
{
    P3M0 = 0x00; P3M1 = 0x00;
    P1M0 = 0xff; P1M1 = 0x00;

}

void TM0_Isr() interrupt 1 //5毫秒
{
        TL0 = 0x00;                                //設置定時初始值
        TH0 = 0xEE;                                //設置定時初始值
        flag++;
        if (flag=20)
        {
        flag=0;
                num--;
                if (num=0)
        {
        num=60;
        }
}
}

void main()
{
IO_init();
T0_init() ;
        while (1)
  {
                SEG=0;
                shi=num/10;
                ge=num%10;
                switch (count)
    {
            case0:SCON1 = 0;SCON2=1; SEG = table[ge];
                    break;
            case1:SCON1 = 1;SCON2=0; SEG = table[shi];
                    break;
            default:
                    break;
    }
                count++;
                if (count>1)count=0;
  }

}




















作者: hjx5548    時間: 2024-5-19 13:50
hjx5548 發表于 2024-5-19 13:44
void TM0_Isr() interrupt 1 //5毫秒
{
        TL0 = 0x00;                                //設置定 ...

這樣也不能顯示?
作者: xiaobendan001    時間: 2024-5-19 17:28
hjx5548 發表于 2024-5-19 13:43
共陽數碼管

共陽極的那你得吧兩個SCON設置為推挽才行啊。要不然標準IO的高電平電流同時點亮8個段,即使亮也幾乎看不到吧。消隱要讓SCON=0,輸出SEG之后再把對應的SCON=1
作者: cy009    時間: 2024-5-19 20:08
hjx5548 發表于 2024-5-19 13:43
共陽數碼管

共陽的數碼管,你用共陰的代碼,提問之前請先說明清楚。
作者: 622323wjl    時間: 2025-11-9 17:21
你的代碼有問題
中斷邏輯錯誤:定時器 0 中斷中使用if(flag=20)和if(flag=0)(賦值語句而非判斷語句),導致倒計時邏輯完全錯亂,無法正常遞減。
倒計時邊界處理缺失:未處理num減至 0 后的復位邏輯,且flag=60的賦值無意義,導致數值溢出或停滯。
動態掃描時序不合理:主函數中無延時直接切換數碼管位選,掃描頻率過快,肉眼無法識別,表現為 “不顯示” 或 “顯示模糊”。
數碼管段碼可能不匹配:若使用共陽極數碼管,當前段碼表(共陰極)會導致顯示異常,需確認硬件連接類型。
  1. #include"stc8.h"
  2. #include "intrins.h"

  3. #define uint unsigned int
  4. #define uchar unsigned char   

  5. #define SEG P1  // 數碼管段選引腳
  6. sbit SCON1 = P3^7;  // 個位數碼管位選
  7. sbit SCON2 = P3^6;  // 十位數碼管位選
  8. sbit KEY = P3^2;    // 按鍵(預留,可用于啟動/復位)

  9. uchar count = 0;    // 數碼管掃描計數
  10. char num = 60;      // 倒計時初始值(0-60)
  11. uchar ge, shi;      // 個位、十位拆分值
  12. uchar flag = 0;     // 定時器計數標志

  13. // 共陰極數碼管段碼表(0-9),若為共陽極需改為0xFC,0x60,0xDA,0xF2,0x66,0xB6,0xBE,0xE0,0xFE,0xF6
  14. uchar code table[] = {      
  15.     0x03,/*0*/ 0x9F,/*1*/ 0x25,/*2*/ 0x0D,/*3*/ 0x99,/*4*/
  16.     0x49,/*5*/ 0x41,/*6*/ 0x1F,/*7*/ 0x01,/*8*/ 0x09,/*9*/
  17. };

  18. // 定時器0初始化:5毫秒@11.0592MHz(12T模式)
  19. void T0_init() {
  20.     AUXR &= 0x7F;    // 定時器時鐘12T模式
  21.     TMOD &= 0xF0;    // 清除定時器0模式
  22.     TMOD |= 0x01;    // 定時器0工作模式1(16位定時)
  23.     TL0 = 0x00;      // 定時5ms初始值(11.0592MHz計算得出)
  24.     TH0 = 0xEE;      // 重載值:TH0=0xEE, TL0=0x00,單次定時約5ms
  25.     TF0 = 0;         // 清除溢出標志
  26.     TR0 = 1;         // 啟動定時器0
  27.     ET0 = 1;         // 使能定時器0中斷
  28.     EA = 1;          // 開啟總中斷
  29. }

  30. // IO口初始化:P1推挽輸出(段選),P3準雙向(位選/按鍵)
  31. void IO_init() {
  32.     P3M0 = 0x00; P3M1 = 0x00;  // P3口準雙向模式
  33.     P1M0 = 0xFF; P1M1 = 0x00;  // P1口推挽輸出(驅動數碼管)
  34.     SCON1 = 1; SCON2 = 1;     // 初始位選關閉(避免串擾)
  35. }

  36. // 毫秒級延時函數(用于數碼管動態掃描,調整顯示清晰度)
  37. void Delay_ms(uint ms) {
  38.     uint i, j;
  39.     for(i = ms; i > 0; i--)
  40.         for(j = 110; j > 0; j--);
  41. }

  42. // 定時器0中斷服務函數:5ms觸發一次,累計1秒遞減num
  43. void TM0_Isr() interrupt 1 {
  44.     TL0 = 0x00;  // 重新加載定時初始值
  45.     TH0 = 0xEE;
  46.     flag++;      // 每5ms計數+1
  47.    
  48.     // 累計20次=100ms?修正:200次=1000ms(1秒),原邏輯計時過快
  49.     if (flag == 200) {  
  50.         flag = 0;       // 計數清零
  51.         num--;          // 每秒遞減1
  52.         if (num < 0) {  // 倒計時結束(0→-1),復位為60
  53.             num = 60;
  54.         }
  55.     }
  56. }

  57. void main() {
  58.     IO_init();   // IO口初始化
  59.     T0_init();   // 定時器0初始化
  60.    
  61.     while (1) {
  62.         // 拆分十位和個位(num范圍0-60)
  63.         shi = num / 10;  // 十位:60→6,0→0
  64.         ge = num % 10;   // 個位:60→0,9→9
  65.         
  66.         // 動態掃描顯示:個位→十位,每段延時5ms,避免閃爍
  67.         switch (count) {
  68.             case 0:  // 顯示個位
  69.                 SCON1 = 0;  // 開啟個位數碼管
  70.                 SCON2 = 1;  // 關閉十位數碼管
  71.                 SEG = table[ge];  // 輸出個位段碼
  72.                 Delay_ms(5);      // 保持顯示,確保肉眼識別
  73.                 break;
  74.             case 1:  // 顯示十位
  75.                 SCON1 = 1;  // 關閉個位數碼管
  76.                 SCON2 = 0;  // 開啟十位數碼管
  77.                 SEG = table[shi];  // 輸出十位段碼
  78.                 Delay_ms(5);      // 保持顯示
  79.                 break;
  80.             default:
  81.                 count = 0;  // 重置掃描計數
  82.                 break;
  83.         }
  84.         count++;
  85.         if (count > 1) {
  86.             count = 0;  // 僅兩位數碼管,循環掃描
  87.         }
  88.     }
  89. }
復制代碼

1. 修復中斷邏輯錯誤
將中斷中的if(flag=20)改為if(flag==200)(判斷語句而非賦值),且修正計時邏輯:5ms×200=1000ms(1 秒),確保每秒遞減 1。
增加num<0的邊界處理,倒計時結束后自動復位為 60,實現循環倒計時。
2. 優化數碼管動態掃描
新增Delay_ms()函數,在每位數碼管顯示后延時 5ms,降低掃描頻率,使肉眼能清晰識別數字(原代碼無延時,掃描過快導致 “不顯示”)。
初始位選設置為SCON1=1、SCON2=1(關閉狀態),避免初始化時數碼管串擾。
3. 修正數碼管段碼適配
段碼表標注共陰極 / 共陽極差異,若硬件使用共陽極數碼管,需替換段碼表(注釋中已給出共陽極段碼),否則會出現 “全亮” 或 “不顯示”。
4. 完善 IO 口初始化
明確 P1 口為推挽輸出(驅動數碼管段選),P3 口為準雙向模式(位選和按鍵輸入),匹配硬件驅動需求。
作者: 人人學會單片機    時間: 2025-11-12 21:38
去找《人人學會單片機》的課程資料 和 源代碼  每一份開源代碼 都是經過嚴格測試 千錘百煉




歡迎光臨 (http://www.raoushi.com/bbs/) Powered by Discuz! X3.1