找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

實現(xiàn)按鍵次數(shù)在數(shù)碼管上顯示并通過串口發(fā)送到PC端

[復(fù)制鏈接]
ID:669905 發(fā)表于 2019-12-21 16:56 | 顯示全部樓層 |閱讀模式
下面的代碼只實現(xiàn)了按鍵次數(shù)在數(shù)碼管上顯示,但是無論我怎么試,也沒有辦法把數(shù)碼管的數(shù)據(jù)發(fā)送至串口助手,求大佬指點。
#include<reg52.h>
#include<stdlib.h>
#define uint unsigned long
#define uchar unsigned char

sbit led1 = P2^0;
sbit led2 = P2^1;
sbit led3 = P2^2;
sbit led4 = P2^3;

sbit k1 = P3^5;
sbit k2 = P3^4;
sbit k3 = P3^3;
sbit k4 = P3^2;
uchar code table[]={0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90};

uint num;

void delay(unsigned int i)
{
       
        while(i--);
  
  
}
void delayms(unsigned int i)
{
for(i=124;i>0;i--);  //Ñóê±124*8+10=1002us
}


void display(unsigned long num)
{
       
                led1=0;               
                P0=table[(num%10000)/1000];       
                delayms(1);               
                P0=0XFF;               
                led1=1;               

                led2=0;               
                P0=table[(num%1000)/100];       
                delayms(1);               
                P0=0XFF;               
                led2=1;

                led3=0;               
                P0=table[(num%100)/10];       
                delayms(1);               
                P0=0XFF;               
                led3=1;

                led4=0;               
                P0=table[num%10];       
                delayms(1);               
                P0=0XFF;               
                led4=1;
               
}



void main()
       
{
       
       



        num=0;       

        while(1)
        {
       
                SBUF=num;
                       
                display(num);
                       
                       
                if(k1==0)
                {
                       
                       
                        delayms(50);
                        if(k1==0)
                        {
                               
                                num++;
                        }
                       
                        while(!k1);
                        delayms(50);
                        while(!k1);
                               
                }
                       
        }
       
}

相關(guān)帖子

回復(fù)

使用道具 舉報

ID:617449 發(fā)表于 2019-12-22 09:07 | 顯示全部樓層
你好!
1、缺少串口初始化程序
2、缺少串口發(fā)送程序
3、增加上述程序后再試
回復(fù)

使用道具 舉報

ID:638320 發(fā)表于 2019-12-22 10:27 | 顯示全部樓層
要用一個發(fā)送標志位TI來判斷,讓它發(fā)送完成才執(zhí)行下面的程序,即SBFU=number;
while(!TI);等待發(fā)送完成
TI=0;清標志位
回復(fù)

使用道具 舉報

ID:213173 發(fā)表于 2019-12-22 11:35 | 顯示全部樓層
要開定時器1做波特率發(fā)生器,按鍵后才發(fā)送,發(fā)送語句要完整。
  1. #include<reg52.h>
  2. #include<stdlib.h>
  3. #define uint unsigned long
  4. #define uchar unsigned char

  5. sbit led1 = P2^0;
  6. sbit led2 = P2^1;
  7. sbit led3 = P2^2;
  8. sbit led4 = P2^3;

  9. sbit k1 = P3^5;
  10. sbit k2 = P3^4;
  11. sbit k3 = P3^3;
  12. sbit k4 = P3^2;
  13. uchar code table[]={0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90};

  14. uchar key;

  15. void delayms(unsigned int i)
  16. {
  17.         unsigned int j;
  18.         while(i--)
  19.         {
  20.                 for(j=124;j>0;j--);
  21.         }
  22. }

  23. void display(uchar num)
  24. {       
  25.         led1=0;               
  26.         P0=table[(num%10000)/1000];        
  27.         delayms(1);               
  28.         P0=0XFF;
  29.         led1=1;               
  30.        
  31.         led2=0;               
  32.         P0=table[(num%1000)/100];        
  33.         delayms(1);               
  34.         P0=0XFF;               
  35.         led2=1;
  36.        
  37.         led3=0;               
  38.         P0=table[(num%100)/10];        
  39.         delayms(1);               
  40.         P0=0XFF;               
  41.         led3=1;
  42.        
  43.         led4=0;               
  44.         P0=table[num%10];        
  45.         delayms(1);               
  46.         P0=0XFF;               
  47.         led4=1;       
  48. }
  49. void main()        
  50. {//初始化定時器(波特率9600)
  51.         TMOD=0x20;
  52.         TH1=0xfd;
  53.         TH1=0xfd;
  54.         TR1=1;
  55.         REN=1;
  56.         SM0=0;
  57.         SM1=1;
  58. //初始鍵值
  59.         key=0;        
  60.         while(1)
  61.         {
  62.                 if(k1==0)
  63.                 {
  64.                         delayms(10);
  65.                         if(k1==0)
  66.                         {
  67.                                 if(key<255)
  68.                                         key++;
  69.                         }
  70.                         while(!k1);//等待松手
  71.                         SBUF=key;//鍵值發(fā)送到串口
  72.                         while(!TI);//等待發(fā)送完成
  73.                         TI=0;//清標志位
  74.                 }
  75.                 display(key);
  76.         }
  77. }
