找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

帖子
查看: 1872|回復(fù): 22
收起左側(cè)

單片機(jī)不在同一端口數(shù)碼管如何顯示?

[復(fù)制鏈接]
ID:1112147 發(fā)表于 2024-3-8 18:53 | 顯示全部樓層 |閱讀模式
共陰極三位數(shù)碼管的段選不在同一個(gè)端口,該怎么用51單片機(jī)讓數(shù)碼管顯示
sbit sega  = P0^1;//數(shù)碼管段選引腳sbit segb  = P3^0;
sbit segc  = P3^4;
sbit segd  = P0^2;
sbit sege  = P0^3;
sbit segf  = P0^0;
sbit segg  = P3^1;
sbit segdp = P1^7;
sbit dir1  = P1^0;//數(shù)碼管位選引腳
sbit dir2  = P1^1;
sbit dir3  = P3^3;


回復(fù)

使用道具 舉報(bào)

ID:883242 發(fā)表于 2024-3-8 22:48 | 顯示全部樓層
那就一個(gè)一個(gè)的置1或者0好了,沒有別的辦法。
回復(fù)

使用道具 舉報(bào)

ID:1109793 發(fā)表于 2024-3-9 07:30 | 顯示全部樓層
把顯示內(nèi)容放到一個(gè)字節(jié),做個(gè)子程序?qū)iT把對(duì)應(yīng)的位傳遞到對(duì)應(yīng)的腳上
回復(fù)

使用道具 舉報(bào)

ID:213173 發(fā)表于 2024-3-9 07:51 | 顯示全部樓層
任意端口組合驅(qū)動(dòng)數(shù)碼管
  1. #include <reg51.H>

  2. sbit sega  = P0^1;//數(shù)碼管段選引腳
  3. sbit segb  = P3^0;
  4. sbit segc  = P3^4;
  5. sbit segd  = P0^2;
  6. sbit sege  = P0^3;
  7. sbit segf  = P0^0;
  8. sbit segg  = P3^1;
  9. sbit segdp = P1^7;
  10. sbit dir1  = P1^0;//數(shù)碼管位選引腳
  11. sbit dir2  = P1^1;
  12. sbit dir3  = P3^3;

  13. unsigned char data table[17]={
  14.         0x3f,0x06,0x5b,0x4f,
  15.         0x66,0x6d,0x7d,0x07,
  16.         0x7f,0x6f,0x77,0x7c,
  17.         0x39,0x5e,0x79,0x71,0x00};

  18. void LED_dula(unsigned char dat)
  19. {
  20.         sega=dat   &0x01;
  21.         segb=dat>>1&0x01;
  22.         segc=dat>>2&0x01;
  23.         segd=dat>>3&0x01;
  24.         sege=dat>>4&0x01;
  25.         segf=dat>>5&0x01;
  26.         segg=dat>>6&0x01;
  27.         segdp=dat>>7&0x01;
  28. }

  29. void LED_wela(unsigned char dat)
  30. {
  31.         dir1=dat   &0x01;
  32.         dir2=dat>>1&0x01;
  33.         dir3=dat>>2&0x01;
  34. //        dir4=dat>>3&0x01;
  35. }

  36. void Delay_ms(unsigned int t)
  37. {
  38.         unsigned int i,j;
  39.         for(i=t;i>0;i--)
  40.                 for(j=120;j>0;j--);
  41. }

  42. void main()
  43. {
  44.         unsigned int i,j,k;
  45.         while (1)
  46.         {
  47.                 LED_wela(0xff);                        //位消隱
  48.                 LED_dula(table[i]);                //傳段碼
  49.                 LED_wela(~(0x01<<i));        //傳位碼
  50.                 i=++i%3;                                                //位循環(huán)計(jì)數(shù)
  51.                 if(++j>=1000)                                //移動(dòng)顯示
  52.                 {
  53.                         j=0;
  54.                         table[16]=table[0];
  55.                         for(k=0;k<16;k++)
  56.                                 table[k]=table[k+1];
  57.                 }       
  58.                 Delay_ms(1);                        //控制主循環(huán)周期
  59.         }
  60. }
復(fù)制代碼
回復(fù)

使用道具 舉報(bào)

