打印

编程思维挑战!!!

[复制链接]
10866|62
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
highgear|  楼主 | 2009-5-12 00:57 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
“按下P1^4,LED闪烁时间加快,按下时间越长,闪烁频率越快。
释放开关,频率固定停在当前值闪烁。这才是编程思维挑战“

首先声明:对于这里的多数人,这当然不是什么编程思维挑战,只不过有人一定要这么说,为了说明这个论坛水平,我这个中低手做了这么一段C代码在visual c++ 的演示,供辉阳的心等初学者参考。我相信有更多的人能做出比这更好的代码。因此,敬请某些人不必再怀疑本论坛众人的智商。


class CLEDTestDlg : public CDialog
{
    struct LEDStatus
    {
        int        frequency;
        int        counter;
        bool    status;
    }
    m_LEDStatus;

    enum Keyboard
    {
        NOKEY,
        LEFTKEY,
        RIGHTKEY
    } KEYBOARD;

    struct KeyStatus
    {
        Keyboard key;
        Keyboard pressedKey;
        int keyState;
        int keyTimer;
        bool keyEventHandled;
    }
    m_KeyStatus;

    CStatic LED1;   //模仿LED 闪烁。

**********************************************************************
BOOL CLEDTestDlg::OnInitDialog()
{
    CDialog::OnInitDialog();
    this->SetTimer(1, 20, NULL);   //用定时器模仿定时中断。
    m_LEDStatus.frequency = 50;    //1 second;
    m_LEDStatus.counter = 0;
    m_KeyStatus.key = NOKEY;
    m_KeyStatus.pressedKey = NOKEY;
    m_KeyStatus.keyState = 0;
    return TRUE;
}

void CLEDTestDlg::OnTimer(UINT_PTR nIDEvent)  //定时中断
{
    BlinkLED();
    DetectKeyPress();
}

void CLEDTestDlg::BlinkLED()  
{
    if (++m_LEDStatus.counter >= m_LEDStatus.frequency) {
        m_LEDStatus.counter = 0;
        LED1.SetWindowText(m_LEDStatus.status ? " " : "*"); //Led 闪烁。
        m_LEDStatus.status = !m_LEDStatus.status;
    }

    if (m_KeyStatus.key != NOKEY && !m_KeyStatus.keyEventHandled) {
        m_KeyStatus.keyEventHandled = true;
        if (m_KeyStatus.key == LEFTKEY) {
            m_LEDStatus.frequency -= 10;
            if (m_LEDStatus.frequency <= 0)
                m_LEDStatus.frequency = 0;
        }
        else if (m_KeyStatus.key == RIGHTKEY) {
            m_LEDStatus.frequency += 10;
            if (m_LEDStatus.frequency >= 500)
                m_LEDStatus.frequency = 500;
        }
    }
}


void CLEDTestDlg::DetectKeyPress()   //模仿键盘处理过程
{
    switch (m_KeyStatus.keyState) {
        case 0:
            if (m_KeyStatus.pressedKey != NOKEY)
                m_KeyStatus.keyState++; //去抖动
            break;
        case 1:    
            if (m_KeyStatus.pressedKey == NOKEY)
                m_KeyStatus.keyState--;
            else {
                m_KeyStatus.key = m_KeyStatus.pressedKey;
                m_KeyStatus.keyEventHandled = false;
                m_KeyStatus.keyTimer = 100;                    //2 seconds
                m_KeyStatus.keyState++;
            }
            break;
        case 2:
            if (m_KeyStatus.key != m_KeyStatus.pressedKey) {
                m_KeyStatus.keyState = 0;
                m_KeyStatus.key = NOKEY;
            }
            else {
                if (--m_KeyStatus.keyTimer == 0) {
                    m_KeyStatus.keyTimer = 50;                // 1 second
                    m_KeyStatus.keyEventHandled = false;
                }
            }
            break;
        default:
            m_KeyStatus.keyState = 0;
    }
}


//处理鼠标左右键的按下
BOOL CLEDTestDlg::PreTranslateMessage(MSG* pMsg)
{
    switch (pMsg->message) {
        case WM_LBUTTONDOWN:
            m_KeyStatus.pressedKey = LEFTKEY;
            break;
        case WM_RBUTTONDOWN:
            m_KeyStatus.pressedKey = RIGHTKEY;
            break;
        case WM_LBUTTONUP:
        case WM_RBUTTONUP:
            m_KeyStatus.pressedKey = NOKEY;
            break;
    }
    return CDialog::PreTranslateMessage(pMsg);
}

欢迎讨论。

相关帖子

沙发
一级菜鸟| | 2009-5-12 02:04 | 只看该作者

PC上的东西和MCU根本就不是那么一回事

定时器中断
{
     变量A++;
     if (变量A == 变量B)
     {
          LED = ~LED;
          变量A = 0;

     }
}

按键处理
{
    变量B++;
}




使用特权

评论回复
板凳
xwj| | 2009-5-12 08:33 | 只看该作者

路过

这也要挑战???

使用特权

评论回复
地板
初入江湖| | 2009-5-12 08:41 | 只看该作者

学习

路过! 顶一下!

使用特权

评论回复
5
长沙卖菜王| | 2009-5-12 09:06 | 只看该作者

顶起

使用特权

评论回复
6
长沙卖菜王| | 2009-5-12 09:07 | 只看该作者

我用汇编帮你搞定

我用汇编就帮你搞定,不很简单的代码

使用特权

评论回复
7
machunshui| | 2009-5-12 09:11 | 只看该作者

标题有点言不符实

标题有点言不符实

使用特权

评论回复
8
highgear|  楼主 | 2009-5-12 09:27 | 只看该作者

谢谢楼上各位。

xwj: 没办法,你的亲戚wxj们认为这是个“编程思维挑战“,我这中手为避免再次出现“无一人做出“的说法,不得已做一个程序,让大家见笑了。

PC上的东西和MCU, 原理验证大同小异,只不过我现手头没有51板子。这是c51程序片断:

struct LEDStatus
{
    int             frequency;
    int             counter;
}
m_LEDStatus;

enum Keyboard
{
    NOKEY,
    LEFTKEY,
    RIGHTKEY
};

struct KeyStatus
{
    char key;
    char pressedKey;
    int keyState;
    int keyTimer;
    char keyEventHandled;
}
m_KeyStatus;

void main()
{
    m_LEDStatus.frequency = 50;
    m_LEDStatus.counter = 0;
    m_KeyStatus.key = NOKEY;
    m_KeyStatus.pressedKey = NOKEY;
    m_KeyStatus.keyState = 0;
    Timer_Initialize();
    while (1) {
    }
}

// 20 millisecond interrupt
void Timer0_ISR() interrupt 1 using 1
{
    TH0 = (unsigned char) (TIMER0_CONSTANT >> 8);
    TL0 = (unsigned char) (TIMER0_CONSTANT & 0xFF);

    BlinkLED();
    DetectKeyPress();
}

void BlinkLED()
{
   if (++m_LEDStatus.counter >= m_LEDStatus.frequency) {
       LED = ~LED;
       m_LEDStatus.counter = 0;
    ...
}

void DetectKeyPress()
{
    DetectKeyInput();
    switch (m_KeyStatus.keyState) {
    ...
}

void DetectKeyInput()
{
   if (P1_1)
       m_KeyStatus.pressedKey = LEFTKEY;
   else if (P1_2)
       m_KeyStatus.pressedKey = RIGHTKEY;
   else
       m_KeyStatus.pressedKey = NOKEY;
}

使用特权

评论回复
9
mohanwei| | 2009-5-12 09:44 | 只看该作者

2楼的伪代码已经说到实质了,但是还有一点小BUG

把B++改为B--就可以完全符合题意了:

定时器中断
{
     变量A++;
     if (变量A == 变量B)
     {
          LED = ~LED;
          变量A = 0;

     }
}

按键处理
{
    变量--;
}

使用特权

评论回复
10
highgear|  楼主 | 2009-5-12 10:07 | 只看该作者

9楼 也有一点小BUG

按键处理
{
    变量B--;
}

看来这个问题公认没有挑战性,的确是“小马过河“的故事啊。

使用特权

评论回复
11
ayb_ice| | 2009-5-12 10:09 | 只看该作者

标题有点大

使用特权

评论回复
12
刘前辈| | 2009-5-12 11:32 | 只看该作者

哈哈,所长终于出山了!

C++都上来了。典型的所长的风格。
不过所长近来确实理解力随年龄有些退化。忘了一个重要的条件:还有其他三个LED在“同时”闪烁呐!highgear不懂什么叫“多任务并发”,所长不会不知道吧?

什么叫“挑战”?
“有4个LED,正同时以不同的频率闪烁;
另设有按键1、按键2,当按键1持续按下时,LED0闪烁频率加快(总不能无限加快,上限可设定。)按键1抬起时,闪烁频率维持当前;

当按键2持续按下时,LED0闪烁频率减慢(总不能无限降低,下线可设定。)按键2抬起时,闪烁频率维持当前;

如果没有其他3个LED1~LED3同时并发闪烁,菜鸟都会做,还要所长出山用C++?!2楼说得好:PC和MCU根本是两回事。所长是不是还准备下一步用C#来做?

对不起,咱菜鸟用C51就能解决啦。

既然highgear又想玩真的,我也学1952那样,拍下500元,站长和版主和全论坛网友作证人,这回你输了就不能一跑了之了吧。

highgear过去的行为咱都看在眼里,输给别人1000元,输了就跑。如今又理直气壮出来啦。

有本事先把1952那道题解了,“21IC水平太低,关门得了”可是你说的?咋呼半天,自己也没解出来,有不了了之了。这是最没劲的事。浪费别人时间,从不付赌资,却总要和人赌。无赖呀。

有胆量咱两人先各拍下500元。玩最后一场真的。以后别老缠着我,也让众网友监督你点,别那么上瘾!我烦!

1、写出1952那道题的程序解,别老谈方案。让你写程序。这次我拍1,000元。
2、本题目C51“可运行”程序,别老节选,片段,方案。这付你500元呢。
3、我写的如果比你简单,你必须掏钱。你这么顶级编程高手,500元捂着钱袋子不放?比我菜鸟还穷?

有胆量就赌,别咋咋呼呼的空喊。没劲!

使用特权

评论回复
13
mohanwei| | 2009-5-12 12:44 | 只看该作者

10楼估计不太清楚“伪代码”的概念……

题目本身的要求也是很模糊的……“加快”总涉及“加速度”吧?“加速度”都没有给出,自然只能给出个Demo;“加快”总有个极限吧?这自然就是边界条件的……既然谈“思维”却又牵涉到具体实现代码,显然一下子降低了N个“档次”……

使用特权

评论回复
14
冷漠| | 2009-5-12 13:53 | 只看该作者

13楼说的太好了。一下子把highgear说愣了。尴尬!

前辈的题目条件还没说全,highgear程序就出来了。惊愕!

其实是highgear没向所长把条件讲述全,他不知道这类题目编程过程中还需要什么条件,也许前辈本来就是故意留一些陷阱的,没这些条件,题目怎么做呀?故意看highgear下一步到底怎么办?所长是局外人,当然看不出还少什么条件,上来就用C++?不知道解个什么题,南辕北辙。

好不容易所长帮highgear写了个文不对题的程序,highgear如获至宝:《编程思想的挑战》,让论坛上网友笑话,

“这也要挑战?”
“汇编都能做了。”

唉!这一对父子兵....还总缠着1952,一来真格的就跑。

使用特权

评论回复
15
冷漠| | 2009-5-12 15:39 | 只看该作者

前辈息怒,有些事了解后就释然了。

1、为什么今天以前 highgear 2、3天未能写出一条程序?不过是一个简单的键盘扫描模块而已;
   原因:周末。所长休息。没人“罩”着highgear。
   所以平时若无所长罩着,highgear恐怕只能“以后慢慢会让你看到”,声音都低了8度。一点高手的底气都没有了。只能急切地盼着下星期工作日到来。
   一旦等到星期一至星期五工作日,马上不一样啦,狐假虎威,神气来了。菜鸟级的程序也《编程思维的挑战》,——所长在后面提拎着呢。

2、highgear 和所长是什么关系:一个单位的,师徒关系。“一天为师,终身为父。”所以我说2人父子关系不为过,没有贬义。

所长和1952之间的过节,是他们之间的事。所长退出是出自50岁男人的尊严。跟别人没关系。
highgear却不能视而不见:谁欺负我师父我就和他没完。

“我见一位我尊敬的前辈无端被辱骂才跳出来对骂,论坛里的技术对错关我p事。”

噢,原来highear不管技术对错,只管跳出来帮师傅对骂?
所以highgear所做的一切,都是为了所长,做给师傅看的。

highgear过去做了对不起所长的事,拍马没拍好,把所长弄得很尴尬,现在一直都在找机会补偿,所以只要论坛上和1952有关系的人,他都像苍蝇见了血,死缠不放。卖命做给所长师傅看的。

所长本来是我们尊重的长辈。HOTPOWER曾评价所长“技术高,心眼儿小”。(这不是我说的,有HOT作证。)现在看所长和highgear这种师徒联合行动,确实有损尊严。

所长是从事PC纯软件工作的,所以动不动上来就是C++,C#,例如很简单的问题(char)i=(char)i; 也要上C++,C#?——本来C51甚至A51就能解决的很简单的问题。
但是highgear不知道MCU和PC这种差别,以为凡是师傅的程序都是至宝,拿到21IC来不管三七二十一就贴,“水平在这里,编程思维挑战。”结果他不知道恰恰这种无知行为,又一次把所长卖了。让我彻底见识了所长的“心眼儿”。

所以前辈不必往心里去。这么两个人,“21IC水平太差,关门得了。”highgear每天把别人如何“菜鸟”的成果回去讲给师傅听,2人一起在阴暗的角落里窃笑,以此获得心理上的快乐。

    前辈还会和这种人计较?

使用特权

评论回复
16
刘前辈| | 2009-5-12 17:54 | 只看该作者

唉,玩这种把戏。

师徒背后联手?所长50多岁的人了......

谢了,LS。俺还蒙在鼓里。

太可悲了。如今真是什么怪事说不准就碰上了。

使用特权

评论回复
17
一级菜鸟| | 2009-5-12 18:09 | 只看该作者

这演的哪一出?

使用特权

评论回复
18
aihe| | 2009-5-12 20:09 | 只看该作者

真的很多人会意淫

算是见识了

使用特权

评论回复
19
mikezhong| | 2009-5-12 21:15 | 只看该作者

这个也不难吧.

89C516有6路PWM,接4个灯是没有问题,单独用按键控制也可以.灯闪越来越快,总不会说不是用人眼看吧...人眼能做出来,速度就不快了,这样写会有什么问题?


总不会说500+600=1100非要规定用手指头来数吧....

使用特权

评论回复
20
highgear|  楼主 | 2009-5-12 21:59 | 只看该作者

哈哈,果然是一伙的下贱小人。

1) wxj1952的题已被公认脑残,如果你们,不服气,可以再次贴出,再次让大家评判。

2)阿米驼佛,小衲不是你们的爹,没必要按照你们的思路进行。“前辈的题目条件还没说全“,真不愧一伙脑残人,即便你们公开问,小衲不是你们的爹,没有义务一定要回答你。

3)知道小衲为什么要全部使用struct么?为什么detectkey 与LED 无关呢? 小衲就知道你们会使用各种下流伎俩,还“多任务并发“,水平之低下,由此可见。敢不敢把你们自己做的两个键,一个LED “编程思维挑战“代码亮出来由大家评判呢?

4)小衲愧为人和地(R&D)堂首座,眼高于顶,不会假手他人。以上的程序均有小衲一人做出,没有任何人指点或帮助。小衲对自己的代码有绝对的自信,所以敢于出示代码,相信这里众人的眼光和水平。至于冷x,刘xx, 没有这种自信,偶尔的代码,一看就知道水平低下。

5)阿米驼佛,我不入地狱,谁入地狱。为21icbbs众人平安,可以赌,条件为:
8 个LED,16个key( 4*4 keyboard).
按下某键,某LED闪烁时间加快,每一秒加快一次(max = 20Hz)
按下某键,某LED闪烁时间减慢,每一秒加慢一次 (min = 0.2Hz)
释放开关,频率固定停在当前值闪烁。

以上程序必须使用单片C51(不得扩展RAM, ROM),Visual C++, Visual Basic 6.0 以及C# 各做一次,敢不敢接受挑战呢?

 

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

19

主题

1222

帖子

61

粉丝