找回密码
 立即注册
查看: 472|回复: 10

打卡学习《Ai8051U深度入门大型实战视频》

[复制链接]
  • 打卡等级:偶尔看看I
  • 打卡总天数:10
  • 最近打卡:2025-02-16 09:38:48
已绑定手机

2

主题

21

回帖

90

积分

注册会员

积分
90
发表于 2025-2-2 15:27:11 | 显示全部楼层 |阅读模式
第一集:讲解了8051U的新功能

突出介绍了Ai8051U的强大功能

1.png
回复

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:10
  • 最近打卡:2025-02-16 09:38:48
已绑定手机

2

主题

21

回帖

90

积分

注册会员

积分
90
发表于 2025-2-2 15:44:38 | 显示全部楼层
第二集


讲解了Ai8051U实验箱硬件和软件开发工具

1.jpeg
2.jpeg

软件下载工具

3.jpeg



回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:10
  • 最近打卡:2025-02-16 09:38:48
已绑定手机

2

主题

21

回帖

90

积分

注册会员

积分
90
发表于 2025-2-3 13:28:32 | 显示全部楼层
第三集 点亮第一颗LED

从本讲开始要写实际的代码了。

相对来说,代码比较简单,容易理解,有C语言基础就行。
  1. #include "ai8051u.h"                //调用头文件
  2. void main(void)
  3. {
  4.         P2M0 = 0;                //P2端口(P20-P27)为准双向口
  5.         P2M1 = 0;
  6.         while(1)
  7.         {
  8.                 P20 = 0;        //P20端口输出0V
  9.                 P27 = 0;        //P27端口输出0V
  10.         }
  11. }
复制代码


回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:10
  • 最近打卡:2025-02-16 09:38:48
已绑定手机

2

主题

21

回帖

90

积分

注册会员

积分
90
发表于 2025-2-3 13:34:40 | 显示全部楼层
第四集 USB不停电下载

上一讲中的代码下载,需要反复按电源键和p3.2按键才能正常下载。
本讲实现了开发板不停电下载,免去了反复按键的麻烦,非常实用。提高了开发效率。


要实现这个功能,就需要调用官方提供的usb库。要将这个库加入项目中。


上代码:



#include "ai8051u.h"
#include "stc32_stc8_usb.h" //新增调用USB头文件

char *USER_DEVICEDESC = NULL;
char *USER_PRODUCTDESC = NULL;
char *USER_STCISPCMD = "@STCISP#";

void main(void)
{
    P_SW2 |= 0x80; // B7位写1,使能访问XFR

    // ...

    usb_init(); // 初始化 USB CDC 接口配置

    IE2 |= 0x80; // 使能USB中断
    EA = 1;      // IE |= 0X80;

    while (DeviceState != DEVSTATE_CONFIGURED)
        ; // 等待USB完成配置

    while (1)
    {

        if (bUsbOutReady)
        {
            usb_OUT_done();
        }

        P20 = 0; // P00端口输出0V
        P22 = 0; // P02端口输出0V
    }
}



回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:10
  • 最近打卡:2025-02-16 09:38:48
已绑定手机

2

主题

21

回帖

90

积分

注册会员

积分
90
发表于 2025-2-3 13:39:19 | 显示全部楼层
第五集 C语言基础

使用STC-USB库实现的printf函数,可以直接与上位机通信,方便调试及与单片机交互。

代码:

#include "ai8051u.h"        //调用头文件
#include "stc32_stc8_usb.h" //调用头文件

#define u8 unsigned char // 8位无符号变量(0-255)
#define u16 unsigned int // 16位无符号变量(0-65535)

char *USER_DEVICEDESC = NULL;
char *USER_PRODUCTDESC = NULL;
char *USER_STCISPCMD = "@STCISP#";

void main(void)
{
    P_SW2 |= 0x80; // B7位写1,使能访问XFR

    // ...

    usb_init(); // USB CDC 接口配置

    IE2 |= 0x80; // 使能USB中断
    EA = 1;      // IE |= 0X80;

    while (DeviceState != DEVSTATE_CONFIGURED)
        ; // 等待USB完成配置

    while (1)
    {

        if (bUsbOutReady) // 如果接收到了数据
        {
            printf("向上位机发送的信息\r\n");    // 发送消息给上位机
            usb_OUT_done();
        }
    }
}