ID:1112147 發(fā)表于 2024-3-9 09:54 | 顯示全部樓層
oid display_num(unsigned char n)
{
        unsigned char temp;
        temp = Tab[n];
        sega = temp & (0x01<<0);
        segb = temp & (0x01<<1);
        segc = temp & (0x01<<2);
        segd = temp & (0x01<<3);
        sege = temp & (0x01<<4);
        segf = temp & (0x01<<5);
        segg = temp & (0x01<<6);
}
消影這樣可以嗎?單個(gè)能顯示對(duì),三位一起顯示就錯(cuò)
void xiao_ying(void)
{
        sega = 0;
        segb = 0;
        segc = 0;
        segd = 0;
        sege = 0;
        segf = 0;
        segg = 0;
}
void display_vvalue(unsigned char adc_value)
{
        unsigned char ge,shi,bai;
        ge  = adc_value % 10 ;
  shi = adc_value % 100 / 10;
  bai = adc_value / 100 ;
       
       
        display_num(ge);//送段碼 個(gè)位
        dir1 = 0;//送位碼
        delay_ms(3);//延時(shí)
        xiao_ying();//消影
       
       
        display_num(shi);//送段碼 十位
        dir2 = 0;//送位碼
        delay_ms(1);//延時(shí)
        xiao_ying();//消影

       
        display_num(bai);//送段碼 百位
        dir3 = 0;//送位碼
        delay_ms(1);//延時(shí)
  xiao_ying(); //消影
}
回復(fù)

使用道具 舉報(bào)

ID:1112147 發(fā)表于 2024-3-9 10:57 | 顯示全部樓層
wulin 發(fā)表于 2024-3-9 07:51
任意端口組合驅(qū)動(dòng)數(shù)碼管

if(++j>=1000)                                //移動(dòng)顯示
                {
                        j=0;
                        table[16]=table[0];
                        for(k=0;k<16;k++)
                                table[k]=table[k+1];
                }      
                Delay_ms(1);                        //控制主循環(huán)周期
        }
大佬其他的都能看懂,就這一段看不懂
回復(fù)

使用道具 舉報(bào)

ID:41656 發(fā)表于 2024-3-9 11:43 | 顯示全部樓層
自己寫個(gè)函數(shù)把你編碼的數(shù)據(jù)的每個(gè)位對(duì)應(yīng)到各個(gè)IO就好了,處理速度沒問題的放心搞
回復(fù)

使用道具 舉報(bào)

