找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 2448|回復(fù): 32
收起左側(cè)

大佬們,為什么我這單片機(jī)數(shù)碼管會亂閃呢?

[復(fù)制鏈接]
ID:1058641 發(fā)表于 2024-2-23 20:50 | 顯示全部樓層 |閱讀模式
  1. #include "reg52.h"
  2. #include "seg.h"
  3. #include "iic.h"
  4. #include "onewire.h"
  5. #include "key.h"
  6. #include "led.h"

  7. #define uchar unsigned char
  8. #define uint unsigned int
  9.         
  10. //led
  11. uchar led_buf[]={0,0,0,0,0,0,0,0};

  12. //°´¼ü
  13. uchar key_sld;

  14. //ÊýÂë¹Ü
  15. uint seg_sld;
  16. uchar seg_pos;
  17. uchar seg_buf[]={10,10,10,10,10,10,10,10};
  18. uchar seg_point[]={0,0,0,0,0,0,0,0};

  19. //½çÃæ
  20. uchar show_mo=0;
  21. bit mode=0;
  22. uint temp;
  23. uchar set_temp=25;
  24. uint out_v;

  25. //º¯Êý

  26. void smg_reset()
  27. {
  28.         uchar i;
  29.         for(i=0;i<8;i++)
  30.         {
  31.                 seg_buf[i]=10;
  32.                 seg_point[i]=0;
  33.         }
  34. }

  35. void init()
  36. {
  37.         P0=0x00;
  38.         P2=P2&0x1f|0xa0;
  39.         P2&=0x1f;
  40.         
  41.         P0=0xff;
  42.         P2=P2&0x1f|0x80;
  43.         P2&=0x1f;
  44. }

  45. void key_proc()
  46. {
  47.         static uchar key_val,key_old,key_down,key_up;
  48.         if(key_sld)
  49.                 return;
  50.         key_sld=1;
  51.         
  52.         key_val=readkey();
  53.         key_down=key_val&(key_val^key_old);
  54.         key_up=~key_val&(key_val^key_old);
  55.         key_old=key_val;
  56.         
  57.         if(key_down==4)
  58.                 show_mo=(++show_mo)%3;
  59.         else if(show_mo==1 && key_down==6)
  60.                 set_temp=(++set_temp>99)?99:set_temp;
  61.         else if(show_mo==1 && key_down==7)
  62.                 set_temp=(--set_temp==0)?0:set_temp;
  63.         else if(key_down==5)
  64.                 mode=~mode;
  65.         
  66. }

  67. void seg_proc()
  68. {
  69.         uint temp_temp;
  70.         if(seg_sld)
  71.                 return;
  72.         seg_sld=1;
  73.         temp_temp=(uint)ds18b20_read();
  74.         temp=temp_temp;
  75.         
  76.         switch(show_mo)
  77.         {
  78.                 case 0:
  79.                         smg_reset();
  80.                         seg_buf[0]=11;//c
  81.                         seg_buf[4]=temp/1000;
  82.                         seg_buf[5]=temp/100%10;
  83.                         seg_buf[6]=temp/10%10;
  84.                         seg_buf[7]=temp%10;
  85.                         seg_point[5]=1;
  86.                  break;
  87.                
  88.                 case 1:
  89.                         smg_reset();
  90.                         seg_buf[0]=12;//p
  91.                         seg_buf[6]=set_temp/10;
  92.                         seg_buf[7]=set_temp%10;
  93.                  break;
  94.                
  95.                 case 2:
  96.                         smg_reset();
  97.                         seg_buf[0]=13;//a
  98.                         if(mode)
  99.                         {
  100.                                 if(temp_temp>set_temp)
  101.                                         out_v=500;
  102.                                 else
  103.                                         out_v=0;
  104.                                 seg_buf[5]=out_v/100;
  105.                                 seg_buf[6]=out_v/10%10;
  106.                                 seg_buf[7]=out_v%10;
  107.                                 seg_point[5]=1;
  108.                                 da_write(out_v*16);
  109.                         }
  110.                         else
  111.                         {
  112.                                 if(temp_temp<=20)
  113.                                         out_v=1;
  114.                                 else if(temp_temp>=40)
  115.                                         out_v=4;
  116.                                 else
  117.                                         out_v=temp_temp*3/20;
  118.                                 seg_buf[5]=out_v/100;
  119.                                 seg_buf[6]=out_v/10%10;
  120.                                 seg_buf[7]=out_v%10;
  121.                                 seg_point[5]=1;
  122.                                 da_write(out_v*16);
  123.                         }
  124.                         break;
  125.         }
  126. }

  127. void led_proc()
  128. {
  129.         led_buf[0]=(mode==0);
  130.         led_buf[1]=(show_mo==0);
  131.         led_buf[2]=(show_mo==1);
  132.         led_buf[3]=(show_mo==2);
  133. }

  134. void Timer0Init(void)                //1??@12.000MHz
  135. {
  136.         TMOD &= 0xF0;                //???????
  137.         TL0 = 0x18;                //??????
  138.         TH0 = 0xFC;                //??????
  139.         TF0 = 0;                //??TF0??
  140.         TR0 = 1;                //???0????
  141.         ET0 = 1;
  142.         EA =1;
  143. }

  144. void timer() interrupt 1
  145. {
  146.         if(++key_sld==10)
  147.                 key_sld=0;
  148.         if(++seg_sld==1000)
  149.                 seg_sld=0;
  150.         if(++seg_pos==8)
  151.                 seg_pos=0;
  152.         
  153.         segdis(seg_buf[seg_pos],seg_pos,seg_point[seg_pos]);
  154.         led_disp(seg_pos,led_buf[seg_pos]);
  155. }


  156. void main()
  157. {
  158.         Timer0Init();
  159.         init();
  160.         while(1)
  161.         {
  162.                 key_proc();
  163.                 seg_proc();
  164.                 led_proc();
  165.         }
  166. }
