找回密码
 立即注册
楼主: du***

跟 冲哥教学视频学习STC——记录每一天的成长| 必须立即送强大的实验箱支持啊 !

[复制链接]
  • TA的每日心情
    开心
    昨天 22:03
  • 签到天数: 110 天

    [LV.6]常住居民II

    5

    主题

    49

    回帖

    599

    积分

    高级会员

    积分
    599
     楼主| 发表于 2024-4-17 22:28:58 | 显示全部楼层
    Mark一下,因为已经快要学习到ADC后面的课程,再用自己手搓的开发板不能做相应的实验,就想申请下冲哥同款实验箱。昨天刚申请通过,今天就收到了,还是寄的顺丰,速度好快,本来预计可能要周六或周日才能到的。收到实验箱的第一眼就喜欢上了。它非常超乎我的意料,制作精美,工艺精湛,后续可以继续跟着冲哥的视频学习后面的课程了。

    其他的小伙伴也要加油,STC真是不错,每天打卡学习真的可以免费得到实验箱,工欲善其事,必先利其器,STC都把这么好的学习武器提供给我们了,我们还有什么理由不好好学习单片机知识呢。
    永远相信美好的事情即将发生!
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    开心
    昨天 22:03
  • 签到天数: 110 天

    [LV.6]常住居民II

    5

    主题

    49

    回帖

    599

    积分

    高级会员

    积分
    599
     楼主| 发表于 2024-4-17 22:31:49 | 显示全部楼层
    dumon 发表于 2024-4-17 22:28
    Mark一下,因为已经快要学习到ADC后面的课程,再用自己手搓的开发板不能做相应的实验,就想申请下冲哥同款 ...

    太激动了,都忘记附上实验箱的照片了。
    截图202404172231026109.jpg
    永远相信美好的事情即将发生!
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    开心
    昨天 06:34
  • 签到天数: 141 天

    [LV.7]常住居民III

    0

    主题

    393

    回帖

    398

    积分

    中级会员

    积分
    398
    发表于 2024-4-18 08:11:06 | 显示全部楼层
    哇,鸟枪换大炮了
    靡不有初,鲜克有终
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    开心
    昨天 22:03
  • 签到天数: 110 天

    [LV.6]常住居民II

    5

    主题

    49

    回帖

    599

    积分

    高级会员

    积分
    599
     楼主| 发表于 2024-4-18 23:28:36 | 显示全部楼层
    按键状态机


    按键按状态来分:按键按下、按键松开
           按电平来分:低电平、高电平

    其中按键按下时按低电平时长分为5种状态:
    <30 ms     消抖
    =30 ms     单击
    <3000ms  单击结束
    =3000ms  长按3秒
    >3000ms  长按结束

    可以看到时间是在一直累加的,当到达其中1个时间点时我们就执行这一步的程序,比如在30ms以内,我们认为按键是消抖状态,不进行任何操作,正好等于30ms时,执行单击程序,大于30ms小于3000ms这个区间是认为在长按过程,正好等于3000ms时认为达到长按的判定。超过3000ms,可以判定为长按结束。
    这里引进了一个状态机的概念,状态机教程里说的是条件转移,即这个变量是按键按下后累计的时长ms,随着时间轴的进行,等于或满足哪个条件时就进行运行状态转移,就比如上面的消抖,单击,长按,他是要满足时间条件后才能运行对应的步。

    下面分析下程序:
    计时数组  u16 count[8] = {0,0,0,0,0,0,0,0};     //一个8位元素的数组,每个元素对应1个P口的8位IO口,用于记录每个按键按下后的时间,数据类型要为16位整型。比如count[0]用于记录P3.0按下的时长

    u8 LastState = 0;   //8位整型变量用于记录上次哪个按键按下

    检查按键状态函数,放在主程序中每10ms执行一次
    void KEY_Deal(void)
    {
        u8 i = 0;
        for(i=0; i<8; i++)       //循环8次,用于判定P30~P37有无按键按下
        {
            if(~P3 & (1<<i))     //假设i= 0时,P30有按下为低电平,~P30 = ^(1111 1110)=0000 0001,1<<0 = 0000 0001,两者相与后为0000 0001,如果持续有P30按下,这个条件是一直满足的。
            {
                if(count[i]<60000)   //当有按键按下时,并且count[i]的值小于60000时,对应的count[i]就会一直进行累加,用于记录对应的按键按下时间。
                    count[i]++;
            }
            else            //当按键松开后,执行else里的语句
            {
                if(count[i]>0)    //当按键松开时,此时count[i]是大于0的,会把按键状态更新给LastState,LastState用来记录哪个按键按下了
                {
                    LastState |= (1<<i);  //这个按键有按下过,假设是P35,i=5,LastState = 0000 0000,1<<5 = 0010 0000,更新后LastState = 0010 0000
                 }
                 else
                 {
                     LastState &= ~(1<<i);  //两者相与,比如上面是P35按下,在i=0到4时,0010 0000 & 1111 1110,还是保持0010 0000不变,只有在i=5时才会将LastState清零,
                 }                                     //所以在这段函数运行时,会记录下哪个按键有按下,按下了多长时间,并将按键状态传递给LastState。
                 count[i] = 0;              //计数变量count[i]清零
             }
        }
    }

    读取指定的按键 状态
    /**************变量声明**************/
    #define KEY_NOPRESS        0                // 按键未按下
    #define KEY_FILCKER                1                // 消抖
    #define KEY_PRESS                2                // 单击
    #define KEY_PRESSOVER        3                // 单击结束
    #define KEY_LONGPRESS        4                // 长按3秒
    #define KEY_LONGOVER        5                // 长按结束
    #define KEY_RELAX                6                // 按键松开

    u8 KEY_Readstate(u8 keynum)    //keynum = 0~7;10ms执行一次
    {
        if(coount[keynum]>0)   //按键有按下时,count[i]有计数,各种状态处理
       {
           if(count[keynum]<3)               //1~29ms按键消抖
          {    return KEY_FILCKER;  }
           else if (count[keynum]==3)     //超过30ms,返回单击
          {    return KEY_PRESS;  }

           else if (count[keynum]<300)    //31~2999ms,返回单击结束
          {    return KEY_PRESSOVER;  }


           else if (count[keynum]==300)  //正好3000ms时,返回长按
          {    return KEY_LONGPRESS;  }


           else                                        // 大于3000ms,返回长按结束
          {    return KEY_LONGOVER;  }

        }
       else                //按键松开后,进行判断按键之前有无按下过
       {
            if(LastState & (1<<keynum))    //假设之前P3.5有按下过,LastState会记忆P3.5的状态值,当P3.5再次按下,等其松开后就会返回”KEY_RELAX“,表示这个键上次有按下过
            {   return KEY_RELAX;  }
            else
            {   return KEY_NOPRESS;  }     //按键之前没有被按下过,比如上次是按的P3.5,这次是按的P3.0,两者不相等,就会返回这里语句的值。
        }
    }

    以上,是对第13集多任务处理中,按键状态机的程序解读,LastState这个变量是用于检查按键检查函数中用于区分”按键松开“与”没有按下“。

    通过计数数组count[i]来统计按键按下时长,根据count[i]的值来判定程序应该执行到哪一步,满足了某个条件就进行转移,这就是状态机,这也是程序中一种常用用法。后面还会经常运用到。
    永远相信美好的事情即将发生!
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    开心
    前天 05:32
  • 签到天数: 58 天

    [LV.5]常住居民I

    8

    主题

    101

    回帖

    468

    积分

    中级会员

    积分
    468
    发表于 2024-4-19 19:50:42 | 显示全部楼层
    学的真好啊
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    开心
    昨天 22:03
  • 签到天数: 110 天

    [LV.6]常住居民II

    5

    主题

    49

    回帖

    599

    积分

    高级会员

    积分
    599
     楼主| 发表于 2024-4-20 13:45:04 | 显示全部楼层
    第13集 多任务处理的总结

    附上开发板烧录程序后的演示视频
    手写学习笔记



    IMG_20240420_133719[1].jpg
    IMG_20240420_133741[1].jpg
    IMG_20240420_133757[1].jpg
    IMG_20240420_133812[1].jpg

    21. STC32G自制开发板 - 多任务处理.zip

    330.8 KB, 下载次数: 4

    程序代码

    永远相信美好的事情即将发生!
    回复 支持 反对 送花

    使用道具 举报

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

    本版积分规则

    QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

    GMT+8, 2024-5-3 04:56 , Processed in 0.491606 second(s), 51 queries .

    Powered by Discuz! X3.5

    © 2001-2024 Discuz! Team.

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