找回密码
 立即注册
查看: 3763|回复: 50

AI8051U教学视频课后小练 | 高质量打卡

[复制链接]
  • 打卡等级:常住居民III
  • 打卡总天数:110
  • 最近打卡:2025-05-02 16:57:27
已绑定手机

1

主题

60

回帖

283

积分

中级会员

积分
283
发表于 2025-1-15 18:31:26 | 显示全部楼层 |阅读模式
第一集 序言

两天前收到了“擎天柱”转接板,很漂亮。

我的擎天柱.jpg
STC的产品越来越强大了!技术支持也越来越全面。激发出了同学们的学习热情
     Ai32位8051
8 0 5 1  凌绝顶,核心算力在哪里 !
算力一日同风起,扶摇直上九万里 !
百兆硬件真浮点,三角函数运算器 !
神州春色三万里,封神榜永远是你 !
===老骥伏枥志在万里,我们再战三万里



回复

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:110
  • 最近打卡:2025-05-02 16:57:27
已绑定手机

1

主题

60

回帖

283

积分

中级会员

积分
283
发表于 2025-1-15 18:41:35 | 显示全部楼层
第三集 点亮第一颗LED
咱也从点亮第一颗LED开始吧。

IMG_20250115_183715.jpg

1 喜欢他/她就送朵鲜花吧,赠人玫瑰,手有余香!
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:110
  • 最近打卡:2025-05-02 16:57:27
已绑定手机

1

主题

60

回帖

283

积分

中级会员

积分
283
发表于 2025-1-15 22:52:28 | 显示全部楼层
第四集 USB不停电下载

AI8051U的USB不停电下载冲哥已经在视频里讲的很清楚了,同学们只要按部就班地一步步照抄就能顺利实现。
但8位U芯片不停电下载这次没有讲,以前有没有讲我不清楚,以前的课我只听了一点点。我手上正好有一片自制的STC8H8K64U核心板
IMG_20250115_223113.jpg
本来是一直用串口下载程序的,这次正好借机学习一下,也加个不停电下载程序。
原以为很简单,照搬就行,但过程说明不是完全照搬,自己摸索肯定也不会成功,后面看到了神***的贴子,才把问题解决了。
有两个关键点看图,其他的都问题不大。
1.png 2.png
Keil c程序.png
编译后有4K多代码,8K以下芯片只能量力而行。
ISP窗口.png
下载成功后,ISP下载接口显示“USB-CDC,CDC”




DEMO.c

1.7 KB, 下载次数: 37

回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:110
  • 最近打卡:2025-05-02 16:57:27
已绑定手机

1

主题

60

回帖

283

积分

中级会员

积分
283
发表于 2025-1-16 09:51:44 | 显示全部楼层
第六集 IO输入输出
这一集的课后小练题目是:
1,按一下P32按钮灯亮,按一下P33按钮灯灭;
2,按一下亮一颗灯,再按一下亮两颗灯,直到全亮。
第一个题目相对简单,我把两题要求做在一起了。用移位法比较直接,也可以用pow()幂函数来实现。
  1. //按一下第1个灯亮,再按一下第2个灯亮,再按一下第3个灯亮......一直到8个灯全亮,再按一下从头再来                        
  2.                 if( P32 == 0 )                                                                //判断P32按钮是否按下
  3.                 {
  4.                         Delay20ms();                                                        //延时20ms消抖
  5.                         if( P32 == 0 )
  6.                         {        
  7.                         //以下用移位法来实现此功能        
  8.                                 if(temp==0)                                
  9.                                 {
  10.                                         temp = 1;
  11.                                         temp =~temp;
  12.                                 }
  13.                                 else
  14.                                         temp <<= 1;
  15.                                  P2 = temp;        
  16.                                         while( P32 == 0 );                                        //等待P32松开                                
  17.                         }
  18.                 }