復(fù)制代碼
回復(fù)

使用道具 舉報

ID:164602 發(fā)表于 2019-12-22 15:53 | 顯示全部樓層
wulin 發(fā)表于 2019-12-22 11:35
要開定時器1做波特率發(fā)生器,按鍵后才發(fā)送,發(fā)送語句要完整。

wulin:看看我這個程序,后面有記錄。我解決不了。(用的是HC6800-ES-V2.0的板子)

#include<reg51.h>

#define GPIO_DIG P0//數(shù)碼管顯示口

sbit LSA=P2^2;//138譯碼器
sbit LSB=P2^3;
sbit LSC=P2^4;

sbit k1=P3^1;//按鍵1

unsigned char code DIG_CODE[16]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,
0x77,0x7c,0x39,0x5e,0x79,0x71};//數(shù)碼管顯示編碼
unsigned char DD[2]={0x3f,0x00};//數(shù)碼管顯示緩存
unsigned char D0,D1;//串口發(fā)送緩存

void Delay10ms(unsigned int c)
{
    unsigned char a,b;
    for(c;c>0;c--)
        for(b=38;b>0;b--)
            for(a=130;a>0;a--);
}

void UsartConfiguration()//設(shè)置串口
{
        SCON=0X50;//串口通信設(shè)置為工作方式1
        TMOD=0X20;//設(shè)置定時器1工作方式2
        PCON=0X80;//波特率加倍
        TH1=0XF3;//計數(shù)器初始值設(shè)置,注意波特率是4800的
        TL1=0XF3;
        TR1=1;//打開計數(shù)器
}

void DigDisplay()//數(shù)碼管顯示函數(shù)
{
        unsigned char i;
        unsigned char j;
        for(i=0;i<2;i++)//只有2個數(shù)碼管
        {
                switch(i)         //位選,選擇點亮的數(shù)碼管,
                {
                        case(0):
                                LSA=0;LSB=0;LSC=0; break;//顯示第0位
                        case(1):
                                LSA=1;LSB=0;LSC=0; break;//顯示第1位
                }
                GPIO_DIG=DD;//發(fā)送段碼
                j=10;                                                 //掃描間隔時間設(shè)定
                while(j--);       
                GPIO_DIG=0x00;//消隱
        }
}

void CKFS (void)//串口發(fā)送
{
        SBUF = D1;
        while (!TI);
        TI = 0;
        SBUF = D0;
        while (!TI);
        TI = 0;
        SBUF = ' ';
        while (!TI);
        TI = 0;
}

