skyalong 发表于 2025-6-5 09:33:29

第十集 虚拟键盘LED和数码管
虚拟显示——LED      
任务1:P2口流水灯,P10闪烁
任务1代码
void Task1(void)
{
    u8 cod[8] = {0};
   
    cod[0] = 0x3f;//指定端口 xx11 1111 xxP5P4 P3P2P1P0
    cod[1] = 0xff;//P0 0000 0001
    cod[2] = (led_num % 2)|0xfe;//P1 0000 0010
    cod[3] = ~SEG_W;//P2 0000 0100
    cod[4] = 0xff;//P3 0101 0101
    cod[5] = 0xff;//P4 1010 1010
    cod[6] = 0xff;//P5 0101 0101
    LED40_SendData(cod, 7);
    led_num ++;
    if(led_num > 7)led_num = 0;
}

虚拟显示——数码管
   
任务2:左边数码管显示P32按下次数,右边数码管显示P33按下次数
任务2代码(做了修改,第4位加点显示做分割,默认显示0000.0000)
u8 key_num1 = 0;
u8 K32num = 0,K33num = 0;
void Task2(void)
{
    u8 cod[8];
    cod[0] = SEG_D/1000%10];
    cod[1] = SEG_D/100%10];
    cod[2] = SEG_D/10%10];
    cod[3] = (SEG_D%10])|0x80;
    cod[4] = SEG_D/1000%10];
    cod[5] = SEG_D/100%10];
    cod[6] = SEG_D/10%10];
    cod[7] = SEG_D%10];
    SEG7_ShowCode(cod);
    if(P32 == 0)
    {
      key_num++;
      if(key_num == 5)
      {
            K32num++;
      }   
    }else{key_num = 0;}
    if(P33 == 0)
    {
      key_num1++;
      if(key_num1 == 5)
      {
            K33num++;
      }   
    }else{key_num1 = 0;}
}

虚拟键盘

任务3:按下数字按键在数码管显示对
应的按键数字!
例:按下按键0数码管显示0;
任务3代码
void main(void)
{   
    Sys_init();
    usb_init();                                     //USB CDC 接口配置
    set_usb_OUT_callback(usb_callback);             //设置中断回调回调函数
   
    Init_595();
    Timer0_Init();
    EA = 1;
    while(1)
    {   
      Task_Pro_Handler_Callback();
      REC_NUM = UsbOutBuffer[5]-48;
    }
}
u16 REC_NUM = 0;
void Task3(void)
{
    SEG7_ShowLong(REC_NUM,10);
}

拓展代码
u8 cod = {16,16,16,16,16,16,16,16};
u8 cod1 ;
void Task3(void)
{      
      if(seg_num == 0)
      {
                cod = 0x40;
                cod = 0x40;
                cod = 0x40;
                cod = 0x40;
                cod = 0x40;
                cod = 0x40;
                cod = 0x40;
                cod = 0x40;
      }      
      cod = SEG_D;
      cod1 = REC_NUM;


      SEG7_ShowCode(cod);
      if(seg_num >= 8)
      {
                if(cod1 == 1&&cod1 == 2&&cod1 == 3&&cod1 == 4&&cod1 == 5&&cod1 == 6&&cod1 == 7&&cod1 == 8)
                {
                        cod = 0x40;
                        cod = 0x40;
                        cod = 0x5c;//o
                        cod = 0x73;//p
                        cod = 0x79;//e
                        cod = 0x54;//n
                        cod = 0x40;
                        cod = 0x40;               
                        
                        SEG7_ShowCode(cod);
                }else seg_num = 0;//8位结束回0
      }
      
}
工程代码

拓展代码工程














--哪怕梦想让我们拼的遍体鳞伤,这一次我们也要勇往直前






skyalong 发表于 2025-6-10 23:25:27