复制代码
  1. //按一下第1个灯亮,再按一下第2个灯亮,再按一下第3个灯亮......一直到8个灯全亮,再按一下从头再来                        
  2.                 if( P32 == 0 )                                                                //判断P32按钮是否按下
  3.                 {
  4.                         Delay20ms();                                                        //延时20ms消抖
  5.                         if( P32 == 0 )
  6.                         {        
  7.                         //以下用幂函数来实现
  8.                                 if(i<8)
  9.                                 {
  10.                                         num = pow(2,i)+num;        //用幂函数实现各位依次置一
  11.                                         i++;
  12.                                 }
  13.                                 else
  14.                                 {        
  15.                                         i = 0;
  16.                                         num = 0;                                       
  17.                                 }
  18.                                 P2 = ~num;
  19.                         //        printf("num: %x",num);
  20.                                 while( P32 == 0 );                                        //等待P32松开                                
  21.                         }                        
  22.                 }
  23.                         
复制代码
题目对于关灯的要求不多,我就自我发挥一点,当有多灯点亮后,按P33用移位法逐位熄灭。
  1.   //按一下依次灯灭
  2.                 if( P33 == 0 )                                                                //判断P33按钮是否按下
  3.                 {
  4.                         Delay20ms();                                                        //延时20ms消抖
  5.                         if( P33 == 0 )
  6.                         {                                
  7.                                 temp =~P2;
  8.                 if(temp)                                
  9.                                 {  
  10.                                         temp >>= 1;
  11.                                     P2 =~temp;
  12.                                 }
  13.                                 else
  14.                                   P2 = 0xff;
  15.                                 while( P33 == 0 );                                        //等待P33松开                                
  16.                         }
  17.                 }        
复制代码

main.c (2.62 KB, 下载次数: 35)
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:110
  • 最近打卡:2025-05-02 16:57:27
已绑定手机

1

主题

60

回帖

283

积分

中级会员

积分
283
发表于 2025-1-16 17:00:58 | 显示全部楼层
第七集-定时器配套程序 课后小练 电子功德箱:
1.按下按键1,串口显示“双倍功德时间”,再次按下显示“单倍功德时间”;
2.按下按键2,双倍功德时间下串口显示“功德+2 当前功德:xxx”;
3.按下按键2,单倍功德时间下串口显示“功德+1 当前功德:xxx”;
4.功德+1时,LED点亮1秒后熄灭表示功德成功点亮;
5.功德+2时,LED点亮2秒后熄灭表示功德成功点亮;
先上视频
  1. while(1)
  2.         {                        
  3.                 //按下按钮1,串口显示“双倍功德时间”,再次按下显示“单倍功德时间”,再次按下不断切换
  4.                 if( P32 == 0 )                                                                //判断P32按钮是否按下
  5.                 {
  6.                         Delay20ms();                                                        //延时20ms消抖
  7.                         if( P32 == 0 )
  8.                         {
  9.                                 Ds_State = !Ds_State;                                //单双切换
  10.                                 
  11.                                 if( Ds_State )                                        //Ds_State=1,为双
  12.                                         printf("双倍功德时间\r\n");
  13.                                 else                                                                //Ds_State=0,为单
  14.                                         printf("单倍功德时间\r\n");
  15.                                 while( P32 == 0 );                                        //等待P32松开
  16.                                 
  17.                         }
  18.                 }
  19.                 if( P33 == 0 )                                                                //判断P33按钮是否按下
  20.                 {
  21.                         Delay20ms();                                                        //延时20ms消抖
  22.                         if( P33 == 0 )
  23.                         {
  24.                                 if( Ds_State )                                                               
  25.                                 {
  26.                                         count =count+2;
  27.                                         printf("功德+2 当前功德:%d\r\n",(int)count);
  28.                                         P20 =0;
  29.                                         TR0 = 1;                                //定时器0开始计时
  30.                                         //Timer0_Init();
  31.                                 }
  32.                                 else
  33.                                 {
  34.                                         count =count+1;
  35.                                         printf("功德+1 当前功德:%d\r\n",(int)count);
  36.                                         P20 =0;
  37.                                         TR0 = 1;                                //定时器0开始计时
  38.                                         //Timer0_Init();
  39.                                 }
  40.                                 while( P33 == 0 );                                        //等待P32松开                                
  41.                         }
  42.                 }               
  43.         }