回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:10
  • 最近打卡:2025-02-16 09:38:48
已绑定手机

2

主题

21

回帖

90

积分

注册会员

积分
90
发表于 2025-2-3 13:48:18 | 显示全部楼层
第六集 I/O输入输出


本集简要介绍了GPIO,高电平、低电平的概念。

并通过将按键接入IO端口进行了讲解。
图片1.png
最后用3个小任务,以实例的形式介绍了通过检测按键,控制led的亮和灭。

上代码:

#include "ai8051u.h"        //调用头文件
#include "stc32_stc8_usb.h" //调用头文件
#include "intrins.h"        //d调用头文件

#define u8 unsigned char // 8位无符号变量(0-255)
#define u16 unsigned int // 16位无符号变量(0-65535)

u8 state = 0; // 初始状态

char *USER_DEVICEDESC = NULL;
char *USER_PRODUCTDESC = NULL;
char *USER_STCISPCMD = "@STCISP#";

void Delay20ms(void) //@24.000MHz  Delay20ms();
{
    unsigned long edata i;

    _nop_();
    _nop_();
    i = 119998UL;
    while (i)
        i--;
}

void main(void)
{
    WTST = 0;  // 设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
    EAXFR = 1; // 扩展寄存器(XFR)访问使能
    CKCON = 0; // 提高访问XRAM速度

    // ...

    usb_init(); // USB CDC 接口配置

    IE2 |= 0x80; // 使能USB中断
    EA = 1;      // IE |= 0X80;

    P40 = 0;

    while (DeviceState != DEVSTATE_CONFIGURED)
        ; // 等待USB完成配置

    while (1)
    {

        if (bUsbOutReady) // 如果接收到了数据
        {
            usb_OUT_done(); //
        }

        // 任务1:按下P32按钮灯亮,松开P32按钮灯灭;
        if (P32 == 0) // 判断P32按钮是否按下
        {
            P00 = 0;
        }
        else
        {
            P00 = 1;
        }

        // 任务2:按下P32按钮灯灭,松开P32按钮灯亮;
        if (P32 == 1) // 判断P32按钮是否按下
        {
            P00 = 0;
        }
        else
        {
            P00 = 1;
        }

        // 任务3:按一下灯亮,按一下灯灭
        if (P32 == 0) // 判断P32按钮是否按下
        {
            Delay20ms(); // 延时20ms消抖
            if (P32 == 0)
            {
                state = !state; // 变量取反 0 1 0 1 0 1
                P00 = state;
                printf("state:%d\r\n", (int)state);

                while (P32 == 0)
                    ; // 等待P32松开
            }
        }
    }
}



回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:10
  • 最近打卡:2025-02-16 09:38:48
已绑定手机

2

主题

21

回帖

90

积分

注册会员

积分
90
发表于 2025-2-3 14:15:28 | 显示全部楼层
第七集 定时器


在本集中,冲哥给我们讲解的单片机的重要部件之一:定时器。那什么是定时器,能干什么?翻阅数据手册:

Ai8051U 系列单片机内部设置了 6 24 位定时器/计数器(8 位预分频+16 位计数)6 16 位定时器 T0T1T2T3T4 T11 都具有计数方式和定时方式两种工作方式。

定时器/计数器 0 4 种工作模式:模式 016 位自动重装载模式),模式 116 位不可重装载模式),模式 28 位自动重装模式),模式 3不可屏蔽中断的 16 位自动重装载模式)。
定时器/计数器 1 除模 3 外,其他工作模式与定时器/计数器 0 相同。T1 在模式 3 时无效,停止计数。
定时器 T2 的工作模式固定为 16 位自动重装载模式。T2 可以当定时器使用,也可以当串口的波特率发生器和可编程时钟输出。
定时器 3、定时器 4、定时器 11 与定时器 T2 一样,它们的工作模式固定为 16 位自动重装载模式。T3/T4可以当定时器使用,也可以当串口的波特率发生器和可编程时钟输出。
定时器 11 的工作模式固定为 16位自动重装载模式。T11 可以当定时器使用,也可编程时钟输出。

在实际项目中,STC-ISP工具给我们提供了一个便捷工具,帮助我们快速计算定时数据:

图片1.png