第十一集 矩阵按键
摘要1.矩阵按键的原理2.矩阵按键的程序实现原理    任务1代码
u8 key_board_num = 0xff;
void key_board(void)
{
COL1 = 0;
COL2 = 0;
COL3 = 0;
COL4 = 0;
ROW1 = 1;
ROW2 = 1;

if(ROW1 == 0||ROW2 == 0)
{
    if(ROW1 == 0&&ROW2 == 0){}
    else if((ROW1 == 1&&ROW2 ==0)||(ROW1 == 0&&ROW2 ==1))
    {
      if(ROW1 == 0){key_board_num = 0;}
      else if(ROW2 ==0){key_board_num = 4;}
   
      COL1 = 1;
      COL2 = 1;
      COL3 = 1;
      COL4 = 1;
      ROW1 = 0;
      ROW2 = 0;
      
      if(COL1 == 0){key_board_num = key_board_num + 1 -1;seg_num++;}
      if(COL2 == 0){key_board_num = key_board_num + 1;seg_num++;}
      if(COL3 == 0){key_board_num = key_board_num + 2;seg_num++;}
      if(COL4 == 0){key_board_num = key_board_num + 3;seg_num++;}
      printf("%d按键按下\r\n",key_board_num);
    }
    COL1 = 0;
    COL2 = 0;
    COL3 = 0;
    COL4 = 0;
    ROW1 = 1;
    ROW2 = 1;
}
else
{
    key_board_num = 0xff;
}
}
void key_Seg(void)
{
seg_num++;
if(seg_num >= 8)    seg_num = 0;//8位结束回0
Display_Seg(~SEG_W[0],SEG_D);
}


程序实现代码
void key_board(void)
{
COL1 = 0;
COL2 = 0;
COL3 = 0;
COL4 = 0;
ROW1 = 1;
ROW2 = 1;

if(ROW1 == 0||ROW2 == 0)
{
    if((ROW1 == 0)&&(ROW2 == 0)){}
    else if(((ROW1 == 1)&&(ROW2 ==0))||((ROW1 == 0)&&(ROW2 ==1)))
    {
      if(ROW1 == 0){key_board_num = 0;}
      else if(ROW2 ==0){key_board_num = 4;}
   
      COL1 = 1;
      COL2 = 1;
      COL3 = 1;
      COL4 = 1;
      ROW1 = 0;
      ROW2 = 0;
      
      if(COL1 == 0){key_board_num = key_board_num + 1 -1;}
      if(COL2 == 0){key_board_num = key_board_num + 1;}
      if(COL3 == 0){key_board_num = key_board_num + 2;}
      if(COL4 == 0){key_board_num = key_board_num + 3;}
      //printf("%d按键按下\r\n",key_board_num);
    }
    COL1 = 0;
    COL2 = 0;
    COL3 = 0;
    COL4 = 0;
    ROW1 = 1;
    ROW2 = 1;
}
else
{
    key_board_num = 0xff;
}
}
void key_Seg(void)
{
Display_Seg(~SEG_W,SEG_D[possward]);
led_num++;
if(led_num >= 8)    led_num = 0;//8位结束回0
}
void write_pow(void)
{
if(key_board_num < 0xff)
{
    key_num ++;
    if(key_num == 5)
    {
      if(seg_num == 0)
      {
      possward[0] = 16;
      possward[1] = 16;
      possward[2] = 16;//o
      possward[3] = 16;//p
      possward[4] = 16;//e
      possward[5] = 16;//n
      possward[6] = 16;
      possward[7] = 16;   
      }
      possward = key_board_num;
      seg_num ++;
      if(seg_num == 8)
      {
      if(possward[0] == 1&&possward[1] == 2&&possward[2] == 3&&possward[3] == 4&&possward[4] == 5&&possward[5] == 6&&possward[6] == 7&&possward[7] == 0)
      {
          possward[0] = 17;
          possward[1] = 1;
          possward[2] = 17;//o
          possward[3] = 1;//p
          possward[4] = 17;//e
          possward[5] = 1;//n
          possward[6] = 17;
          possward[7] = 1;   
      }
      else
      {
          possward[0] = 16;
          possward[1] = 16;
          possward[2] = 16;//o
          possward[3] = 16;//p
          possward[4] = 16;//e
          possward[5] = 16;//n
          possward[6] = 16;
          possward[7] = 16;   
      }
      seg_num = 0;
      }   
    }
}
else
{
    key_num = 0;
}
}


拓展代码包含洗衣机拓展









--哪怕梦想让我们拼的遍体鳞伤,这一次我们也要勇往直前

skyalong 发表于 2025-6-13 14:50:26

第十二集 复位系统
摘要1硬件复位2.软件复位
硬件复位            看门狗复位代码,按下按键跳过喂狗超时将复位WDT_CONTR = 0X24;//开启看门狗
    while(1)
    {   
      Task_Pro_Handler_Callback();
      //REC_NUM = UsbOutBuffer-48;//任务3
      if(P33 != 0)
            WDT_CONTR = 0X34;//喂狗
    }
软件复位代码,P32软件复位,P32软件复位并进入下载模式