复制代码
这里说一下这个视频是怎么来的:下载了一个“一维科技”的EV虚拟摄像头,手机端和电脑端都安装这款软件,然后无线连接。
视频是用windows11系统自带的截图工具录制的。第一次这么操作,做的很粗糙。

main.c

3.14 KB, 下载次数: 34

回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:110
  • 最近打卡:2025-05-02 16:57:27
已绑定手机

1

主题

60

回帖

283

积分

中级会员

积分
283
发表于 2025-1-17 12:34:50 | 显示全部楼层
第九集 数码管  课后小练
简易10秒免单计数器
1. 在前四位数码管上显示目标时间,即“10.00”表示定时时间10秒。
2. 后四位显示当前的计时00.00,最小单位为10ms。
3. 按下开始按钮后,每10ms最末尾的数字+1;直到按下结束按钮后停止计数。
4. 后四位数码管显示当前时间,如果时间正好是停在了10.00,就可以免单。
还是先上视频,视频中的八位数码管是我手工焊出来的。

程序在冲哥DEMO 的基础上稍作修改:
主程序:
  1. while(1)
  2.         {               
  3.         if (bUsbOutReady)                                                        //如果接收到了数据
  4.         {
  5.           //USB_SendData(UsbOutBuffer,OutNumber);   //发送数据缓冲区,长度(接收数据原样返回, 用于测试)
  6.                         
  7.             usb_OUT_done();                                                        //
  8.         }
  9.                 Task_Pro_Handler_Callback();                                //执行功能函数
  10.                
  11.                 if(P32==0)                                                          //P32为开始按钮,按下时间清零,计时开始
  12.                 {                                                                                        //在io.h头文件中声明下面3个全局变量
  13.                         shihaomiao = 0;                                                        //extern u8 shihaomiao;
  14.                         miao = 0;                                                                //extern u8 miao;
  15.                         start = 1;                                                                 //extern  bit start;
  16.                  }
  17.                 if(P33==0)                                                                        //P33为结束按钮,按下计时停止
  18.                  {
  19.                     start = 0;
  20.                   }
  21.          }
  22. }
复制代码

io.c文件:
  1. u8 shihaomiao =0;
  2. u8 miao =0;
  3. bit start = 0;
  4. void Seg_Task(void)
  5. {
  6.         u8 num = 0;
  7.         if( Seg_no ==0 )                                                                //秒十位
  8.         {
  9.                 Display_Seg( SEG_NUM[1] , ~T_NUM[0]);                //数码管刷段码和位码
  10.         }
  11.         else if( Seg_no ==1 )                                                        //秒个位
  12.         {
  13.                 Display_Seg( SEG_NUM[0]+0x80 , ~T_NUM[1]);        //+0x80,是为了加入DP点显示
  14.         }        
  15.         else if( Seg_no ==2 )                                                        //百毫秒
  16.         {
  17.                 Display_Seg( SEG_NUM[0] , ~T_NUM[2]);                //数码管刷段码和位码
  18.         }        
  19.         else if( Seg_no ==3 )                                                        //十毫秒
  20.         {
  21.                 Display_Seg( SEG_NUM[0] , ~T_NUM[3]);                //数码管刷段码和位码
  22.         }
  23.         else if( Seg_no ==4 )//秒十位
  24.         {
  25.                 num = miao/10;
  26.                 Display_Seg( SEG_NUM[num] , ~T_NUM[4]);                //数码管刷段码和位码
  27.         }        
  28.         else if( Seg_no ==5 )//秒个位
  29.         {
  30.                 num = miao%10;
  31.                 Display_Seg( SEG_NUM[num]+0x80 , ~T_NUM[5]);//+0x80,是为了加入DP点显示
  32.         }        
  33.         else if( Seg_no ==6 )//百毫秒
  34.         {
  35.                 num = shihaomiao/10;
  36.                 Display_Seg( SEG_NUM[num] , ~T_NUM[6]);                //数码管刷段码和位码
  37.         }
  38.         else if( Seg_no ==7 )//十毫秒
  39.         {
  40.                 num = shihaomiao%10;
  41.                 Display_Seg( SEG_NUM[num] , ~T_NUM[7]);                //数码管刷段码和位码
  42.         }        
  43.         else
  44.         {
  45.                
  46.         }
  47.         Seg_no ++;
  48.         if( Seg_no>7 )
  49.                 Seg_no=0;
  50. }
  51. void TIMECOUNT_Task(void)
  52. {
  53.         if(start)
  54.          shihaomiao ++;
  55.         if( shihaomiao>99 )
  56.         {
  57.                 shihaomiao = 0;
  58.                 miao++;
  59.                 if( miao>59 )
  60.                 {
  61.                         miao = 0;
  62.                 }
  63.         }
  64. }