void main(void)
{
        unsigned char i,j;//i為松手消抖計數(shù)變量;j為按鍵計數(shù);
        UsartConfiguration();
        while(1)
        {       
                if(k1==0)//掃描鍵盤k1
                {
                        Delay10ms(1);//按下消抖
                        if(k1==0)
                        {
                                j++;
                                if (j>99)
                                {
                                        j=0;
                                }
                                if (j<10)
                                {
                                        DD[0]=DIG_CODE[j];
                                        DD[1]=0x00;
                                        D0 = (0x30+j);
                                        D1 = 0x00;
                                }
                                else
                                {
                                        DD[1]=DIG_CODE[j/10];
                                        DD[0]=DIG_CODE[j%10];
                                        D0 = (0x30+(j%10));
                                        D1 = (0x30+(j/10));
                                }
                            while((i<50)&&(k1==0))//松鍵消抖
                            {
                                    Delay10ms(1);
                                    i++;
                            }
                            i=0;
                        }
                        CKFS();
                }
                DigDisplay();
        }               
}


/*
編后感:
此程序是通過數(shù)碼管顯示按鍵次數(shù)(99以內(nèi)),并且將次數(shù)通過串口發(fā)送到電腦。
但串口接收常常有亂碼!
通過調(diào)試,發(fā)現(xiàn)這樣的現(xiàn)象:
第一:單獨的數(shù)碼管顯示沒有問題;單獨的串口發(fā)送也沒有問題;
第二:個人感覺,兩功能組合后,接收出現(xiàn)問題,主要是按鍵的消抖延時,影響到了串口工作的時序,
比如:串口發(fā)送的語句單獨出現(xiàn)在按鍵程序中,串口根本接收不到有效數(shù)據(jù),把它們集中到子函數(shù)中,
就可以接收到有效數(shù)據(jù)了。
第三:亂碼問題沒有根本解決,有部分數(shù)據(jù)沒有亂碼。根本原因沒有找到,就無法解決。
*/


回復(fù)

使用道具 舉報

ID:213173 發(fā)表于 2019-12-22 23:39 | 顯示全部樓層
HC6800-ES-V2.0 發(fā)表于 2019-12-22 15:53
wulin:看看我這個程序,后面有記錄。我解決不了。(用的是HC6800-ES-V2.0的板子)

#include