復(fù)制代碼
回復(fù)

使用道具 舉報

ID:192020 發(fā)表于 2024-2-28 09:07 | 顯示全部樓層

中斷里調(diào)用segdis函數(shù)的傳參反了
回復(fù)

使用道具 舉報

ID:1058641 發(fā)表于 2024-2-27 21:36 | 顯示全部樓層
qq475878026 發(fā)表于 2024-2-27 09:52
改的小問題,不夠細(xì)心

那里的問題唉
回復(fù)

使用道具 舉報

ID:1058641 發(fā)表于 2024-2-27 12:25 | 顯示全部樓層
qq475878026 發(fā)表于 2024-2-27 09:52
改的小問題,不夠細(xì)心

那里的錯唉
回復(fù)

使用道具 舉報

ID:192020 發(fā)表于 2024-2-27 09:52 | 顯示全部樓層
改的小問題,不夠細(xì)心

十二_2.rar

52.3 KB, 下載次數(shù): 1

回復(fù)

使用道具 舉報

ID:1109793 發(fā)表于 2024-2-27 08:10 | 顯示全部樓層

我找了一個KEIL5怎么只有ARM的
回復(fù)

使用道具 舉報

ID:1058641 發(fā)表于 2024-2-26 19:35 | 顯示全部樓層
xiaobendan001 發(fā)表于 2024-2-26 17:46
怎么我在這里下載的proteus還是打不開你的這個文件呢?難道又是版本太低?

我是8.10的
回復(fù)

使用道具 舉報

ID:1109793 發(fā)表于 2024-2-26 17:46 | 顯示全部樓層
rtyweq 發(fā)表于 2024-2-26 15:14
這是proteus的仿真,后面是錄屏

怎么我在這里下載的proteus還是打不開你的這個文件呢?難道又是版本太低?
回復(fù)

使用道具 舉報

ID:1109793 發(fā)表于 2024-2-26 17:44 | 顯示全部樓層
rtyweq 發(fā)表于 2024-2-26 15:14
這是proteus的仿真,后面是錄屏

正好我用來學(xué)習(xí)一下proteus
回復(fù)

使用道具 舉報

ID:1058641 發(fā)表于 2024-2-26 15:14 | 顯示全部樓層
這是proteus的仿真,后面是錄屏

藍(lán)橋杯單片機(jī)仿真原理圖 (2).rar

39.82 KB, 下載次數(shù): 6

回復(fù)

使用道具 舉報

ID:161164 發(fā)表于 2024-2-26 09:48 | 顯示全部樓層
rtyweq 發(fā)表于 2024-2-25 11:46
還是不對勁,我把工程發(fā)給你能幫我看看嗎

如何不對勁?描述一下或錄屏
把仿真檔也上傳
回復(fù)

使用道具 舉報

ID:213173 發(fā)表于 2024-2-26 09:45 | 顯示全部樓層
rtyweq 發(fā)表于 2024-2-25 11:46
還是不對勁,我把工程發(fā)給你能幫我看看嗎