void key(void)
{
    if(P32 == 0)
    {
      key_num++;
      if(key_num == 5)
      {
            //printf("按键按下\r\n");
            USB_Reset_U();
            IAP_CONTR = 0X20;//软件复位,不进入下载模式
      }   
    }
    else
    {
      key_num = 0;
    }
    if(P33 == 0)
    {
      key_num1++;
      if(key_num1 == 5)
      {
            //printf("按键按下\r\n");
            USB_Reset_U();
            IAP_CONTR = 0X60;//软件复位,进入下载模式
      }   
    }
    else
    {
      key_num1 = 0;
    }
}
课后小练
拓展代码:


            





--哪怕梦想让我们拼的遍体鳞伤,这一次我们也要勇往直前


skyalong 发表于 2025-6-18 15:56:41

第十三集 外部中断
摘要1.中断系统介绍2.外部中断介绍3.外部中断用法
中断系统介绍    外部中断      硬件复位任务1:编写外部中断1的程序任务代码:
void Delay3000ms(void)//@24.000MHz
{
    unsigned long edata i;

    _nop_();
    _nop_();
    i = 17999998UL;
    while (i) i--;
}
void INT1_Init(void)
{
    IT1 = 1;            //下降沿中断
    EX1 = 1;            //外部中断1允许
    EA = 1;             //打开总中断
}
void INT_ISR(void) interrupt 2
{
    P21 = !P21;
}
void main(void)
{   
    Sys_init();
    usb_init();                                     //USB CDC 接口配置
    set_usb_OUT_callback(usb_callback);             //设置中断回调回调函数
   
    Init_595();
    INT1_Init();
    Timer0_Init();
    EA = 1;
    //Task4();
   
    //WDT_CONTR = 0X24;//开启看门狗


    while(1)
    {   
      //Task_Pro_Handler_Callback();
      //REC_NUM = UsbOutBuffer-48;//任务3
      //if(P33 != 0)
      //WDT_CONTR = 0X35;//喂狗 超时时间1秒
      P20 = !P20;
      Delay3000ms();
    }
}
拓展拓展代码:
void INT1_Init(void)
{
    IT1 = 1;            //下降沿中断
    EX1 = 1;            //外部中断1允许
    EA = 1;             //打开总中断
}
void INT_ISR(void) interrupt 2
{
    P00 = 0;//关灯 光机停止工作 模拟保护
}
void key_start(void)
{
    COL1 = 0;
    COL2 = 0;
    COL3 = 0;
    COL4 = 0;
    ROW1 = 1;
    ROW2 = 1;
   
    if(ROW1 == 0||ROW2 == 0)
    {
      if((ROW1 == 0)&&(ROW2 == 0)){}
      else if(((ROW1 == 1)&&(ROW2 ==0))||((ROW1 == 0)&&(ROW2 ==1)))
      {   
            if(ROW1 == 0){key_board_num = 0;}
            else if(ROW2 ==0){key_board_num = 4;}
      
            COL1 = 1;
            COL2 = 1;
            COL3 = 1;
            COL4 = 1;
            ROW1 = 0;
            ROW2 = 0;
            
            if(COL1 == 0){key_board_num = key_board_num + 1 -1;}
            if(COL2 == 0){key_board_num = key_board_num + 1;}
            if(COL3 == 0){key_board_num = key_board_num + 2;}
            if(COL4 == 0){key_board_num = key_board_num + 3;}
            //printf("%d按键按下\r\n",key_board_num);
      }
      COL1 = 0;
      COL2 = 0;
      COL3 = 0;
      COL4 = 0;
      ROW1 = 1;
      ROW2 = 1;
    }
    else
    {
      key_board_num = 0xff;
    }
}
void main(void)
{   
    Sys_init();
    usb_init();                                     //USB CDC 接口配置
    set_usb_OUT_callback(usb_callback);             //设置中断回调回调函数
   
    Init_595();
    INT1_Init();
   
    Timer0_Init();
    EA = 1;
    //Task4();
   
    //WDT_CONTR = 0X24;//开启看门狗

    P0=0x00;
    while(1)
    {   
      //Task_Pro_Handler_Callback();
      //REC_NUM = UsbOutBuffer-48;//任务3
      //if(P33 != 0)
      //WDT_CONTR = 0X35;//喂狗 超时时间1秒
      key_start();
      if(key_board_num == 1)
      {
            P00 = 1;
      }
      //P20 = !P20;
      //Delay3000ms();
    }
}














--哪怕梦想让我们拼的遍体鳞伤,这一次我们也要勇往直前


skyalong 发表于 5 天前