复制代码
task.c文件:
  1. static TASK_COMPONENTS Task_Comps[]=
  2. {
  3. //状态  计数  周期  函数
  4.         
  5. // {0, 300,   300,   LED0_Blink},      /* task 1 Period: 300ms */
  6. // {0, 600,   600,   LED1_Blink},      /* task 1 Period: 600ms */
  7. // {0, 900,   900,   LED2_Blink},      /* task 1 Period: 600ms */  
  8. // {0, 10,    10,    KEY_Task},        /* task 1 Period: 600ms */  
  9. {0,    1 ,  1   ,   Seg_Task},        /* task 1 Period: 600ms */
  10. {0,  10,  10,   TIMECOUNT_Task},   /* task 1 Period: 10ms   此处修改为10 */
复制代码
其余不变。
第9集 免单计shu器.zip (157.6 KB, 下载次数: 26)
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:110
  • 最近打卡:2025-05-02 16:57:27
已绑定手机

1

主题

60

回帖

283

积分

中级会员

积分
283
发表于 2025-1-17 22:24:19 | 显示全部楼层
加油!加油!加油!
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:110
  • 最近打卡:2025-05-02 16:57:27
已绑定手机

1

主题

60

回帖

283

积分

中级会员

积分
283
发表于 2025-1-18 22:07:06 | 显示全部楼层
第十集 虚拟LED数码管  课后小练

密码锁
1. 没有输入时,显示“- - - - - - - -”
2. 有输入时,按下一个按键,开始按顺序写入
     例如,第一个按下1,显示“1 - - - - - - - ”
     例如,第二个按下3,显示“1 3 - - - - - - ”
3. 当按下的密码为“1 2 3 4 5 6 7 8”时,数码管显示open的字符,否则,还是显示“- - - - - - - -”
题目要求比较简洁,考虑到如果前面几位按错了,不想8位全部按完就重新开始按,这种情况比较常见。
所以我增加了这部分的功能。下面还是先上视频。

main程序内先定义3个全局变量:

extern u32 REC_NUM;
extern u8 j , open ;

在config.h内调用头文件:    #include "string.h"     //memcmp()、memcpy()两函数需要。
  1. while(1)
  2.         {
  3.                
  4.         if (bUsbOutReady)                                                        //如果接收到了数据
  5.         {
  6.             if( UsbOutBuffer[5]==106)               //加入恢复起始状态的按键“*”,键值为106
  7.                         {
  8.                                 open = 0;
  9.                                 j = 0;
  10.                         }
  11.                         else
  12.                         {
  13.                                 REC_NUM = UsbOutBuffer[5]-48;       //把接收到的数字减48为需要的数值
  14.                             j++;
  15.                          }       
  16.             usb_OUT_done();                                                        //
  17.         }
  18.                 Task_Pro_Handler_Callback();                                //执行功能函数
  19.         }
复制代码
  1. #include "io.h"
  2. u8 State1 = 0;                                        //LED1初始状态
  3. u8 State2 = 0;                                        //LED2初始状态
  4. u8 State3 = 0;                                        //LED3初始状态
  5. u16 Key_Vol[3] ;                                //按键按下持续时间
  6. BYTE cod0[] = {0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40};                                   //数码管初始值显示“--------”
  7. BYTE cod[] =  {0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40};                                          //cod[]保存输入的数字               
  8. BYTE cod1[] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07,0x7F,0x6F,0x40};   // 0-9 段码数组
  9. BYTE cod2[] = {0x06, 0x5B, 0x4F, 0x66, 0x6D ,0x7D, 0x07, 0x7F};                                          // 密码数字
  10. BYTE cod3[] = {0x40, 0x40, 0x5c, 0x73, 0x79, 0x54, 0x40, 0x40};                                         //“--OPEN--”
  11. u32 REC_NUM = 10;      //起始值数码管显示“-”
  12. u8 j =0;
  13. u8 open =0;
  14. void TASK_1(void)
  15. {
  16.         if((open ==0)&&(j==0))  //起始状态
  17.                 memcpy(cod,cod0,8);       //将初始值cod0复制给cod,回到起始状态
  18.         if(open ==0)    //open=0 闭锁状态,open=1 开锁状态
  19.         {
  20.                 cod[j-1] = cod1[REC_NUM];                 //把收到的数字逐一存入cod[]中
  21.                 if(j==8)                                                 //如果按了8个数字
  22.                 {
  23.                         if(!memcmp(cod,cod2,8))      //比较cod与cod2两数组是否相等,若相等显示“--OPEN--”,不等显示初始值“--------”
  24.                         {
  25.                                 open = 1;
  26.                         }
  27.                 else
  28.                         {
  29.                                 memcpy(cod,cod0,8);       //将初始值cod0复制给cod,回到起始状态
  30.                                 SEG7_ShowCode(cod);                  //显示初始值“--------”
  31.                                 j = 0;
  32.                         }
  33.                 }       
  34.           else                  
  35.                 SEG7_ShowCode(cod); //显示输入的数字
  36.         }       
  37.         else
  38.         {
  39.                 SEG7_ShowCode(cod3);//显示“--OPEN--”
  40.                 memcpy(cod ,cod0,8);                             //将数组cod0的值复制给cod,等待下一次解锁
  41.                 j = 0;
  42.         }       
  43. }
复制代码
程序在冲哥第十课程序的基础上,稍作以上修改,其余不用动。
10.虚拟LED和SHU码管.zip (162.64 KB, 下载次数: 47)
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:110
  • 最近打卡:2025-05-02 16:57:27
已绑定手机

1

主题

60

回帖

283

积分

中级会员

积分
283
发表于 2025-1-19 08:44:48 | 显示全部楼层

有一个问题想请教一下:
STC_ISP 调试仿真接口下面的调试接口协议中,7段数码管接口的功能1:

在数码管上显示字符串,我研究了半天也没搞清楚,冲哥在课程里面也没有讲这一部分,
有没有哪位大神给解释一下?
屏幕截图 2025-01-19 083644.png

点评

和printf用法一样的,只是要考虑数码管不能显示一些特殊的字符和汉字等等,只要能显示的字符和数字就能直接当printf这么用~! [attachimg]81933[/attachimg]  详情 回复 发表于 2025-1-21 12:04
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:55
  • 最近打卡:2025-05-02 08:32:59

718

主题

1万

回帖

1万

积分

管理员

积分
15632
发表于 2025-1-19 09:16:06 | 显示全部楼层
回复 支持 反对

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2025-5-3 08:08 , Processed in 1.771258 second(s), 111 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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