初學(xué)階段不要試圖將學(xué)習(xí)板上的功能模塊在一個工程里都實(shí)現(xiàn)。要由簡入深循序漸進(jìn)。充分掌握各模塊功能后再將各功能模塊組合到一個工程里就是水到渠成的事。
回復(fù)

使用道具 舉報

ID:1109793 發(fā)表于 2024-2-26 07:23 | 顯示全部樓層

真先進(jìn),我剛在這里下載了keil3和proteus,研究了一下,順便問問,proteus能不能導(dǎo)入AD的原理圖?
回復(fù)

使用道具 舉報

ID:1058641 發(fā)表于 2024-2-25 20:44 | 顯示全部樓層
我可以啊
回復(fù)

使用道具 舉報

ID:1058641 發(fā)表于 2024-2-25 20:43 | 顯示全部樓層
就是keil啊keil5
回復(fù)

使用道具 舉報

ID:1109793 發(fā)表于 2024-2-25 19:47 | 顯示全部樓層

問一下,你這用什么打開?我用keil好像不行啊
回復(fù)

使用道具 舉報

ID:1058641 發(fā)表于 2024-2-25 15:58 | 顯示全部樓層
有沒有哪個大佬能幫我看一下啊
回復(fù)

使用道具 舉報

ID:1058641 發(fā)表于 2024-2-25 14:34 | 顯示全部樓層
球球了,真不知道咋回事了
回復(fù)

使用道具 舉報

ID:1109793 發(fā)表于 2024-2-25 13:15 | 顯示全部樓層

問一下題外話,我鼠標(biāo)指針指到文件名上面就出來一個黃顏色提示框,點(diǎn)擊文件名下載,這個框擋住了文件名,點(diǎn)擊也不能下載,是咋回事
回復(fù)

使用道具 舉報

ID:1058641 發(fā)表于 2024-2-25 11:47 | 顯示全部樓層
這是壓縮包

十二.rar

46.38 KB, 下載次數(shù): 9

回復(fù)

使用道具 舉報

ID:1058641 發(fā)表于 2024-2-25 11:46 | 顯示全部樓層
wulin 發(fā)表于 2024-2-25 06:20
P0分時復(fù)用通過573驅(qū)動數(shù)碼管需要分3步:段消影、送位碼、送段碼。以本例硬件條件編寫
        P0=0xff; //P0賦 ...

還是不對勁,我把工程發(fā)給你能幫我看看嗎
回復(fù)

使用道具 舉報