第十四集 IO中断摘要1.IO中断介绍2.IO中断用法3.中断优先级的设置
IO中断介绍IO中断用法            任务1:编写IO中断的程序
代码:触发中断P20状态取反void P3_IO_Init(void)
{
P3IM0 = 0X00;   //IO中断模式设置为了下降沿
P3IM1 = 0X00;

P3INTE= 0x04;   //打开中断 7654 3210 8421 8421
}
void main(void)
{   
Sys_init();
usb_init();                                     //USB CDC 接口配置
set_usb_OUT_callback(usb_callback);             //设置中断回调回调函数
Timer0_Init();
P3_IO_Init();
EA = 1;

P20 = 1;
    while(1)
{
    P21 = !P21;
    Delay3000ms();
}
}
void P3_IO_ISR(void)interrupt 40
{
u8 intf;
intf = P3INTF;
if( intf )      //判断有没有IO触发了中断
{
    P3INTF = 0;
    if( intf & 0x04 )//判断是否是P32按钮按下
    {
      P20 = !P20;
    }
}
}
中断优先级设置

任务2:编写P4端口的IO中断 打断 P3低电平中断的的程序(注意优先级)代码:(将P4改为了P1,P1默认优先级比P3高,P1可以打断P3,P3不能打断P1;修改优先级后给予P3最高优先级后,P3可以打断P1)
void P3_IO_Init(void)
{
P3IM0 = 0X00;   //IO中断模式设置为了下降沿
P3IM1 = 0Xff;

P3INTE= 0x04;   //打开中断 P32 7654 3210 8421 8421

PINIPH|= 0x08;//写入最高优先级
PINIPL|= 0x08;
}
void P1_IO_Init(void)
{
P1IM0 = 0X00;   //IO中断模式设置为了下降沿
P1IM1 = 0Xff;

P1INTE= 0x04;   //打开中断 P12 7654 3210 8421 8421
}
void main(void)
{   
Sys_init();
usb_init();                                     //USB CDC 接口配置
    set_usb_OUT_callback(usb_callback);             //设置中断回调回调函数
    Init_595();
Timer0_Init();
P3_IO_Init();
P1_IO_Init();
EA = 1;

P20 = 1;
P22 = 1;
    while(1)
{
    //Task_Pro_Handler_Callback();      //执行功能函数
    Display_Seg(0xfe,0x3f);
}
}
void P3_IO_ISR(void)interrupt 40
{
u8 intf;
intf = P3INTF;
if( intf )      //判断有没有IO触发了中断
{
    P3INTF = 0;
    if( intf & 0x04 )//判断是否是P32按钮按下
    {
      Display_Seg(0xfe,0x5b);
    }
}
}
void P1_IO_ISR(void)interrupt 38
{
u8 intf;
intf = P1INTF;
if( intf )      //判断有没有IO触发了中断
{
    P1INTF = 0;
    if( intf & 0x04 )//判断是否是P32按钮按下
    {
      Display_Seg(0xfe,0x06);
    }
}
}
课后练习

练习代码:void P1_IO_Init(void)
{
P1IM0 = 0X00;   //IO中断模式设置为了下降沿
P1IM1 = 0Xff;

P1INTE= 0x07;   //打开中断 P12 7654 3210 8421 8421
}
void main(void)
{   
Sys_init();
usb_init();                                     //USB CDC 接口配置
    set_usb_OUT_callback(usb_callback);             //设置中断回调回调函数
    Init_595();
Timer0_Init();
//P3_IO_Init();
P1_IO_Init();
EA = 1;

P20 = 1;
P22 = 1;
    while(1)
{
    //Task_Pro_Handler_Callback();      //执行功能函数
    Display_Seg(0xfe,0x3f);
}
}
void P1_IO_ISR(void)interrupt 38
{
u8 intf;
intf = P1INTF;
if( intf )      //判断有没有IO触发了中断
{
    //P1INTF = 0;
    if( intf & 0x04 )//判断是否是P12按钮按下
    {
      Display_Seg(0xfe,0x4f);
      while(1);
    }
    if( intf & 0x02 )//判断是否是P11按钮按下
    {
      Display_Seg(0xfe,0x5b);
      while(1);
    }
    if( intf & 0x01 )//判断是否是P10按钮按下
    {
      Display_Seg(0xfe,0x06);
      while(1);
    }
}
}






--哪怕梦想让我们拼的遍体鳞伤,这一次我们也要勇往直前
页: 1 [2]
查看完整版本: 学习《Ai8051U教学视频》心得打卡