①:在下载软件中选择“定时器计算器”功能页,进定时器代码生成界面
②:设置系统工作频率(单位:MHz
③:设置定时时间长度(单位:毫秒/微秒
④:选择目标定时器,并设置定时器工作模式
⑤:选择是否需要使能定时器中断
⑥:手动生成 C 代码或者 ASM 代码,复制范例


最后,通过3个小任务给出了具体应用实例:

  1.   // 任务1:
  2.                 if (P32 == 0) // 判断P32按钮是否按下
  3.                 {
  4.                         Delay20ms(); // 延时20ms消抖
  5.                         if (P32 == 0)
  6.                         {
  7.                                 printf("按键按下次数\xfd:%d 次\r\n", (int)count);
  8.                                 count++;
  9.                                 while (P32 == 0)
  10.                                         ; // 等待P32松开
  11.                         }
  12.                 }
  13. // 任务2:灯按一下点亮三秒后熄灭。
  14.                 if (P32 == 0) // 判断P32按钮是否按下
  15.                 {
  16.                         Delay20ms(); // 延时20ms消抖
  17.                         if (P32 == 0)
  18.                         {
  19.                                 printf("按键按下次数\xfd:%d 次\r\n", (int)count);
  20.                                 count++;
  21.                                 P00 = 0;
  22.                                 Timer0_Init();
  23.                                 while (P32 == 0)
  24.                                         ; // 等待P32松开
  25.                         }
  26.                 }
  27. // 任务3:救护车灯控制器,按下报警按钮,红蓝交替闪烁(LED1和LED2表示红和蓝灯),再按一下报警按钮,红蓝灯停止。
  28.                 if (P32 == 0) // 判断P32按钮是否按下
  29.                 {
  30.                         Delay20ms(); // 延时20ms消抖
  31.                         if (P32 == 0)
  32.                         {
  33.                                 Run_State = !Run_State; // 运行状态取反
  34.                                 if (Run_State == 1) // 运行
  35.                                 {
  36.                                         Timer0_Init();
  37.                                 }
  38.                                 else
  39.                                 {
  40.                                         TR0 = 0; // 关闭定时器
  41.                                         P00 = 1;
  42.                                         P01 = 1;
  43.                                 }
  44.                                 while (P32 == 0)
  45.                                         ; // 等待P32松开
  46.                         }
  47.                 }
复制代码




回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:10
  • 最近打卡:2025-02-16 09:38:48
已绑定手机

2

主题

21

回帖

90

积分

注册会员

积分
90
发表于 2025-2-3 14:35:41 | 显示全部楼层
第八集 周期性调度任务


本集接续上一集,用定时器来实现周期性的任务调度,避免了用循环方法,释放单片机资源,提高系统响应速度,改善用户体验。

通过实现三个任务,冲哥深入浅出地讲解了如何用定时器来周期性地调度这些任务:

任务1:用一个定时器实现这个任务。LED1实现0.3秒取反一次,LED2实现0.6秒取反一次,LED3 0.9秒取反一次
任务2:数组点亮LED,实现流水灯
任务3:按键按一下,LED通过数组移动一下;


在代码实现中,通过数组的方式来定义任务:
  1. static TASK_COMPONENTS Task_Comps[] = {
  2.     // 状态  计数  周期  函数
  3.     {0, 300, 300, LED0_Blink}, /* task 1 Period: 300ms */
  4.     {0, 600, 600, LED1_Blink}, /* task 1 Period: 600ms */
  5.     {0, 900, 900, LED2_Blink}, /* task 1 Period: 600ms */
  6.     {0, 10, 10, KEY_Task},     /* task 1 Period: 600ms */
  7. };
复制代码

任务回调处理代码:
  1. u8 Tasks_Max = sizeof(Task_Comps) / sizeof(Task_Comps[0]);
  2. void Task_Pro_Handler_Callback(void)
  3. {
  4.     u8 i;
  5.     for (i = 0; i < Tasks_Max; i++)
  6.     {
  7.         if (Task_Comps[i].Run) /* If task can be run */
  8.         {
  9.             Task_Comps[i].Run = 0;    /* Flag clear 0 */
  10.             Task_Comps[i].TaskHook(); /* Run task */
  11.         }
  12.     }
  13. }
复制代码


回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:10
  • 最近打卡:2025-02-16 09:38:48
已绑定手机

2

主题

21

回帖

90

积分

注册会员

积分
90
发表于 2025-2-3 14:57:42 | 显示全部楼层
第九集 数码管


本集讲解了

1.数码管介绍
2.数码管显示原理
3.数码管静态显示
4.数码管动态显示
5.虚拟显示——LED和数码管

八段数码管由8个发光二极管构成,通过不同的组合可用来显示数字0~9、字符A~F和小数点“.”。分为共阳极和共阴极两种结构


截图202502031456018058.jpg



如果静态显示8位数码管,至少需要占用8*8+3位IO端口,非常浪费宝贵的端口资源。
在实际的项目中,多采用动态显示模式。利用人眼的视觉暂留原理,逐位动态扫描显示,可以达到多位视觉上同时显示的效果。
在实际的实现中,还需要注意消隐,改善视觉效果。


代码:
  1. void Send_595(u8 dat)
  2. {
  3.         u8 i;
  4.         for (i = 0; i < 8; i++)
  5.         {
  6.                 dat <<= 1;                // DAT = (DAT<<1);        //CY
  7.                 HC595_SER = CY; // 先把数据写到引脚上
  8.                 HC595_SCK = 1;        // 输出上升沿的时钟信号
  9.                 HC595_SCK = 0;
  10.         }
  11. }
  12. void Display_Seg(u8 HC595_1, u8 HC595_2)
  13. {
  14.         Send_595(HC595_1); // 数码管段码输出  高电平点亮
  15.         Send_595(HC595_2); // 数码管位码      低电平点亮
  16.         HC595_RCK = 1; // 数据输出
  17.         HC595_RCK = 0;
  18. }
  19. void Seg_Task(void)
  20. {
  21.         u8 num = 0;
  22.         if (Seg_no == 0) // 小时十位
  23.         {
  24.                 num = shi / 10;
  25.                 Display_Seg(SEG_NUM[num], ~T_NUM[0]); // 数码管刷段码和位码
  26.         }
  27.         else if (Seg_no == 1) // 小时的个位
  28.         {
  29.                 num = shi % 10;
  30.                 Display_Seg(SEG_NUM[num], ~T_NUM[1]); // 数码管刷段码和位码
  31.         }
  32.         else if (Seg_no == 2) // 第一个横杠
  33.         {
  34.                 Display_Seg(SEG_NUM[16], ~T_NUM[2]); // 数码管刷段码和位码
  35.         }
  36.         else if (Seg_no == 3) // 分钟的十位
  37.         {
  38.                 num = fen / 10;
  39.                 Display_Seg(SEG_NUM[num], ~T_NUM[3]); // 数码管刷段码和位码
  40.         }
  41.         else if (Seg_no == 4)
  42.         {
  43.                 num = fen % 10;
  44.                 Display_Seg(SEG_NUM[num], ~T_NUM[4]); // 数码管刷段码和位码
  45.         }
  46.         else if (Seg_no == 5)
  47.         {
  48.                 Display_Seg(SEG_NUM[16], ~T_NUM[5]); // 数码管刷段码和位码
  49.         }
  50.         else if (Seg_no == 6)
  51.         {
  52.                 num = miao / 10;
  53.                 Display_Seg(SEG_NUM[num], ~T_NUM[6]); // 数码管刷段码和位码
  54.         }
  55.         else if (Seg_no == 7)
  56.         {
  57.                 num = miao % 10;
  58.                 Display_Seg(SEG_NUM[num], ~T_NUM[7]); // 数码管刷段码和位码
  59.         }
  60.         else
  61.         {
  62.         }
  63.         Seg_no++;
  64.         if (Seg_no > 7)
  65.                 Seg_no = 0;
  66. }
复制代码



回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:10
  • 最近打卡:2025-02-16 09:38:48
已绑定手机

2

主题

21

回帖

90

积分

注册会员

积分
90
发表于 2025-2-3 16:39:53 | 显示全部楼层

第十集 虚拟LED数码管

手上只有擎天柱的朋友有福了!AIAPP-ISP提供了虚拟功能!

先准备好三件套:

图片1.png

isp提供的虚拟功能为快速调试提供了便利条件。

  1. 虚拟显示——LED

11.PNG

2 虚拟显示——数码管

22.PNG

3 虚拟键盘

33.PNG

回复 支持 反对

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2025-6-19 05:33 , Processed in 0.159328 second(s), 95 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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