ID:213173 發(fā)表于 2024-2-25 06:20 | 顯示全部樓層
rtyweq 發(fā)表于 2024-2-24 21:50
這是數(shù)碼管部分的
unsigned char smgduan[]={
0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,

P0分時復(fù)用通過573驅(qū)動數(shù)碼管需要分3步:段消影、送位碼、送段碼。以本例硬件條件編寫
  1.         P0=0xff; //P0賦段消影碼
  2.         P2&=0x1f;//清P2高3位
  3.         P2|=0xe0;//傳送消影段碼
  4.         P2&=0x1f;//清P2高3位

  5.         P0=0x01<<i;//P0賦位碼
  6.         P2&=0x1f;//清P2高3位
  7.         P2|=0xd0;//傳送位碼
  8.         P2&=0x1f;//清P2高3位

  9.         P0=dis_buf[i];//P0賦段碼
  10.         P2&=0x1f;//清P2高3位
  11.         P2|=0xe0;//傳送段碼
  12.         P2&=0x1f;//清P2高3位
復(fù)制代碼
回復(fù)

使用道具 舉報

ID:1058641 發(fā)表于 2024-2-24 21:50 | 顯示全部樓層
wulin 發(fā)表于 2024-2-24 17:30
樓主搞了這么長時間數(shù)碼管還搞不定,情何以堪。前面的帖子給你的示例認(rèn)真看了嗎?這是壇友畫的仿真圖,寫 ...

這是數(shù)碼管部分的
unsigned char smgduan[]={
0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
0x80,0x90,0xff,0xc6,0x7c,0x88};

unsigned char segwei[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};

void segdis(unsigned char wei,unsigned char duan,unsigned char point)
{
        P0=0xff;
        P2=P2&0x1f|0xe0;
        P0=segwei[wei];
       
        P2=P2&0x1f|0xc0;
        P2&=0x1f;
        P0=smgduan[duan];
       
        if(point)
                P0&=0x7f;
       
        P2=P2&0x1f|0xe0;
        P2&=0x1f;
}
回復(fù)

使用道具 舉報

ID:213173 發(fā)表于 2024-2-24 17:30 | 顯示全部樓層

樓主搞了這么長時間數(shù)碼管還搞不定,情何以堪。前面的帖子給你的示例認(rèn)真看了嗎?這是壇友畫的仿真圖,寫個時鐘程序給你試試。
無標(biāo)題.jpg 仿真.rar (46.5 KB, 下載次數(shù): 1)

  1. #include "reg52.h"
  2. #include "intrins.h"

  3. sbit key1=P3^0;
  4. sbit key2=P3^1;
  5. sbit key3=P3^2;
  6. sbit GND =P3^7;

  7. unsigned char code smgdata[]={
  8. 0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,
  9. 0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xbf,0x8c};
  10. unsigned char  data dis_buf[8];
  11. unsigned int temp,Cnt2ms;
  12. char H=12,M=30,S=0;//時分秒
  13. unsigned char KeySec;//鍵值
  14. bit flag;//中斷標(biāo)志
  15. bit flicker;//閃爍標(biāo)志
  16. void keyscan()
  17. {
  18.         static char time=0;
  19.         static bit sign=0;
  20.         if(!key1||!key2||!key3)
  21.         {
  22.                 if(++time>=20 && sign==0)//短按消抖
  23.                 {
  24.                         sign=1;
  25.                         if(!key1)KeySec=++KeySec%4;
  26.                         if(!key2 && KeySec!=0)
  27.                         {
  28.                                 switch(KeySec)
  29.                                 {
  30.                                         case 1: if(++H>23)H=0; break;
  31.                                         case 2: if(++M>59)M=0; break;
  32.                                         case 3: if(++S>59)S=0; break;
  33.                                 }
  34.                         }
  35.                         if(!key3 && KeySec!=0)
  36.                         {
  37.                                 switch(KeySec)
  38.                                 {
  39.                                         case 1: if(--H<0)H=23; break;
  40.                                         case 2: if(--M<0)M=59; break;
  41.                                         case 3: if(--S<0)S=59; break;
  42.                                 }
  43.                         }
  44.                         Cnt2ms=0;
  45.                 }
  46.         }
  47.         else {time=0;sign=0;}
  48. }


  49. void Timer0_Init(void)                //2毫秒@11.0592MHz
  50. {
  51.         TMOD |= 0x01;                        //設(shè)置定時器模式
  52.         TL0 = 0xCD;                                //設(shè)置定時初始值
  53.         TH0 = 0xF8;                                //設(shè)置定時初始值
  54.         TF0 = 0;                                //清除TF0標(biāo)志
  55.         TR0 = 1;                                //定時器0開始計(jì)時
  56.         ET0 = 1;                                //使能定時器0中斷
  57.         EA  = 1;
  58. }

  59. void main()
  60. {
  61.         unsigned char i,j;
  62.         GND=0;//模擬地
  63.         Timer0_Init();
  64.         while (1)
  65.         {
  66.                 if(flag)
  67.                 {
  68.                         flag=0;
  69.                         P0=0xff;       P2=0xe0; P2=0x00;//段消影
  70.                         P0=0x01<<i;    P2=0xd0; P2=0x00;//傳位碼
  71.                         P0=dis_buf[i]; P2=0xe0; P2=0x00;//傳段碼
  72.                         keyscan();
  73.                         if(++j==100){j=0;flicker=~flicker;}
  74.                         if(KeySec==0)Cnt2ms++;
  75.                         if(Cnt2ms>=500)//秒
  76.                         {
  77.                                 Cnt2ms=0;
  78.                                 S++;
  79.                                 if(S>=60){S=0;M++;}
  80.                                 if(M>=60){M=0;H++;}
  81.                                 if(H>=24)H=0;
  82.                         }
  83.                         switch(i)
  84.                         {
  85.                                 case 0: dis_buf[0]=smgdata[H/10]; break;
  86.                                 case 1: dis_buf[1]=smgdata[H%10]; break;
  87.                                 case 2: dis_buf[2]=0xbf; break;//"-"
  88.                                 case 3: dis_buf[3]=smgdata[M/10]; break;
  89.                                 case 4: dis_buf[4]=smgdata[M%10]; break;
  90.                                 case 5: dis_buf[5]=0xbf; break;//"-"
  91.                                 case 6: dis_buf[6]=smgdata[S/10]; break;
  92.                                 case 7: dis_buf[7]=smgdata[S%10]; break;

  93.                         }      
  94.                         i=++i%8;//循環(huán)計(jì)數(shù)
  95.                         if(KeySec==1 && flicker){dis_buf[0]=dis_buf[1]=0xff;}//時閃爍
  96.                         if(KeySec==2 && flicker){dis_buf[3]=dis_buf[4]=0xff;}//分閃爍
  97.                         if(KeySec==3 && flicker){dis_buf[6]=dis_buf[7]=0xff;}//秒閃爍
  98.                 }
  99.         }
  100. }
  101. void Timer0_Isr(void) interrupt 1
  102. {
  103.         TL0 = 0xCD;                                //設(shè)置定時初始值
  104.         TH0 = 0xF8;                                //設(shè)置定時初始值
  105.         flag=1;
  106. }
復(fù)制代碼




回復(fù)

使用道具 舉報

ID:1109793 發(fā)表于 2024-2-24 16:27 | 顯示全部樓層
閃爍是怎樣的也看不到。代碼也不全。
回復(fù)

使用道具 舉報

ID:1058641 發(fā)表于 2024-2-24 14:47 | 顯示全部樓層
yzwzfyz 發(fā)表于 2024-2-24 09:57
掃屏顯示的切換應(yīng)當(dāng)用最少的指令完成,在不多于8個LED的情況下:三條指令即可完成,對于STC的單片機(jī),10us ...

不太明白
回復(fù)

使用道具 舉報

ID:1109793 發(fā)表于 2024-2-24 12:28 | 顯示全部樓層
電路好復(fù)雜,這是買的誰家的實(shí)驗(yàn)板嗎?看代碼挺費(fèi)勁,也沒有注釋,好像沒看到驅(qū)動代碼,只是在計(jì)算一些BCD碼。先不要計(jì)算,只給緩沖區(qū)里面固定的數(shù)據(jù)看,如果還是閃,就是驅(qū)動部分了
回復(fù)

使用道具 舉報

ID:1110945 發(fā)表于 2024-2-24 10:18 | 顯示全部樓層
8個數(shù)碼管實(shí)際就是64個發(fā)光二極管,可是控制它的引線只有16根。
實(shí)際上同一時間只能顯示其中的一個數(shù)碼管,8個數(shù)碼管分時輪流顯
示,只要切換的時間足夠快,人眼就能感覺到8個數(shù)碼管在同時顯示
數(shù)字了。數(shù)碼管有段碼表,還有共陰或共陽的區(qū)別。其中任何一個環(huán)
節(jié)出錯了那么顯示的數(shù)字就是亂的。
回復(fù)

使用道具 舉報

ID:123289 發(fā)表于 2024-2-24 09:57 | 顯示全部樓層
掃屏顯示的切換應(yīng)當(dāng)用最少的指令完成,在不多于8個LED的情況下:三條指令即可完成,對于STC的單片機(jī),10us不到就完成了,例:8個LED哪個亮(位選)受P1控制,顯示什么內(nèi)容(段碼)由P0決定。
要點(diǎn):技巧如下。!
先將哪個LED需要亮的參數(shù)事先準(zhǔn)備好,放在:P1_OUT變量中,同樣將這個LED需要顯示的段碼放在P0_OUT中。【這個做法最關(guān)鍵,不要直接切換操作P0、P1口,而是通過這兩個變量來操作。原因是,無論你用多長時間對P1_OUT、P0_OUT進(jìn)行操作,操作期間,顯示不受影響!
切換:
第一條指令:關(guān)斷所有顯示:P1=FFH              ;關(guān)閉所有顯示
第二條指令:切換LED段碼:P0=P0_OUT         ;這時顯示已關(guān),切換不會有殘留,重影,閃爍了。
第三條指令:更新顯示的LED管:P1=P1_OUT  ;點(diǎn)亮需要顯示的LED,例如:11101111B
【這個做法是最優(yōu)秀的掃描顯示切換方法,用時最短,最合理,沒有之二。!】
重復(fù)一下關(guān)鍵點(diǎn):事先處理準(zhǔn)備好變量P1_OUT、P0_OUT的值。

以上供參考,請根據(jù)你的接口來操作,這里的P0、P1不一定與你的圖相同。
回復(fù)

使用道具 舉報

ID:123289 發(fā)表于 2024-2-24 09:53 | 顯示全部樓層
掃描方案不合理。
回復(fù)

使用道具 舉報

ID:1058641 發(fā)表于 2024-2-23 21:12 | 顯示全部樓層
就是這種
屏幕截圖 2024-02-23 211158.png
回復(fù)

使用道具 舉報

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

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表