daiya 发表于 2015-11-17 16:34:31

请教单片机设置参数的方法

程序中红色部分是一种参数设置方法,按SET键切换参数,按UP键+,按DOWN键-。可是每设置一个参数都要调用按键扫描函数keyscan(),各位高人有没有更方便的办法实现参数设置呢?

#include<reg51.h>

unsigned char code LedChar[] = {
        0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
        0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e
};
unsigned char LedBuff = {0xff,0xff,0xff,0xff};

sbit gewei = P1^3;
sbit shiwei = P1^2;
sbit baiwei = P1^1;
unsigned char i = 0;

unsigned char iset = 0;

signed int disp0 = 15;
signed int disp1 = 21;

void delayms(unsigned int k)
{
        unsigned int i,j;
        for(i=k;i>0;i--)
                for(j=110;j>0;j--);
}

unsigned char keyscan(void)
{
        unsigned char keynum=0;
        unsigned char temp=0;
        P3=0xff;        //P3口置oxff,准备读取输入值
        if(P3!=0xff)        //判断是否有键按下
        {
                delayms(10);        //延时10ms消抖动
                P3=0xff;        //P3口置oxff,准备2次读取输入值
                if(P3!=0xff)        //2次判断是否有键按下
                {
                        temp=P3;        //读取P3口值至temp中
                        while(P3!=0xff);        //按键释放检测语句
                        switch(temp)        //进入开关多分支语句判断
                        {
                                case 0xfb:
                                        keynum=1;        //SET键
                                        break;
                                case 0xf7:
                                        keynum=2;        //LEFT键
                                        break;
                                case 0xef:
                                        keynum=3;        //UP键
                                        break;
                                case 0xdf:
                                        keynum=4;        //DOWN键
                                        break;
                                case 0xbf:
                                        keynum=5;        //模拟SET键长按
                                        break;
                                case 0x7f:
                                        keynum=6;        //模拟LEFT键长按
                                        break;
                                default:
                                        break;
                        }
                }
        }

        return keynum;
}

void main()
{
        unsigned long sec = 0;
        unsigned char key;
       
        EA = 1;
        TMOD = 0x01;
        TH0 = 0xfc;
        TL0 = 0x67;
        ET0 = 1;
        TR0 = 1;

        while(1)
        {
                if(iset == 0)
                {
                        key = keyscan();
                        if(key == 1)        //SET键
                        {
                                iset++;
                        }
                        if(key == 3)        //UP键
                        {
                                disp0++;
                        }
                        if(key == 4)        //DOWN键
                        {
                                disp0--;
                        }
                        LedBuff = LedChar;
                        LedBuff = LedChar;
                        LedBuff = LedChar;
                }
                else if(iset == 1)
                {
                        key = keyscan();
                        if(key == 1)        //SET键
                        {
                                iset++;
                        }
                        if(key == 3)        //UP键
                        {
                                disp1++;
                        }
                        if(key == 4)        //DOWN键
                        {
                                disp1--;
                        }
                        LedBuff = LedChar;
                        LedBuff = LedChar;
                        LedBuff = LedChar;
                }
               
        }
}

void InterruptTimer0() interrupt 1
{
        TH0 = 0xfc;
        TL0 = 0x67;

        P0 = 0xff;
        if(i == 0)
        {
                baiwei = 1;
                shiwei = 1;
                gewei = 0;
                i++;
                P0 = LedBuff;
        }
        else if(i == 1)
        {
                baiwei = 1;
                shiwei = 0;
                gewei = 1;
                i++;
                P0 = LedBuff;
        }
        else if(i == 2)
        {
                baiwei = 0;
                shiwei = 1;
                gewei = 1;
                i = 0;
                P0 = LedBuff;
        }
}

lcw_swust 发表于 2015-11-17 19:20:16