在此例程序中,按鍵與串口共用P3.1口,按鍵松手不穩(wěn),簧片抖動是產(chǎn)生亂碼的主要原因。在有些開發(fā)板由于功能交叉會產(chǎn)生這樣難題。寫個程序解決一下學(xué)習(xí)問題無所謂。在實際應(yīng)用電路中絕不可如此設(shè)計。給你把程序修改了一下,你試試。
  1. #include<reg51.h>

  2. #define GPIO_DIG P0//數(shù)碼管顯示口

  3. sbit LSA=P2^2;//138譯碼器
  4. sbit LSB=P2^3;
  5. sbit LSC=P2^4;

  6. sbit k1=P3^1;//按鍵1

  7. unsigned char code DIG_CODE[16]={//數(shù)碼管顯示編碼
  8. 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
  9. 0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
  10. unsigned char DD[]="00\n";//串口發(fā)送緩存
  11. //unsigned char D0,D1;//串口發(fā)送緩存
  12. unsigned char key=0;                //鍵值
  13. bit mark=0;//允許發(fā)送標志
  14. void Delayms(unsigned int c)
  15. {
  16.         unsigned int a;
  17.         for(c;c>0;c--)
  18.                 for(a=130;a>0;a--);
  19. }

  20. void UsartConfiguration()//設(shè)置串口
  21. {
  22.         SCON=0X50;//串口通信設(shè)置為工作方式1
  23.         TMOD=0X20;//設(shè)置定時器1工作方式2
  24.         PCON=0X80;//波特率加倍
  25.         TH1=0XF3;//計數(shù)器初始值設(shè)置,注意波特率是4800的
  26.         TL1=0XF3;
  27.         TR1=0;//關(guān)計數(shù)器
  28. }

  29. void DigDisplay()//數(shù)碼管顯示函數(shù)
  30. {
  31.         static bit i=0;
  32.         static unsigned int j=0;
  33.         if(++j>=100)
  34.         {
  35.                 j=0;
  36.                 GPIO_DIG=0x00;//消隱
  37.                 if(i){LSA=0;LSB=0;LSC=0;GPIO_DIG=DIG_CODE[key/10];}//顯示十位       
  38.                 else {LSA=1;LSB=0;LSC=0;GPIO_DIG=DIG_CODE[key%10];}//顯示個位
  39.                 i=~i;
  40.         }
  41. }
  42. void SendOneByte(unsigned char c)
  43. {
  44.     SBUF = c;                //發(fā)送數(shù)據(jù)
  45.     while(!TI);        //等待發(fā)送完成
  46.     TI = 0;                        //發(fā)送中斷請求標志位清0
  47. }
  48. void CKFS()//串口發(fā)送
  49. {
  50.         static unsigned int i=0,j;
  51.         if(mark==1)
  52.         {
  53.                 if(++i>=1000)//計數(shù)延時
  54.                 {
  55.                         TR1=1;//開T1
  56.                         i=200;
  57.                     while(i--);//小延時
  58.                         for(j=0;j<3;j++)//發(fā)送兩個字符+換行符
  59.                                 SendOneByte(DD[j]);
  60.                         TR1=0;//關(guān)T1
  61.                         mark=0;//允許發(fā)送標志清0
  62.                 }
  63.         }
  64. }

  65. void main(void)
  66. {
  67.         unsigned char count=0;        //消抖計數(shù)
  68.         bit flag=0;                                        //按鍵標志
  69.         UsartConfiguration();
  70.         Delayms(100);
  71.         while(1)
  72.         {        
  73.                 if(k1==0)//掃描鍵盤k1
  74.                 {
  75.                         if(++count>=100 && flag==0)
  76.                         {
  77.                                 flag=1;
  78.                                 key++;
  79.                                 if(key>99)
  80.                                         key=0;
  81.                                 if(key<10)
  82.                                 {
  83.                                         DD[0]=' ';
  84.                                         DD[1]=key%10+'0';
  85.                                 }
  86.                                 else
  87.                                 {
  88.                                         DD[0]=key/10+'0';
  89.                                         DD[1]=key%10+'0';
  90.                                 }
  91.                         }
  92.                 }
  93.                 else
  94.                 {
  95.                         if(flag)
  96.                         {
  97.                                 flag=0;
  98.                                 mark=1;//允許發(fā)送
  99.                         }
  100.                         count=0;
  101.                 }
  102.                 CKFS();
  103.                 DigDisplay();
  104.         }               
  105. }
復(fù)制代碼
回復(fù)

使用道具 舉報

ID:164602 發(fā)表于 2019-12-23 08:39 | 顯示全部樓層
wulin 發(fā)表于 2019-12-22 23:39
在此例程序中,按鍵與串口共用P3.1口,按鍵松手不穩(wěn),簧片抖動是產(chǎn)生亂碼的主要原因。在有些開發(fā)板由于功 ...

非常感謝你。程序已經(jīng)驗證。你的編程方法,也給我很大的提示!。。。
是你指出了問題的根源,所以,我更改了按鍵,用k4鍵,占用P33口,就不沖突了,一切正常。
再次謝謝!
回復(fù)

使用道具 舉報

ID:670959 發(fā)表于 2019-12-23 09:45 | 顯示全部樓層
wulin:看看我這個程序,后面有記錄。我解決不了。(用的是HC6800-ES-V2.0的板子)

#include<reg51.h>

#define GPIO_DIG P0//數(shù)碼管顯示口

sbit LSA=P2^2;//138譯碼器
sbit LSB=P2^3;
sbit LSC=P2^4;

sbit k1=P3^1;//按鍵1

unsigned char code DIG_CODE[16]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,
0x77,0x7c,0x39,0x5e,0x79,0x71};//數(shù)碼管顯示編碼
unsigned char DD[2]={0x3f,0x00};//數(shù)碼管顯示緩存
unsigned char D0,D1;//串口發(fā)送緩存

void Delay10ms(unsigned int c)
{
    unsigned char a,b;
    for(c;c>0;c--)
        for(b=38;b>0;b--)
            for(a=130;a>0;a--);
}

void UsartConfiguration()//設(shè)置串口
{
        SCON=0X50;//串口通信設(shè)置為工作方式1
        TMOD=0X20;//設(shè)置定時器1工作方式2
        PCON=0X80;//波特率加倍
        TH1=0XF3;//計數(shù)器初始值設(shè)置,注意波特率是4800的
        TL1=0XF3;
        TR1=1;//打開計數(shù)器
}

