YangHY 发表于 2025-12-29 12:11:09

经过查找源程序,发现按钮按下,应该是==0!

YangHY 发表于 2025-12-29 12:20:48

其实还有个地方,行和列要恢复一下初值:

if(( ROW1 == 0 ) || ( ROW2 == 0 ))                //如果行按键有按下
      {
                if(( ROW1 ==0 ) && ( ROW2 ==0 ))      //如果两行都有按键按下,不处理
                {
                        
                }
                else if((( ROW1 ==1 )&&( ROW2 ==0 )) || (( ROW1 ==0 )&&( ROW2 ==1 )))      //如果有按键按下,而且只有一颗
                {
                        if( ROW1 ==0 )                              //判断哪一行,输出行开始的序号
                              key_num = 0;
                        else if( ROW2 ==0 )
                              key_num = 4;
                              
                        //②第二步:现将P0.0-P0.3输出高电平,P0.6-P0.7输出低电平,如果有按键按下,按下的那一列的IO就会变成低电平,就可以判断出哪一列按下了。
                        COL1 = 1;
                        COL2 = 1;
                        COL3 = 1;
                        COL4 = 1;
                        ROW1 = 0;
                        ROW2 = 0;
                        
                        if( COL1 ==0 )                              //判断哪一列,叠加按键的序号
                        {
//                              key_num = key_num +0 ;   //③第三步:行列组合一下就可以判断出是哪个按键按下了。

                        }
                        else if( COL2 ==0 )
                        {
                              key_num = key_num + 1;
                        }
                        else if( COL3 ==0 )
                        {
                              key_num = key_num + 2;
                        }
                        else if( COL4 ==0 )
                        {
                              key_num = key_num + 3;
                        }
                }
                COL1 = 0;   //以下6行如果不写的话,会有点小问题,就是上次检测完按键后
                COL2 = 0;//没有把初始值恢复,数码管会闪一下,感觉很不稳定
                COL3 = 0;//所以这样要把行和列都重新设置回初值
                COL4 = 0;
                ROW1 = 1;
                ROW2 = 1;               
      }
      else
      {
                key_num = 0xff;
      }
      
其实主要是端口的电平还是要恢复为初始状态

YangHY 发表于 2025-12-29 12:28:01

任务二:做一把密码锁:

YangHY 发表于 2025-12-29 12:30:12

矩阵按键的程序实现
密码锁.
1.没有输入时,显示
2.有输入时,按下一个按键,开始按顺序写入例如,第一个按下1,显示“1例如,第二个按下3,显示“1 3.-
3.当按下的密码为“12345670”时,数码管显示“88888888”的字符,否则,还是显示 “EEEEEEEE”

程序怎么写?

YangHY 发表于 2025-12-29 12:31:12

我们先把冲哥的程序代码贴上来:

/*下面是任务二密码锁代码
u8 passward = { 16,16,16,16,16,16,16,16 };

u8 Seg_no = 0;

void SEG_Task(void)
{
        u8 num = 0;
        if( Seg_no ==0 )                                                                //小时十位
        {
                Display_Seg( SEG_NUM] , ~T_NUM);                //数码管刷段码和位码
        }
        else if( Seg_no ==1 )                                                        //小时的个位
        {
                Display_Seg( SEG_NUM] , ~T_NUM);                //数码管刷段码和位码
        }       
        else if( Seg_no ==2 )                                                        //第一个横杠
        {
                Display_Seg( SEG_NUM] , ~T_NUM);                //数码管刷段码和位码
        }       
        else if( Seg_no ==3 )                                                        //分钟的十位
        {
                Display_Seg( SEG_NUM] , ~T_NUM);                //数码管刷段码和位码
        }
        else if( Seg_no ==4 )
        {
                Display_Seg( SEG_NUM] , ~T_NUM);                //数码管刷段码和位码
        }       
        else if( Seg_no ==5 )
        {
                Display_Seg( SEG_NUM] , ~T_NUM);                //数码管刷段码和位码
        }       
        else if( Seg_no ==6 )
        {
                Display_Seg( SEG_NUM] , ~T_NUM);                //数码管刷段码和位码
        }
        else if( Seg_no ==7 )
        {
                Display_Seg( SEG_NUM] , ~T_NUM);                //数码管刷段码和位码
        }       
        else
        {
               
        }
        Seg_no ++;
        if( Seg_no>7 )
                Seg_no=0;
}

u8 Key_Vol3 = 0;
u8 key_no =0 ;

void PW_write_Task(void)
{
        if( key_num <0xff )
        {
                Key_Vol3 ++;
                if( Key_Vol3 == 5 )
                {
                        if( key_no == 0 )
                        {
                                passward = 16;
                                passward = 16;
                                passward = 16;
                                passward = 16;
                                passward = 16;
                                passward = 16;
                                passward = 16;
                                passward = 16;                       
                        }                               
                        passward[ key_no] = key_num ;
                        key_no ++;
//                        passward = 17;       
                        if( key_no == 8 )                //密码输入到了八位
                        {
                                if((passward==1) && (passward==2) && (passward==3) && (passward==4) && (passward==5) && (passward==6) && (passward==7) &&(passward==0) )
                                {
                                        passward = 17;
                                        passward = 17;
                                        passward = 17;
                                        passward = 17;
                                        passward = 17;
                                        passward = 17;
                                        passward = 17;
                                        passward = 1;                                }
        else
        {
                Key_Vol3 = 0;
        }
}

YangHY 发表于 2025-12-29 12:41:06

第一个函数void SEG_Task(void)其实就是负责显示

不过这里有8位,就要考虑闪烁问题:

执行扫描的间隔不能太长


static TASK_COMPONENTS Task_Comps[]=
{
//状态计数周期函数
      

      
      {0, 10,10,   Task_1},      /* task 1 Period: 300ms */
      {0,1,   1,   SEG_Task},      /* task 1 Period: 300ms */      
      {0, 10,10,   PW_write_Task},
      
};