while(1)
      {
       key = keyscan();      
         if(iset == 0)
                  ...
         if(iset == 1)
                  ...

建议keyscan内不要死等,应当用if语句或用状态机判断按键的按下\放开.

xiaobendan 发表于 2015-11-17 20:09:59

本帖最后由 xiaobendan 于 2015-11-17 20:11 编辑

效率比较低
我一般的方法是,参数放在数组里面,DIS平时就显示参数【0】
然后
switch(key){
case 1:
set++;
break;
case 2:
参数++;
break;
case 3:
参数--;
break;
}
在主循环里面判断set大于0则把参数复制到参数【0】

daiya 发表于 2015-11-17 22:22:52

本帖最后由 daiya 于 2015-11-17 23:07 编辑

lcw_swust 发表于 2015-11-17 19:20
while(1)
      {
       key = keyscan();      


按照您的方法改了,效果很好!

#include<reg51.h>

unsigned char code LedChar[] = {
        0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
        0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e
};
unsigned char LedBuff = {0xff,0xff,0xff,0xff};

sbit gewei = P1^3;
sbit shiwei = P1^2;
sbit baiwei = P1^1;
unsigned char i = 0;

unsigned char iset = 0;

signed int disp = 0;
signed int disp0 = 15;
signed int disp1 = 21;

void delayms(unsigned int k)
{
        unsigned int i,j;
        for(i=k;i>0;i--)
                for(j=110;j>0;j--);
}

unsigned char keyscan(void)
{
        unsigned char keynum=0;
        unsigned char temp=0;
        P3=0xff;        //P3口置oxff,准备读取输入值
        if(P3!=0xff)        //判断是否有键按下
        {
                delayms(10);        //延时10ms消抖动
                P3=0xff;        //P3口置oxff,准备2次读取输入值
                if(P3!=0xff)        //2次判断是否有键按下
                {
                        temp=P3;        //读取P3口值至temp中
                        while(P3!=0xff);        //按键释放检测语句
                        switch(temp)        //进入开关多分支语句判断
                        {
                                case 0xfb:
                                        keynum=1;        //SET键
                                        break;
                                case 0xf7:
                                        keynum=2;        //LEFT键
                                        break;
                                case 0xef:
                                        keynum=3;        //UP键
                                        break;
                                case 0xdf:
                                        keynum=4;        //DOWN键
                                        break;
                                case 0xbf:
                                        keynum=5;        //模拟SET键长按
                                        break;
                                case 0x7f:
                                        keynum=6;        //模拟LEFT键长按
                                        break;
                                default:
                                        break;
                        }
                }
        }

        return keynum;
}

void main()
{
        unsigned long sec = 0;
        unsigned char key;
       
        EA = 1;
        TMOD = 0x01;
        TH0 = 0xfc;
        TL0 = 0x67;
        ET0 = 1;
        TR0 = 1;

        while(1)
        {
                key = keyscan();
                if(iset == 0)
                {
                        if(key == 1)        //SET键
                        {
                                iset++;
                        }
                        if(key == 3)        //UP键
                        {
                                disp0++;
                        }
                        if(key == 4)        //DOWN键
                        {
                                disp0--;
                        }
                        disp = disp0;
                }
                else if(iset == 1)
                {
                        if(key == 1)        //SET键
                        {
                                iset++;
                        }
                        if(key == 3)        //UP键
                        {
                                disp1++;
                        }
                        if(key == 4)        //DOWN键
                        {
                                disp1--;
                        }
                        disp = disp1;
                }
                else if(iset == 2)
                {
                        iset=0;
                }
                LedBuff = LedChar;
                LedBuff = LedChar;
                LedBuff = LedChar;
        }
}

void InterruptTimer0() interrupt 1
{
        TH0 = 0xfc;
        TL0 = 0x67;

        P0 = 0xff;
        if(i == 0)
        {
                baiwei = 1;
                shiwei = 1;
                gewei = 0;
                i++;
                P0 = LedBuff;
        }
        else if(i == 1)
        {
                baiwei = 1;
                shiwei = 0;
                gewei = 1;
                i++;
                P0 = LedBuff;
        }
        else if(i == 2)
        {
                baiwei = 0;
                shiwei = 1;
                gewei = 1;
                i = 0;
                P0 = LedBuff;
        }
}

daiya 发表于 2015-11-17 23:16:37

有没有更好的程序架构能实现设置参数呢?

talkingbeast 发表于 2015-11-17 23:26:32

感觉很奇怪的按键设置,不管按不按设置键,按上下按键可以增加和减小显示数字,这个和实际的应用不符合吧。

a136498491 发表于 2015-11-17 23:58:02

更好的框架当然是RTOS了,状态机是设计时把任务分解,OS就是轮番调度了,设计时没那么麻烦。

daiya 发表于 2015-11-20 16:39:09

修改了一下,这样结构比较好!

#include<reg51.h>

unsigned char code LedChar[] = {
        0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
        0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e
};
unsigned char LedBuff = {0xff,0xff,0xff,0xff};

sbit gewei = P1^3;
sbit shiwei = P1^2;
sbit baiwei = P1^1;
unsigned char i = 0;

unsigned char iset = 0;

signed int disp = 0;
signed int disp0 = 15;
signed int disp1 = 21;
signed int disp2 = 5;

void delayms(unsigned int k)
{
        unsigned int i,j;
        for(i=k;i>0;i--)
                for(j=110;j>0;j--);
}

unsigned char keyscan(void)
{
        unsigned char keynum=0;
        unsigned char temp=0;
        P3=0xff;        //P3口置oxff,准备读取输入值
        if(P3!=0xff)        //判断是否有键按下
        {
                delayms(10);        //延时10ms消抖动
                P3=0xff;        //P3口置oxff,准备2次读取输入值
                if(P3!=0xff)        //2次判断是否有键按下
                {
                        temp=P3;        //读取P3口值至temp中
                        while(P3!=0xff);        //按键释放检测语句
                        switch(temp)        //进入开关多分支语句判断
                        {
                                case 0xfb:
                                        keynum=1;        //SET键
                                        break;
                                case 0xf7:
                                        keynum=2;        //LEFT键
                                        break;
                                case 0xef:
                                        keynum=3;        //UP键
                                        break;
                                case 0xdf:
                                        keynum=4;        //DOWN键
                                        break;
                                case 0xbf:
                                        keynum=5;        //模拟SET键长按
                                        break;
                                case 0x7f:
                                        keynum=6;        //模拟LEFT键长按
                                        break;
                                default:
                                        break;
                        }
                }
        }

        return keynum;
}

void main()
{
        unsigned long sec = 0;
        unsigned char key;
       
        EA = 1;
        TMOD = 0x01;
        TH0 = 0xfc;
        TL0 = 0x67;
        ET0 = 1;
        TR0 = 1;

        while(1)
        {
                key = keyscan();
                if(key == 1)        //SET键
                {
                        iset++;
                        if(iset == 3)
                                iset=0;
                }
                else if(key == 3)        //UP键
                {
                        if(iset == 1)
                        {
                                disp0++;
                        }
                        else if(iset == 2)
                        {
                                disp1++;
                        }
                }
                else if(key == 4)        //DOWN键
                {
                        if(iset == 1)
                        {
                                disp0--;
                        }
                        else if(iset == 2)
                        {
                                disp1--;
                        }
                }
                if(iset == 0)
                {
                        disp=disp2;
                }
                else if(iset == 1)
                {
                        disp=disp0;
                }
                else if(iset == 2)
                {
                        disp=disp1;
                }
                LedBuff = LedChar;
                LedBuff = LedChar;
                LedBuff = LedChar;
        }
}

void InterruptTimer0() interrupt 1
{
        TH0 = 0xfc;
        TL0 = 0x67;

        P0 = 0xff;
        if(i == 0)
        {
                baiwei = 1;
                shiwei = 1;
                gewei = 0;
                i++;
                P0 = LedBuff;
        }
        else if(i == 1)
        {
                baiwei = 1;
                shiwei = 0;
                gewei = 1;
                i++;
                P0 = LedBuff;
        }
        else if(i == 2)
        {
                baiwei = 0;
                shiwei = 1;
                gewei = 1;
                i = 0;
                P0 = LedBuff;
        }
}
页: [1]
查看完整版本: 请教单片机设置参数的方法