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

【已送实验箱】LED点灯学习

[复制链接]
  • TA的每日心情
    开心
    3 天前
  • 签到天数: 108 天

    [LV.6]常住居民II

    9

    主题

    56

    回帖

    633

    积分

    高级会员

    积分
    633
     楼主| 发表于 2024-1-8 09:16:36 | 显示全部楼层
    第十三集    简易多任务处理



    应用模块化的编程(.c+.h)
    1、创建程序文件三步
       1.1新建文件并保存
       1.2添加工程
       1.3添加引用路径

    2、引用定义都在.h文件
             sbit 名称=P10;
             #define  名称 P10
    3、函数定义三步
         定义
         声明
         调用

    修饰符extern用在变量或者函数的声明前,用来说明”此变量/函数是在别处定义的,要在此处引用“ 。
    举例1:如果文件a.c需要引用b.c中变量int V,就可以在a.c中申明extern int V,然后就可以引用变量V.
    举例2:如果文件a.c需要引用b.c中变量int V,就可以在b.h中申明extern int V,然后a.c调用b.h就可以引用变量V.  
    注意extern修饰的变量不能赋初值

    4、bdata位寻址变量的使用
                
                         a.c                                                  a.h
    u8  bdata  LED  =0X00;                       exten  u8 bdata LED;
    sbit  LED0 = LED^0;                           exten  bit   LED0;
    sbit  LED1 = LED^1;                           exten  bit   LED1;

    5、用模块化编程方式将LED&数码管、按健、蜂鸣器、定时器集成在一个工程中,完成多个功能。
    6、模块化编程中讲了for循环应用
           u8  i=0;
           u8  t=0;
         for (i=0;i<8;i++)    //i<8,i后自加1次,条件为真,执行for循环内部语句,i=8,i不小于,条件不为成立,跳出循环语句。
         {   
               t++;  
          }
    7、讲了static用法
    void  SEG_fre(void )
    {
       static  u8  num = 0 ;//变量前有static修饰时, num赋初值只1次,下次就为1,再下次为2 。
       if(num<7)
       {
           ;
        }
       num++;
    }

    8、讲了按键状态机应用
    20.png




    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    开心
    3 天前
  • 签到天数: 108 天

    [LV.6]常住居民II

    9

    主题

    56

    回帖

    633

    积分

    高级会员

    积分
    633
     楼主| 发表于 2024-1-9 11:14:47 | 显示全部楼层

    第十四讲   矩阵按键
    1、讲了按键原理图
    截图202401091006205063.jpg

    按键识别原理:端口默认为高电平,实时读取到引脚为低电平是表示按下。
    第一步:现将P0.0-P0.3输出低电平,P0.6-P0.7输出高电平,如果有按键按下,按下的那一列的IO就会变成低电平,就可以判断出哪一列按下了。
    第二步:现将P0.0-P0.3输出高电平,P0.6-P0.7输出低电平,如果有按键下,按下的那一行的IO就会变成低电平,就可以判断出哪一行按下了。

    第三步:  行列组合一下就可判断出是哪一个按键按下了。

    2、矩阵按键部分程序
    /************延时函数*****************/
    void MateixKEY_delay(void)
    {
        u8 i =60;
       while(--i);
    }
    /*****矩阵按键读取当前是哪一个按钮按下*********/
    u8  MateixKEY_Read(void)
    {
         u8 keystate;                              //表示当前的按键的状态值
        //第一步:现将P0.0-P0.3输出低电平◇P0.6-P0.7输出高电平◇如果有按键按下◇
        MateixKEY  = 0xC0;                    //1100 0000
        MateixKEY_delay();

        keystate = ( MateixKEY ^ 0xC0);  // 0100 0000 ^1100 0000 =1000 000
      
       //第二步◇现将P0.0-P0.3输出高电平◇P0.6-P0.7输出低电平◇如果有按键按下,按下的那一行IO就会变成低电平。
       MateixKEY= OXOf;                     //0000 1111
       MateixKEY_delay();
       keystate |=(MateixKEY ^OX0f);     //0000  1110 ^ 00001111 = 0000 0001 | 1000 0000 =0x81。
      //第三步:行列组合一下就可以判断出是哪个按键按下了。
       printf("0x%02x\r\n",keystate);
       return keystate:


    }


    void  main()

          u8 KEY_NUM = 0; //
          sys_init () ;
          usb_init () ;
          Timer0_Init ();
          EA = 1;
          LED = 0XFF;
          while(1)
          {
             if(DeviceState !=DEVSTATE_CONFIGURED)
              continue;
             if( bUsbOutReady )
             {
              usb_OUT_done();
               }
             if(TIM_10MS_Flag==1 )
             {
                TIM_10MS_Flag=0;
                KEY_NUM=  MateixKEY_Read();
               SEG7 = void  main()

          u8 KEY_NUM = 0; //
          sys_init () ;
          usb_init () ;
          Timer0_Init ();
          EA = 1;
          LED = 0XFF;
          while(1)
          {
             if(DeviceState !=DEVSTATE_CONFIGURED)
              continue;
             if( bUsbOutReady )
             {
              usb_OUT_done();
               }
             if(TIM_10MS_Flag==1 )
             {
                TIM_10MS_Flag=0;
                KEY_NUM =  MateixKEY_Read();
                SEG7 = KEY_NUM;
             }

      }




    3、密码锁编程

    截图202401081945547949.jpg
    密码锁需求:1.通过LEDO模拟门锁状态,LED点亮表示门锁打开,熄灭表示门锁锁上2.增加8位数码管,可以动态
    显示8位的密码,无密码时显示“......"3.通过矩阵按键可以输入1-8的数字表示密码,并依次显示在数码管上;4.每
    输入一个数字,蜂鸣器响20ms表示有数字按下5.密码正确打开LED0,密码错误蜂鸣响2秒。#include "COMM/stc.h"
    #ifndef _ _ KEY_
    #define_ _ KEY_


    #include"COM/stc.h"

    #include"COM/usb.h"


    #define  KEY   P3   //P32-P35
    #define  KEY1  2  //按键1

    #define  KEY1  3  //按键2

    #define  KEY1  4  //按键3

    #define  KEY1  5  //按键4

    #define  MateixKEY   P0  //定义矩阵按键引脚



    #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  MateixKEY_Read(void)
    {
         u8 keystate;                              //表示当前的按键的状态值
         u8 key_val = 0;                          //表示当前按键的键码
        //第一步:现将P0.0-P0.3输出低电平◇P0.6-P0.7输出高电平◇如果有按键按下◇
        MateixKEY  = 0xC0;                    //1100 0000
        MateixKEY_delay();

        keystate = ( MateixKEY ^ 0xC0);  // 0100 0000 ^1100 0000 =1000 000
      
       //第二步◇现将P0.0-P0.3输出高电平◇P0.6-P0.7输出低电平◇如果有按键按下,按下的那一行IO就会变成低电平。
       MateixKEY= OXOf;                     //0000 1111
       MateixKEY_delay();
       keystate |=(MateixKEY ^OX0f);     //0000  1110 ^ 00001111 = 0000 0001 | 1000 0000 =0x81。
      //第三步:行列组合一下就可以判断出是哪个按键按下了。
       printf("0x%02x\r\n",keystate);
       switch(keystate)
       {  
            case 0x41  : key_val =1;
                    break;
            case 0x42  : key_val =2;
                    break;
            case 0x44  : key_val =3;
                    break;
            case 0x48  : key_val =4;
                    break;
            case 0x81  : key_val =5;
                     break;
            case 0x82  : key_val =6;
                     break;   
            case 0x84  : key_val =7;
                     break;
            case 0x88  : key_val =8;
                     break;
             default :   key_val =0;
                      break;
         }
    return keystate;
    }

    void  main()

          u8 KEY_NUM = 0; // 保存矩阵按键的键码
          u8 KEY_Str  =0;  //表示当前输入几个密码位
          sys_init () ;
          usb_init () ;
          Timer0_Init ();
          EA = 1;
          LED = 0XFF;
          while(1)
          {
             if(DeviceState !=DEVSTATE_CONFIGURED)
              continue;
             if( bUsbOutReady )
             {
              usb_OUT_done();
               }
             if(TIM_10MS_Flag==1 )
             {
                TIM_10MS_Flag=0;
                KEY_NUM =  MateixKEY_Read( );
                 if(KEY_NUM>0 )
                {
                  BEEP_ON(2);   //蜂鸣器2ms
                   Show_tab[KEY_str] = KEY_NUM;
                  KEY_Str++;
                    if(KEY_Str[0] ==1)&&(KEY_Str[1] ==2)&&(KEY_Str[2] ==3)&&(KEY_Str[3] ==4)&&(KEY_Str[4] ==5)&&(KEY_Str[5] ==6)&&(KEY_Str[6] ==7)
                    {
                            LED0 = 0; //灯亮
                    }   
                    else
                    {
                      BEEN_ON(200) ;//密码错误,蜂鸣器响2秒
                     }
                      SEG0=SEG1=SEG2=SEG3=SEG4=SEG5=SEG=6SEG7=21
                      }
                }
                KEY_NUM = 0;
          }








    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    开心
    3 天前
  • 签到天数: 108 天

    [LV.6]常住居民II

    9

    主题

    56

    回帖

    633

    积分

    高级会员

    积分
    633
     楼主| 发表于 2024-1-9 12:51:42 | 显示全部楼层
    第15集 外部中断

    1、中断系统

    中断系统是为使CPU具有对外界紧急事件的实时处理能力而设置的。
    当中央处理机 CPU正在处理某件事的时候外界发生了紧急事件请求,要求CPU暂停当前的工作,转而去处理这个紧急事件,处理完以后,
    再回到原来被中断的地方,继续原来的工作,这样的过程称为中断。实现这种功能的部件称为中断系统,请示CPU中断的请求源称为中2、什么是外部中断

    外部中断就是在单片机的一个引脚上,由于外部因素导致了一个电平的变化(比如由高变低),而通过捕获这个变化,单片机内部自主运行的
    程序就会被暂时打断,转而去执行相应的中断处理程序,执行完后又回到原来中断的地方继续执行原来的程序。


    3、外部中断使用方法
    截图202401091239338080.jpg
       截图202401091240208295.jpg
       截图202401091240537941.jpg
       截图202401091241184723.jpg


    4、外部部分程序

    void  INT0_Init(void)
    {
        IT0 = 1;//下降沿中断
        EX0 = 1;//允许中断
        IE0 = 0;//清除中断标志位
    }


    void  main()

          u8 KEY_NUM = 0;
          sys_init () ;
          usb_init () ;
          Timer0_Init ();
           INT0_Init( );
           EA = 1;
          LED = 0XFF;
          while(1)
          {
             if(DeviceState !=DEVSTATE_CONFIGURED)
              continue;
             if( bUsbOutReady )
             {
              usb_OUT_done();
               }
              for(i=0;i<8;i++)
              {
                LED =(1<<i);
                 delay_ms(500);
              }
              if( P33 == 0  )
              SEG1 +=1;
         }

    }
         
    void   INT0_ Isr (void)  interrupt  0
    {
              SEG0  +=1;   
    }   
       






    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    开心
    3 天前
  • 签到天数: 108 天

    [LV.6]常住居民II

    9

    主题

    56

    回帖

    633

    积分

    高级会员

    积分
    633
     楼主| 发表于 2024-1-10 08:14:29 | 显示全部楼层
    第16集 IO中断

    1、外部中断与IO中断区别
        外部中断适用用单此信号,检测信号上升沿或下降沿。  
        IO口中断适用于持续进入中断信号,检测信号为高电平或低电平,如按键一直按下信号。

    2、什么是IO口中断
    截图202401100812088062.jpg
    截图202401100813113162.jpg

    截图202401100814029036.jpg


    3、实例-简易中央门禁控制系统
    1).用8个按键代表每个门的门锁开关,8个LED作为每个门的工作状态,点亮表示门已经打开,熄灭表示门打开。
    2).如遇突发火灾,按下应急按钮立刻打开所有门锁,方便人逃生。
    3).按下应急按钮后,所有按钮门锁不能上锁
    4).松开应急按钮后,倒计时5秒后恢复之前的状态,并可以操作门锁,

    简易中央门禁控制系统部分程序

    u16  Tme_countDown =0;
    void  Time0_init (void)   //1毫秒,24MHZ, 12分频
    {
       AUXR &=  0X7F;
       TMOD &= 0XF0;

        TL0 = 0X30;
        TH0 = 0XF8;
        TF0 =0;
         TR0 = 1;
         ET0 = 1;
         IP = 0X02; //设置为最高优先集
         IPH =0X02;
    }


    void  P3Exit_Init(void)
    {
        P3IM0 = 0X00;
        P3IM1 = 0XFF;   //低电平中断
       P3INTE = 0X20;  //P35中断  0010  0000
    }

    void  main()

          u8  LOCK_State =0xff;//门锁工作状态
          u8 KEY_NUM = 0; // 保存矩阵按键的键码
          u8 KEY_Str  =0;  //表示当前输入几个密码位
          sys_init () ;
          usb_init () ;
          Timer0_Init ();
           P3Exit_Init();
          EA = 1;
          LED =LOCK_State ;
          while(1)
          {
             if(DeviceState !=DEVSTATE_CONFIGURED)
              continue;
             if( bUsbOutReady )
             {
              usb_OUT_done();
               }
             if(TIM_10MS_Flag==1 )
             {
                TIM_10MS_Flag=0;
                if( Tme_countDown ==0)
                {
                    KEY_NUM =  MateixKEY_Read( );
                     BEEP_RUN();
                     if(KEY_NUM>0 )
                     {

                       BEEP_ON(2);   //蜂鸣器2ms

                        LOCK_State  ^= (1<<   KEY_NUM-1)  //获取当前第几个按键按下,(1-8)-1

                       }

                       LED =   LOCK_State;

                       SEG0 = 20;// 熄灭数码管

                    }

                   else

                   {

                     Tme_countDown--;

                     SEG0 = Tme_countDown/100+1;   // 500/100   499


                     }   

                  }
               }      
          }         
                  
    void  P3Exit)_Isr(void)    interrupt   40
    {
        u8 intf ;
         intf = P3INIF ;//读取中断标志位
       if( intf)
       {
          P3INIF =0;
          if(intf &0x20) //P35按键按下   0010 0000
          {
              LED =0X00;  //打开所有门锁
              SEG0 = 5 ;  //数码管持续显示5
               Tme_countDown = 500;
           }
       }

    }

    截图202401100813364319.jpg
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    开心
    3 天前
  • 签到天数: 108 天

    [LV.6]常住居民II

    9

    主题

    56

    回帖

    633

    积分

    高级会员

    积分
    633
     楼主| 发表于 2024-1-10 10:45:11 | 显示全部楼层
    第二集  开发板有哪些功能

    1、开发板功能有:LED点灯、数码管显示、电压比较、红外发射、红外接收、蜂鸣器、调试接口、RS232电路、FLASH扩展、232接口、USB接口、LED、LCD接口、独立按键、矩阵按键、24C02、DAC、PWM模拟、基准电压、ADC、18B20、
    NTC测温。
    2、讲了STC32G12K128单片机资源。
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    开心
    3 天前
  • 签到天数: 108 天

    [LV.6]常住居民II

    9

    主题

    56

    回帖

    633

    积分

    高级会员

    积分
    633
     楼主| 发表于 2024-1-10 10:55:11 | 显示全部楼层
    第三集  开发环境搭建和程序下载

    1、讲了KEIL安装和使用
    2、讲了STC_ISP程序下载
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    开心
    3 天前
  • 签到天数: 108 天

    [LV.6]常住居民II

    9

    主题

    56

    回帖

    633

    积分

    高级会员

    积分
    633
     楼主| 发表于 2024-1-10 10:55:12 | 显示全部楼层
    第三集  开发环境搭建和程序下载

    1、讲了KEIL安装和使用
    2、讲了STC_ISP程序下载
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    开心
    3 天前
  • 签到天数: 108 天

    [LV.6]常住居民II

    9

    主题

    56

    回帖

    633

    积分

    高级会员

    积分
    633
     楼主| 发表于 2024-1-11 11:07:13 | 显示全部楼层
    本帖最后由 17141200320 于 2024-1-11 15:15 编辑

    第十七集  模数转化器ADC


    1.模数转换器是什么:
         模数转换器即A/D转换器,或简称ADC (Analog-to-、digital converter),通常是指一个将模拟信号转变为数字信号的电子元件。
    模拟信号 ->电压.
    数字信号 -> 0和1组成的二进制数

    利用图形和表格方式描述了AD转化过程
    截图202401111102583119.jpg

    截图202401111103261874.jpg





    截图202401111104031031.jpg





    截图202401111105153584.jpg
    截图202401111106139198.jpg
    截图202401111107042192.jpg







    2、ADC查询方式部分程序
    #define  ADC_CHECK  0  //查询
    #define  ADC_Isr     1     //中断
    #define  ADC_FUNC     ADC_Isr   // 最终选择

    # if   ADC_FUNC  ==  ADC_CHECK
    void  ADC_Init(void)   //查询ADCC初始化
    {
        P1M0 = 0x00;
        P1M1 =0X01;   //设置P10为高阻输入
        ADCTIM = 0X3F;
        ADCCFG =0X2F;   //数据右对齐,时钟选择sysclk/2/16最慢
       ADC_POWER = 1;
    }



    u16 ADC_Read(u8 no)
    {
      u16 adcval;
       ADC_CONTER &= 0Xf0;   //清空通道
       ADC_CONTTER  |= no;   //选择通道
       ADC_Start = 1;               //开启ADC转化
        _nop_();                       //空操作指令

        _nop_();
      while(!ADC_FLAG);          //等待ADC转换结束
      ADC_FLAG = 0;
      adcval = (ADC_RES<<8)+ADC_RESL;   
      return   adcval;
    }


    u16 ADC_CAL_Voltage(u16 num)   //转换电压
    {
       return  num*2.5*1000/4096;
    }

    void  main()

          u8 KEY_NUM = 0; //
          sys_init () ;
          usb_init () ;
          Timer0_Init ();
           ADC_Init();
          EA = 1;
          LED = 0XFF;
          while(1)
          {
             if(DeviceState !=DEVSTATE_CONFIGURED)
              continue;
             if( bUsbOutReady )
             {
              usb_OUT_done();
               }
             if(TIM_10MS_Flag==1 )
             {
                TIM_10MS_Flag=0;
                 ADC_VAL = ADC_Read();
                 Printf ("当前ADC数\xfd值:%d\r\n ",(int)ADC_VAL ,   (int)ADC_CAL_Voltage(ADC_VAL));    //ad值和相对的电压
             }

      }


    #else if   ADC_FUNC  ==  ADC_Isr


    void  ADC_Init(void)   //ADC中断初始化
    {
        P1M0 = 0x00;
        P1M1 =0X01;   //设置P10为高阻输入
        ADCTIM = 0X3F;
        ADCCFG =0X2F;   //数据右对齐,时钟选择sysclk/2/16最慢
       ADC_POWER = 1;
        EADC = 1;
    }

    void  ADC_Isr(void)  interrupt  5
    {
          ADC_FLAG = 0;
          ADC_VAL=   (ADC_RES<<8)+ADC_RESL;  
          ADC_Start = 1;
    }

    #else
    #endif










    回复 支持 反对 送花

    使用道具 举报

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

    本版积分规则

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

    GMT+8, 2024-6-3 05:25 , Processed in 0.066716 second(s), 57 queries .

    Powered by Discuz! X3.5

    © 2001-2024 Discuz! Team.

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