ID:1109793 發(fā)表于 2024-3-9 13:42 | 顯示全部樓層
lqzd 發(fā)表于 2024-3-9 10:57
if(++j>=1000)                                //移動(dòng)顯示
                {
                       ...

每次主循環(huán)把顯示內(nèi)容向左循環(huán)移動(dòng)一個(gè)位置,總工的代碼風(fēng)格非常間接高效。
比如本次循環(huán)顯示123,下次顯示234,大概是這樣的。
回復(fù)

使用道具 舉報(bào)

ID:1109793 發(fā)表于 2024-3-9 13:43 | 顯示全部樓層
lqzd 發(fā)表于 2024-3-9 10:57
if(++j>=1000)                                //移動(dòng)顯示
                {
                       ...

不對(duì),是每1000次循環(huán)移動(dòng)一次
回復(fù)

使用道具 舉報(bào)

ID:213173 發(fā)表于 2024-3-9 17:34 | 顯示全部樓層
lqzd 發(fā)表于 2024-3-9 10:57
if(++j>=1000)                                //移動(dòng)顯示
                {
                       ...

xiaobendan001的解釋是正確的,此段代碼目的就是把0~F按一定時(shí)間間隔循環(huán)顯示。檢驗(yàn)一下數(shù)碼管字符有無差錯(cuò)。
回復(fù)

使用道具 舉報(bào)

ID:883242 發(fā)表于 2024-3-9 19:41 | 顯示全部樓層
wulin 發(fā)表于 2024-3-9 07:51
任意端口組合驅(qū)動(dòng)數(shù)碼管

嚴(yán)重懷疑segd=dat>>3&0x01;這種寫法執(zhí)行效率極其低下,建議讓編譯器輸出匯編代碼檢查一下。

寫成segd=dat&(0x01<<3);應(yīng)該更好一些,這種寫法的移位是編譯時(shí)進(jìn)行的,單片機(jī)沒有移位操作,segd根據(jù)等號(hào)右邊的值是0或者非零來置0或1。

我沒有c51只是個(gè)建議。
回復(fù)

使用道具 舉報(bào)

ID:883242 發(fā)表于 2024-3-9 20:25 | 顯示全部樓層
wulin 發(fā)表于 2024-3-9 07:51
任意端口組合驅(qū)動(dòng)數(shù)碼管

我用了DOS下面Franklin C51 V3.2(就是Keil在美國銷售代理的名字)測試了一下,果然如果我所料,你的代碼執(zhí)行效率非常差。生成出來的匯編代碼對(duì)比如下:

  1. ; void LED_dula(unsigned char dat)

  2.         RSEG  ?PR?_LED_dula?1801
  3.         USING        0
  4. _LED_dula:
  5.         MOV          dat?00,R7
  6.                         ; SOURCE LINE # 32
  7. ; {
  8.                         ; SOURCE LINE # 33
  9. ;         sega=dat   &0x01;
  10.                         ; SOURCE LINE # 34
  11.         MOV          A,dat?00
  12.         RRC          A
  13.         MOV          sega,C
  14. ;         segb=dat>>1&0x01;
  15.                         ; SOURCE LINE # 35
  16.         MOV          A,dat?00
  17.         CLR          C
  18.         RRC          A
  19.         RRC          A
  20.         MOV          segb,C
  21. ;         segc=dat>>2&0x01;
  22.                         ; SOURCE LINE # 36
  23.         MOV          A,dat?00
  24.         RRC          A
  25.         RRC          A
  26.         ANL          A,#03FH
  27.         RRC          A
  28.         MOV          segc,C
  29. ;         segd=dat>>3&0x01;
  30.                         ; SOURCE LINE # 37
  31.         MOV          A,dat?00
  32.         RRC          A
  33.         RRC          A
  34.         RRC          A
  35.         ANL          A,#01FH
  36.         RRC          A
  37.         MOV          segd,C
  38. ;         sege=dat>>4&0x01;
  39.                         ; SOURCE LINE # 38
  40.         MOV          A,dat?00
  41.         SWAP         A
  42.         ANL          A,#0FH
  43.         RRC          A
  44.         MOV          sege,C
  45. ;         segf=dat>>5&0x01;
  46.                         ; SOURCE LINE # 39
  47.         MOV          A,dat?00
  48.         SWAP         A
  49.         RRC          A
  50.         ANL          A,#07H
  51.         RRC          A
  52.         MOV          segf,C
  53. ;         segg=dat>>6&0x01;
  54.                         ; SOURCE LINE # 40
  55.         MOV          A,dat?00
  56.         SWAP         A
  57.         RRC          A
  58.         RRC          A
  59.         ANL          A,#03H
  60.         RRC          A
  61.         MOV          segg,C
  62. ;         segdp=dat>>7&0x01;
  63.                         ; SOURCE LINE # 41
  64.         MOV          A,dat?00
  65.         SWAP         A
  66.         RRC          A
  67.         RRC          A
  68.         RRC          A
  69.         ANL          A,#01H
  70.         RRC          A
  71.         MOV          segdp,C
  72. ; }
  73.                         ; SOURCE LINE # 42
  74.         RET         
  75. ; END OF _LED_dula

  76. ; void LED_dula1(unsigned char dat)

  77.         RSEG  ?PR?_LED_dula1?1801
  78.         USING        0
  79. _LED_dula1:
  80.         MOV          dat?10,R7
  81.                         ; SOURCE LINE # 43
  82. ; {
  83.                         ; SOURCE LINE # 44
  84. ;         sega=dat   &0x01;
  85.                         ; SOURCE LINE # 45
  86.         MOV          A,dat?10
  87.         RRC          A
  88.         MOV          sega,C
  89. ;         segb=dat&0x01<<1;
  90.                         ; SOURCE LINE # 46
  91.         MOV          A,dat?10
  92.         MOV          C,ACC.1
  93.         MOV          segb,C
  94. ;         segc=dat&0x01<<2;
  95.                         ; SOURCE LINE # 47
  96.         MOV          C,ACC.2
  97.         MOV          segc,C
  98. ;         segd=dat&0x01<<3;
  99.                         ; SOURCE LINE # 48
  100.         MOV          C,ACC.3
  101.         MOV          segd,C
  102. ;         sege=dat&0x01<<4;
  103.                         ; SOURCE LINE # 49
  104.         MOV          C,ACC.4
  105.         MOV          sege,C
  106. ;         segf=dat&0x01<<5;
  107.                         ; SOURCE LINE # 50
  108.         MOV          C,ACC.5
  109.         MOV          segf,C
  110. ;         segg=dat&0x01<<6;
  111.                         ; SOURCE LINE # 51
  112.         MOV          C,ACC.6
  113.         MOV          segg,C
  114. ;         segdp=dat&0x01<<7;
  115.                         ; SOURCE LINE # 52
  116.         RLC          A
  117.         MOV          segdp,C
  118. ; }
  119.                         ; SOURCE LINE # 53
  120.         RET         
  121. ; END OF _LED_dula1
復(fù)制代碼


還有更好的寫法:
  1. unsigned char bdata tmp;
  2. sbit tmp0=tmp^0;
  3. sbit tmp1=tmp^1;
  4. sbit tmp2=tmp^2;
  5. sbit tmp3=tmp^3;
  6. sbit tmp4=tmp^4;
  7. sbit tmp5=tmp^5;
  8. sbit tmp6=tmp^6;
  9. sbit tmp7=tmp^7;

  10. void LED_dula2(unsigned char dat)
  11. {
  12.         tmp=dat;
  13.         sega=tmp0;
  14.         segb=tmp1;
  15.         segc=tmp2;
  16.         segd=tmp3;
  17.         sege=tmp4;
  18.         segf=tmp5;
  19.         segg=tmp6;
  20.         segdp=tmp7;
  21. }
復(fù)制代碼


最終生成的匯編就更加簡潔了:
  1. ; void LED_dula2(unsigned char dat)

  2.         RSEG  ?PR?_LED_dula2?1801
  3.         USING        0
  4. _LED_dula2:
  5.         MOV          dat?20,R7
  6.                         ; SOURCE LINE # 54
  7. ; {
  8.                         ; SOURCE LINE # 55
  9. ;         tmp=dat;
  10.                         ; SOURCE LINE # 56
  11.         MOV          tmp,dat?20
  12. ;         sega=tmp0;
  13.                         ; SOURCE LINE # 57
  14.         MOV          C,tmp0
  15.         MOV          sega,C
  16. ;         segb=tmp1;
  17.                         ; SOURCE LINE # 58
  18.         MOV          C,tmp1
  19.         MOV          segb,C
  20. ;         segc=tmp2;
  21.                         ; SOURCE LINE # 59
  22.         MOV          C,tmp2
  23.         MOV          segc,C
  24. ;         segd=tmp3;
  25.                         ; SOURCE LINE # 60
  26.         MOV          C,tmp3
  27.         MOV          segd,C
  28. ;         sege=tmp4;
  29.                         ; SOURCE LINE # 61
  30.         MOV          C,tmp4
  31.         MOV          sege,C
  32. ;         segf=tmp5;
  33.                         ; SOURCE LINE # 62
  34.         MOV          C,tmp5
  35.         MOV          segf,C
  36. ;         segg=tmp6;
  37.                         ; SOURCE LINE # 63
  38.         MOV          C,tmp6
  39.         MOV          segg,C
  40. ;         segdp=tmp7;
  41.                         ; SOURCE LINE # 64
  42.         MOV          C,tmp7
  43.         MOV          segdp,C
  44. ; }
  45.                         ; SOURCE LINE # 65
  46.         RET         
  47. ; END OF _LED_dula2
復(fù)制代碼
回復(fù)

使用道具 舉報(bào)

ID:213173 發(fā)表于 2024-3-9 21:28 | 顯示全部樓層
Hephaestus 發(fā)表于 2024-3-9 19:41
嚴(yán)重懷疑segd=dat>>3&0x01;這種寫法執(zhí)行效率極其低下,建議讓編譯器輸出匯編代碼檢查一下。

寫成segd= ...

對(duì)于初學(xué)者而言,易懂比效率更適宜。何況在相同環(huán)境原代碼執(zhí)行時(shí)間35us,改后的代碼執(zhí)行時(shí)間64us,效率不升反降。
回復(fù)

使用道具 舉報(bào)

ID:1034262 發(fā)表于 2024-3-9 22:40 | 顯示全部樓層
51單片機(jī)有一個(gè)很大的好處:位操作。
回復(fù)

使用道具 舉報(bào)

ID:883242 發(fā)表于 2024-3-10 14:47 | 顯示全部樓層
wulin 發(fā)表于 2024-3-9 21:28
對(duì)于初學(xué)者而言,易懂比效率更適宜。何況在相同環(huán)境原代碼執(zhí)行時(shí)間35us,改后的代碼執(zhí)行時(shí)間64us,效率不 ...

算了吧你,你的代碼每行要產(chǎn)生超過5條指令,我改了以后只有2條。
回復(fù)

使用道具 舉報(bào)

ID:1109793 發(fā)表于 2024-3-10 15:58 | 顯示全部樓層
兩位總工各有千秋
回復(fù)

使用道具 舉報(bào)

ID:213173 發(fā)表于 2024-3-10 20:49 | 顯示全部樓層
Hephaestus 發(fā)表于 2024-3-10 14:47
算了吧你,你的代碼每行要產(chǎn)生超過5條指令,我改了以后只有2條。

你是對(duì)的,我弄反了。原代碼執(zhí)行時(shí)間64us,改后的代碼執(zhí)行時(shí)間35us.
回復(fù)

使用道具 舉報(bào)

ID:1109793 發(fā)表于 2024-3-11 07:50 | 顯示全部樓層
unsigned char bdata tmp;
sbit tmp0=tmp^0;
sbit tmp1=tmp^1;
sbit tmp2=tmp^2;
sbit tmp3=tmp^3;
sbit tmp4=tmp^4;
sbit tmp5=tmp^5;
sbit tmp6=tmp^6;
sbit tmp7=tmp^7;

void LED_dula2(unsigned char dat)
{
        tmp=dat;
        sega=tmp0;
        segb=tmp1;
        segc=tmp2;
        segd=tmp3;
        sege=tmp4;
        segf=tmp5;
        segg=tmp6;
        segdp=tmp7;
}
sbit還可以這樣用啊?漲姿勢了這回
回復(fù)

使用道具 舉報(bào)

ID:1064915 發(fā)表于 2024-3-11 09:16 | 顯示全部樓層
dula、wela,這是什么詞的縮寫
回復(fù)

使用道具 舉報(bào)

ID:1108581 發(fā)表于 2024-3-11 10:30 | 顯示全部樓層
牛逼牛逼,看到大佬之間的對(duì)話精彩之極,感嘆我等道友何時(shí)能達(dá)到這種級(jí)別
回復(fù)

使用道具 舉報(bào)

ID:883242 發(fā)表于 2024-3-11 13:27 | 顯示全部樓層
xiaobendan001 發(fā)表于 2024-3-11 07:50
unsigned char bdata tmp;
sbit tmp0=tmp^0;
sbit tmp1=tmp^1;

關(guān)鍵在于bdata
回復(fù)

使用道具 舉報(bào)

ID:1112147 發(fā)表于 2024-3-12 09:27 | 顯示全部樓層
xiaobendan001 發(fā)表于 2024-3-11 07:50
unsigned char bdata tmp;
sbit tmp0=tmp^0;
sbit tmp1=tmp^1;

你能看明白嗎?能不能給我解釋一下,怎么能這樣寫的。
unsigned char bdata tmp;
sbit tmp0=tmp^0;
sbit tmp1=tmp^1;
sbit tmp2=tmp^2;
sbit tmp3=tmp^3;
sbit tmp4=tmp^4;
sbit tmp5=tmp^5;
sbit tmp6=tmp^6;
sbit tmp7=tmp^7;

void LED_dula2(unsigned char dat)
{
        tmp=dat;
        sega=tmp0;
        segb=tmp1;
        segc=tmp2;
        segd=tmp3;
        sege=tmp4;
        segf=tmp5;
        segg=tmp6;
        segdp=tmp7;
}
回復(fù)

使用道具 舉報(bào)

ID:883242 發(fā)表于 2024-3-12 14:48 | 顯示全部樓層
lqzd 發(fā)表于 2024-3-12 09:27
你能看明白嗎?能不能給我解釋一下,怎么能這樣寫的。
unsigned char bdata tmp;
sbit tmp0=tmp^0;

你查下8051的RAM地址20h~2fh有和與眾不同之處就知道了。
回復(fù)

使用道具 舉報(bào)

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

本版積分規(guī)則

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

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

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