1ms就扫描一次

YangHY 发表于 2025-12-29 13:15:06

PW_write_Task()

函数是按键输入函数:

void PW_write_Task(void)
{
      if( key_num <0xff )
      {
                Key_Vol3 ++;
                if( Key_Vol3 == 5 )
                {
                        if( key_no == 0 )
                        {
                              passward = 16;
                              passward = 16;
                              passward = 16;
                              passward = 16;
                              passward = 16;
                              passward = 16;
                              passward = 16;
                              passward = 16;                        
                        }                              
                        passward[ key_no] = key_num ;
                        key_no ++;
//                        passward = 17;      //把显示1的位置清空
                        if( key_no == 8 )                //密码输入到了八位
                        {
                              if((passward==1) && (passward==2) && (passward==3) && (passward==4) && (passward==5) && (passward==6) && (passward==7) &&(passward==8) )
                              {
                                        passward = 17;//清空密码
                                        passward = 17;//清空密码
                                        passward = 17;//清空密码
                                        passward = 17;//清空密码
                                        passward = 17;//清空密码
                                        passward = 17;//清空密码
                                        passward = 17;//清空密码
                                        passward = 1;//清空密码,显示个1
                              }
      else
      {
                Key_Vol3 = 0;
      }
}

这个逻辑还是有点复杂,慢慢理解才行,首先这个键盘是矩阵按键


要和上面的实验连续起来才行,void Task_1(void)是每10ms执行一次

所以key_num会随时反应你按下的键值,这样联合思考,才能读懂上面的

void PW_write_Task(void)函数,我其实没有写过自己的体会,主要是觉得

现阶段只是看懂冲哥的程序,理解冲哥的意图........能完成这2个任务,都很

吃力。

YangHY 发表于 2025-12-29 13:37:43

出现一个小问题:
键盘上没有8

我们把密码中的8改为0:



YangHY 发表于 2025-12-29 13:47:20

经过以上修改,程序可以稳定运行

实验成功!

第十一课矩阵键盘到此结束

YangHY 发表于 2025-12-30 08:51:59

神农鼎 发表于 2025-11-30 21:33
要 做到 USB不停电下载;
要 尝试 图形化配置外设;
推荐优先看的 printf_usb("Hello World !\r\n")及usb不 ...

今天我们复习AiCube


先跟着李工看一遍她的操作:

如何利用这个智能配置开发工具来实验,自动辅助开发,程序自动生成的工具,快速的让单片机发送字符串到PC机 ?

当然上位机PC的程序STC也直接开发了串口助手,并且集中在ISP软件中:在李工带领下

我们要完成三个超简单的USB通信实验,及USB不停电下载:

当然是对李工来讲超简单:


实验一:直接输出,printf_usb("Hello World!\r\n")

实验二:查询方式,查询到电脑命令后,printf_usb("Hello World!\r\n")或其他

实验三:中断方式,单片机USB中断接收服务函数收到命令后,printf_usb("Hello World!\r\n")或其他




页: 34 35 36 37 38 39 40 41 42 43 [44] 45 46 47 48 49 50 51 52 53
查看完整版本: 第一课 序言《AI8051U的特点》