搜索
bottom↓
回复: 7

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

[复制链接]

出0入0汤圆

发表于 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[4] = {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[0] = LedChar[disp0 % 10];
                        LedBuff[1] = LedChar[disp0 / 10 % 10];
                        LedBuff[2] = LedChar[disp0 / 100 % 10];
                }
                else if(iset == 1)
                {
                        key = keyscan();
                        if(key == 1)        //SET键
                        {
                                iset++;
                        }
                        if(key == 3)        //UP键
                        {
                                disp1++;
                        }
                        if(key == 4)        //DOWN键
                        {
                                disp1--;
                        }
                        LedBuff[0] = LedChar[disp1 % 10];
                        LedBuff[1] = LedChar[disp1 / 10 % 10];
                        LedBuff[2] = LedChar[disp1 / 100 % 10];
                }
               
        }
}

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

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

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

发表于 2015-11-17 19:20:16 | 显示全部楼层
while(1)
        {
       key = keyscan();        
           if(iset == 0)
                  ...
           if(iset == 1)
                  ...

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

出0入0汤圆

发表于 2015-11-17 20:09:59 | 显示全部楼层
本帖最后由 xiaobendan 于 2015-11-17 20:11 编辑

效率比较低
我一般的方法是,参数放在数组里面,DIS平时就显示参数【0】
然后
  1. switch(key){
  2. case 1:
  3. set++;
  4. break;
  5. case 2:
  6. 参数[set]++;
  7. break;
  8. case 3:
  9. 参数[set]--;
  10. break;
  11. }
复制代码

在主循环里面判断set大于0则把参数[set]复制到参数【0】

出0入0汤圆

 楼主| 发表于 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[4] = {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[0] = LedChar[disp % 10];
                LedBuff[1] = LedChar[disp / 10 % 10];
                LedBuff[2] = LedChar[disp / 100 % 10];
        }
}

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

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

出0入0汤圆

 楼主| 发表于 2015-11-17 23:16:37 | 显示全部楼层
有没有更好的程序架构能实现设置参数呢?

出20入0汤圆

发表于 2015-11-17 23:26:32 | 显示全部楼层
  感觉很奇怪的按键设置,不管按不按设置键,按上下按键可以增加和减小显示数字,这个和实际的应用不符合吧。

出0入0汤圆

发表于 2015-11-17 23:58:02 | 显示全部楼层
更好的框架当然是RTOS了,状态机是设计时把任务分解,OS就是轮番调度了,设计时没那么麻烦。

出0入0汤圆

 楼主| 发表于 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[4] = {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[0] = LedChar[disp % 10];
                LedBuff[1] = LedChar[disp / 10 % 10];
                LedBuff[2] = LedChar[disp / 100 % 10];

        }
}

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

        P0 = 0xff;
        if(i == 0)
        {
                baiwei = 1;
                shiwei = 1;
                gewei = 0;
                i++;
                P0 = LedBuff[0];
        }
        else if(i == 1)
        {
                baiwei = 1;
                shiwei = 0;
                gewei = 1;
                i++;
                P0 = LedBuff[1];
        }
        else if(i == 2)
        {
                baiwei = 0;
                shiwei = 1;
                gewei = 1;
                i = 0;
                P0 = LedBuff[2];
        }
}
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-23 20:50

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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