void DigDisplay()//數(shù)碼管顯示函數(shù)
{
        unsigned char i;
        unsigned char j;
        for(i=0;i<2;i++)//只有2個數(shù)碼管
        {
                switch(i)         //位選,選擇點亮的數(shù)碼管,
                {
                        case(0):
                                LSA=0;LSB=0;LSC=0; break;//顯示第0位
                        case(1):
                                LSA=1;LSB=0;LSC=0; break;//顯示第1位
                }
                GPIO_DIG=DD;//發(fā)送段碼
                j=10;                                                 //掃描間隔時間設(shè)定
                while(j--);        
                GPIO_DIG=0x00;//消隱
        }
}

void CKFS (void)//串口發(fā)送
{
        SBUF = D1;
        while (!TI);
        TI = 0;
        SBUF = D0;
        while (!TI);
        TI = 0;
        SBUF = ' ';
        while (!TI);
        TI = 0;
}

void main(void)
{
        unsigned char i,j;//i為松手消抖計數(shù)變量;j為按鍵計數(shù);
        UsartConfiguration();
        while(1)
        {        
                if(k1==0)//掃描鍵盤k1
                {
                        Delay10ms(1);//按下消抖
                        if(k1==0)
                        {
                                j++;
                                if (j>99)
                                {
                                        j=0;
                                }
                                if (j<10)
                                {
                                        DD[0]=DIG_CODE[j];
                                        DD[1]=0x00;
                                        D0 = (0x30+j);
                                        D1 = 0x00;
                                }
                                else
                                {
                                        DD[1]=DIG_CODE[j/10];
                                        DD[0]=DIG_CODE[j%10];
                                        D0 = (0x30+(j%10));
                                        D1 = (0x30+(j/10));
                                }
                            while((i<50)&&(k1==0))//松鍵消抖
                            {
                                    Delay10ms(1);
                                    i++;
                            }
                            i=0;
                        }
                        CKFS();
                }
                DigDisplay();
        }               
}


/*
編后感:
此程序是通過數(shù)碼管顯示按鍵次數(shù)(99以內(nèi)),并且將次數(shù)通過串口發(fā)送到電腦。
但串口接收常常有亂碼!
通過調(diào)試,發(fā)現(xiàn)這樣的現(xiàn)象:
第一:單獨的數(shù)碼管顯示沒有問題;單獨的串口發(fā)送也沒有問題;
第二:個人感覺,兩功能組合后,接收出現(xiàn)問題,主要是按鍵的消抖延時,影響到了串口工作的時序,
比如:串口發(fā)送的語句單獨出現(xiàn)在按鍵程序中,串口根本接收不到有效數(shù)據(jù),把它們集中到子函數(shù)中,
就可以接收到有效數(shù)據(jù)了。
第三:亂碼問題沒有根本解決,有部分數(shù)據(jù)沒有亂碼。根本原因沒有找到,就無法解決。
*/
回復(fù)

使用道具 舉報

ID:669905 發(fā)表于 2019-12-28 10:18 | 顯示全部樓層
wulin 發(fā)表于 2019-12-22 11:35
要開定時器1做波特率發(fā)生器,按鍵后才發(fā)送,發(fā)送語句要完整。

你好,我試了您給的代碼,但是在串口助手不是1234 這樣的按鍵次數(shù),而是81 82 83 84 85 86 87 80 81 8A 83 84 8D 8E 8F 90 91 82 83 8C 85 86 97 88 89 8A 8F 8C 8D這樣的數(shù)
回復(fù)

使用道具 舉報

ID:213173 發(fā)表于 2019-12-28 16:48 | 顯示全部樓層
tomorrow101 發(fā)表于 2019-12-28 10:18
你好,我試了您給的代碼,但是在串口助手不是1234 這樣的按鍵次數(shù),而是81 82 83 84 85 86 87 80 81 8A 8 ...

可能是你的串口助手沒有調(diào)好。
無標題.jpg

回復(fù)

使用道具 舉報

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

本版積分規(guī)則

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

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

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