找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4500|回复: 7
收起左侧

如何用51单片机实现排序?

[复制链接]
ID:493416 发表于 2019-3-19 20:31 | 显示全部楼层 |阅读模式
要求:通过键盘任意输入8个数字,实时按照输入顺序依次从左到右在数码管上显示。


下面是我自己写的代码
#include <reg51.h>
#define uint unsigned int
#define uchar unsigned char
uint i,button,temp,num,j=0,n;
uchar code button_table[]={0xee,0xde,0xbe,0x7e,
                                 0xed,0xdd,0xbd,0x7d,
                                 0xeb,0xdb};
uchar table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
uchar address[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
void delay(n)              
{
        for(i=n;i>0;i--)
        ;
}
void delay2()
{for(n=50000;n>0;n--)
        ;
}
/*****************************************************************/
void main()
{
        while(1)
        {
                P3=0xf0;
                if(P3!=0xf0)
                {
                        delay(10000);
            if(P3!=0xf0)
                        {
                                temp=P3;
        P3=0x0f;               
              button=P3|temp;
                  for(i=0;i<10;i++)
                    {
                        if(button==button_table[ i])
                        {        num=i;break;}
                    }
                        P2=address[j];
            P0=table[num];
            delay2();
                  j++;
                if(j==8)
                 {j=0;}
            }
          }
        ;
}
}

但是这个只能实现显示当前按键所对应的数字,图上是我第三个按键按的6,用这种动态显示的数码管无法显示8个数啊,应该怎么办?求大佬解答一下,谢谢~



1.png
回复

使用道具 举报

ID:351395 发表于 2019-3-20 09:29 | 显示全部楼层
用数组,然后,全部独个比较,变换大小位置,几个循环后就好了。
回复

使用道具 举报

ID:437981 发表于 2019-3-20 13:50 | 显示全部楼层
把数据存在数组中,在进行“冒泡排序”,“快速排序”....
回复

使用道具 举报

ID:164602 发表于 2019-3-20 14:26 | 显示全部楼层
#include<reg51.h>

#define GPIO_DIG P0
#define GPIO_KEY P3

unsigned char code DIG_CODE[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,
0x77,0x7c,0x39,0x5e,0x79,0x71};

unsigned char KeyValue;

bit KeyState;

unsigned char DisplayData[8];

void Delay10ms();
void KeyDown();
void DigDisplay();

void main(void)
{
        unsigned char i;
        KeyState=0;
        while(1)
        {
                KeyDown();
                 if(KeyState==1)
                {
                        switch (i)
                        {
                                case (0):DisplayData[7]=DIG_CODE[KeyValue];break;
                                case (1):DisplayData[6]=DIG_CODE[KeyValue];break;
                                case (2):DisplayData[5]=DIG_CODE[KeyValue];break;
                                case (3):DisplayData[4]=DIG_CODE[KeyValue];break;
                                case (4):DisplayData[3]=DIG_CODE[KeyValue];break;
                                case (5):DisplayData[2]=DIG_CODE[KeyValue];break;
                                case (6):DisplayData[1]=DIG_CODE[KeyValue];break;
                                case (7):DisplayData[0]=DIG_CODE[KeyValue];break;
                        }                       
                        i++;
                        if (i==8)
                        {
                                i=0;
                        }
                        KeyState=0;
                }
                DigDisplay();
        }                               
}

void DigDisplay()
{
        unsigned char i,j;
        for(i=0;i<8;i++)
        {
                switch(i)
                {
                        case(0):
                                P2=0xfe; break;
                        case(1):
                                P2=0xfd; break;
                        case(2):
                                P2=0xfb; break;
                        case(3):
                                P2=0xf7; break;
                        case(4):
                                P2=0xef; break;
                        case(5):
                                P2=0xdf; break;
                        case(6):
                                P2=0xbf; break;
                        case(7):
                                P2=0x7f; break;
                }
                GPIO_DIG=DisplayData[i];
                j=10;
                while(j--);       
                GPIO_DIG=0x00;
        }
}

void KeyDown(void)
{
        unsigned char a=0;
        GPIO_KEY=0x0f;
        if(GPIO_KEY!=0x0f)
        {
                Delay10ms();
                if(GPIO_KEY!=0x0f)
                {
                        KeyState=1;
                        switch(GPIO_KEY)
                        {
                                case(0X07):        KeyValue=0;break;
                                case(0X0b):        KeyValue=1;break;
                                case(0X0d): KeyValue=2;break;
                                case(0X0e):        KeyValue=3;break;
                        }
                        GPIO_KEY=0Xf0;
                        Delay10ms();
                        switch(GPIO_KEY)
                        {
                                case(0X70):        KeyValue=KeyValue;break;
                                case(0Xb0):        KeyValue=KeyValue+4;break;
                                case(0Xd0): KeyValue=KeyValue+8;break;
                                case(0Xe0):        KeyValue=KeyValue+12;break;
                        }
                        while((a<200)&&(GPIO_KEY!=0xf0))
                        {
                                Delay10ms();
                                a++;
                        }
                        a=0;
                }
        }
}

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

使用道具 举报

ID:426861 发表于 2019-3-20 15:34 | 显示全部楼层
C语言有成型的排序比较方法,你只需要处理好键盘接收数据和屏幕显示数据就好了
回复

使用道具 举报

ID:493416 发表于 2019-3-20 20:06 | 显示全部楼层
HC6800-ES-V2.0 发表于 2019-3-20 14:26
#include

#define GPIO_DIG P0

请问一下
1.第一次进入main函数的时候switch(i) 是为什么,这里的i应该没有赋值啊。又是怎么从0到8循环的呢。
2.还有这里j=10;
                while(j--);        
                GPIO_DIG=0x00;
这里是做了什么,每次都给j赋10的话while判定的时候一定为真啊 为什么每次要让数码管熄灭?
回复

使用道具 举报

ID:164602 发表于 2019-3-21 07:58 | 显示全部楼层
冷瞳啊 发表于 2019-3-20 20:06
请问一下
1.第一次进入main函数的时候switch(i) 是为什么,这里的i应该没有赋值啊。又是怎么从0到8循 ...

变量i就是从零到八的循环
第一次进入的switch就是你按键的次数并给显示缓存赋值
第二个问题就是消影。
回复

使用道具 举报

ID:213173 发表于 2019-3-21 16:49 | 显示全部楼层
给你把程序改好了,用冒泡法排序。希望能对你有所帮助。
无标题.jpg

  1. #include <reg51.h>
  2. #define uint unsigned int
  3. #define uchar unsigned char
  4. uchar code  key_table[]={0xee,0xde,0xbe,0x7e,0xed,0xdd,0xbd,0x7d,0xeb,0xdb};//键码
  5. uchar code dula_table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//段码
  6. uchar code wela_table[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//位码
  7. uchar numn[8];//缓存
  8. uchar nums[8];//缓存


  9. void keyscan()        //按键扫描
  10. {
  11.         static uchar count=0;//消抖计数
  12.         static bit sign=0;//按键自锁标志
  13.         uchar i,j,temp;//临时变量
  14.         P3=0xf0;
  15.         if(P3!=0xf0)
  16.         {
  17.                 if((++count>=20)&&(sign==0))
  18.                 {
  19.                         sign=1;
  20.                         temp=P3;
  21.                         P3=temp|0x0f;               
  22.                         temp=P3;
  23.                         for(i=0;i<10;i++)
  24.                         {
  25.                                 if(temp==key_table[i])
  26.                                 {      
  27.                                         for(j=7;j>0;j--)
  28.                                                 numn[j]=numn[j-1];//按输入顺序移位保存键值,超出抛弃
  29.                                         numn[0]=i;                        //保存最后输入键值
  30.                                         for(j=0;j<8;j++)
  31.                                         {
  32.                                                 nums[j]=numn[j];//转移有效数据
  33.                                         }
  34.                                         break;
  35.                                 }
  36.                         }
  37.                 }
  38.         }
  39.         else  //键抬起
  40.         {               
  41.                 count=0;//计数清0
  42.                 sign=0;//自锁清0
  43.         }
  44. }
  45. void Line_up()//冒泡法排序程序
  46. {
  47.         uchar i, j, temp;
  48.         for(i=0; i<8-1; i++)
  49.         {
  50.                 for(j=0;j<8-1-i;j++)
  51.                 {
  52.                         if(nums[j]>nums[j+1])
  53.                         {
  54.                                 temp=nums[j];
  55.                                 nums[j]=nums[j+1];
  56.                                 nums[j+1]=temp;
  57.                         }
  58.                 }
  59.         }
  60. }
  61. void display()//动态显示程序
  62. {
  63.         static uchar i=0;
  64.         P0=0x00;//消隐
  65.         P2=wela_table[i];//位码
  66.         P0=dula_table[nums[i]];//段码
  67.         if(++i==8)
  68.                 i=0;
  69. }

  70. void main()
  71. {
  72.         while(1)
  73.         {
  74.                 keyscan();//按键扫描
  75.                 Line_up();//排序程序
  76.                 display();//显示程序
  77.         }
  78. }
复制代码



回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表