找回密码
 立即注册
查看: 592|回复: 9

学习《8051U深度入门到32位51大型实战教学视频》

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

1

主题

12

回帖

71

积分

注册会员

积分
71
发表于 2025-2-3 07:05:30 | 显示全部楼层 |阅读模式
第一集

学习本集,感受到了Ai8051u这个仿真实验板的强大功能!也感受到了新型高速单片机带来的极致体验效果。

希望在这里,通过国芯论坛,通过冲哥的视频教程,能学习到更好的硬件编程方法,和创造更有实用价值的制作。

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

谢谢冲哥送出的这勉励话语,我将让其陪伴左右,警醒自己!提升自己!

回复

使用道具 举报 送花

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

1

主题

12

回帖

71

积分

注册会员

积分
71
发表于 2025-2-3 07:14:08 | 显示全部楼层
第二集
介绍了AI8051U实验箱的各个硬件模块;编程软件、程序下载软件的下载与安装;简要介绍了软件的基本操作,如何添加头文件及如何加入扩展功能等的操作。
1.jpeg

2.jpeg

3.PNG

回复 支持 反对

使用道具 举报 送花

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

1

主题

12

回帖

71

积分

注册会员

积分
71
发表于 2025-2-3 07:21:36 | 显示全部楼层

第三集

课程开始,冲哥就讲解了keil软件的启动和工程的建立!搭建了一个基本的软件代码框架。

介绍了 GPIO

就拿P00来说,P00有4中状态,
假如P0组的引脚只有两种状态,那么仅需要P0M0就够用了,P0M0是一个字节(8位),即二进制为 0000 0000,其中每一位标志一个引脚状态,如下:
0:表示“准双向口”
1:表示“推挽输出”
举例 P0M0为 0100 0000 则表示 P06 为 “推挽输出”,其他7个都是“准双向口”。

0.jpg

回复 支持 反对

使用道具 举报 送花

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

1

主题

12

回帖

71

积分

注册会员

积分
71
发表于 2025-2-3 09:49:35 | 显示全部楼层
第4集 USB不停电下载



上代码
  1. #include "ai8051u.h" //调用头文件
  2. #include "stc32_stc8_usb.h"
  3. char *USER_DEVICEDESC = NULL;
  4. char *USER_PRODUCTDESC = NULL;
  5. char *USER_STCISPCMD = "@STCISP#";
  6. void main(void)
  7. {
  8.     P_SW2 |= 0x80; //B7位写1,使能访问XFR     
  9.     P0M1 = 0x00;   P0M0 = 0x00;
  10.     P1M1 = 0x00;   P1M0 = 0x00;
  11.     P2M1 = 0x00;   P2M0 = 0x00;
  12.     P3M1 = 0x00;   P3M0 = 0x00;
  13.     P4M1 = 0x00;   P4M0 = 0x00;
  14.     P5M1 = 0x00;   P5M0 = 0x00;
  15.     P6M1 = 0x00;   P6M0 = 0x00;
  16.     P7M1 = 0x00;   P7M0 = 0x00;
  17.         
  18.     usb_init();   
  19.     IE2 |= 0x80;                                    //使能USB中断
  20.     EA = 1;
  21.         
  22.         while (DeviceState != DEVSTATE_CONFIGURED);     //等待USB完成配置
  23.         while(1)
  24.         {        
  25.                 if (bUsbOutReady)
  26.         {
  27.             USB_SendData(UsbOutBuffer,OutNumber);   //发送数据缓冲区,长度(接收数据原样返回, 用于测试)
  28.             
  29.             usb_OUT_done();
  30.         }
  31.                
  32.                 P40 = 0;
  33.                 P00 = 0;
  34.                 P02 = 0;
  35.                 //P01 = 0;         
  36.         }         
  37. }
复制代码


0.jpg

捕获.PNG
回复 支持 反对

使用道具 举报 送花

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

1

主题

12

回帖

71

积分

注册会员

积分
71
发表于 2025-2-3 10:03:52 | 显示全部楼层
第5集 C语言基础



本集让我重新温习了一遍C语言

老师讲解了 printf, 实现USB-CDC串口发送。

上代码


#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

    P0M1 = 0x00;
    P0M0 = 0x00;
    P1M1 = 0x00;
    P1M0 = 0x00;
    P2M1 = 0x00;
    P2M0 = 0x00;
    P3M1 = 0x00;
    P3M0 = 0x00;
    P4M1 = 0x00;
    P4M0 = 0x00;
    P5M1 = 0x00;
    P5M0 = 0x00;
    P6M1 = 0x00;
    P6M0 = 0x00;
    P7M1 = 0x00;
    P7M0 = 0x00;

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

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

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

    while (1)
    {

        if (bUsbOutReady) // 如果接收到了数据
        {
            printf("Ai8051U真强大\r\n");
            usb_OUT_done(); //
        }
    }
}


运行效果图

33.PNG
回复 支持 反对

使用道具 举报 送花

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

1

主题

12

回帖

71

积分

注册会员

积分
71
发表于 2025-2-3 10:15:23 | 显示全部楼层
第6集 IO输入输出


首先讲解了 GPIO 的概念。1 高电平 0 低电平



     GPIO(General Purpose I/O Ports)意思为通用输入/输出端口,通俗地说,就是一些引脚,可以通过它们输出高低电平或者通过它们读入引脚的状态-是高电平或是低电平。
     高电平就是指接近于电源正极电压的电平;也叫逻辑“1”; VDD最大电压不能超过5.5V。上限溢出允许0.3v内.
     单片机输出高电平就是输出VCC电压,输出低电平就是输出GND的电压。
     四种模式:准双向口、推挽输出、高阻输出、开漏模式。 灌电流(电源到管脚串电阻尽量大于1K,不小于470欧)和拉电流(管脚到Gnd,推挽/强上拉)的讲解
     单片机电压3.3V,施密特触发器,低电平不能高于0.99V,高电平不能低于1.18V。

通过按键来检测io状态
按键消抖。延时20ms


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

// 注意:擎天柱的LED端口在P2,且没有三极管的电源控制,所以只要控制P2端口即可,按键通用,本节课程的其余内容均通用!

#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速度

    P0M1 = 0x00;
    P0M0 = 0x00;
    P1M1 = 0x00;
    P1M0 = 0x00;
    P2M1 = 0x00;
    P2M0 = 0x00;
    P3M1 = 0x00;
    P3M0 = 0x00;
    P4M1 = 0x00;
    P4M0 = 0x00;
    P5M1 = 0x00;
    P5M0 = 0x00;
    P6M1 = 0x00;
    P6M0 = 0x00;
    P7M1 = 0x00;
    P7M0 = 0x00;

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

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

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

    while (1)
    {

        if (bUsbOutReady) // 如果接收到了数据
        {
            // USB_SendData(UsbOutBuffer,OutNumber);   //发送数据缓冲区,长度(接收数据原样返回, 用于测试)

            usb_OUT_done(); //
        }

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

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

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

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



回复 支持 反对

使用道具 举报 送花

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

1

主题

12

回帖

71

积分

注册会员

积分
71
发表于 2025-2-3 11:39:19 | 显示全部楼层
第七集 定时器


本集开始讲解Ai8051U最重要的数字外设之一: 定时器


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

3.PNG

上代码,用定时器实现了3个小任务:

#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;     // 初始状态
u8 Run_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 Timer0_Init(void); // 3秒@24.000MHz     //函数声明

void main(void)
{
    int count = 1; // 按键计数变量

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

    P0M1 = 0x00;
    P0M0 = 0x00;
    P1M1 = 0x00;
    P1M0 = 0x00;
    P2M1 = 0x00;
    P2M0 = 0x00;
    P3M1 = 0x00;
    P3M0 = 0x00;
    P4M1 = 0x00;
    P4M0 = 0x00;
    P5M1 = 0x00;
    P5M0 = 0x00;
    P6M1 = 0x00;
    P6M0 = 0x00;
    P7M1 = 0x00;
    P7M0 = 0x00;

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

    IE2 |= 0x80; // 使能USB中断
    //  Timer0_Init();                                  //定时器初始化

    EA = 1; // IE |= 0X80;

    P40 = 0;

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

    while (1)
    {

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

        // 任务1:
        if (P32 == 0) // 判断P32按钮是否按下
        {
            Delay20ms(); // 延时20ms消抖
            if (P32 == 0)
            {
                printf("按键按下次数\xfd:%d\r\n", (int)count);
                count++;

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

        // 任务2:灯按一下点亮三秒后熄灭。
        if (P32 == 0) // 判断P32按钮是否按下
        {
            Delay20ms(); // 延时20ms消抖
            if (P32 == 0)
            {
                printf("按键按下次数\xfd:%d\r\n", (int)count);
                count++;
                P00 = 0;
                Timer0_Init();
                while (P32 == 0)
                    ; // 等待P32松开
            }
        }

        // 任务3:救护车灯控制器,按下报警按钮,红蓝交替闪烁(LED1和LED2表示红和蓝灯),再按一下报警按钮,红蓝灯停止。
        if (P32 == 0) // 判断P32按钮是否按下
        {
            Delay20ms(); // 延时20ms消抖
            if (P32 == 0)
            {
                Run_State = !Run_State; // 运行状态取反

                if (Run_State == 1) // 运行
                {
                    Timer0_Init();
                }
                else
                {
                    TR0 = 0; // 关闭定时器
                    P00 = 1;
                    P01 = 1;
                }
                while (P32 == 0)
                    ; // 等待P32松开
            }
        }
    }
}

void Timer0_Init(void) // 500毫秒@24.000MHz
{
    TM0PS = 0x0F; // 设置定时器时钟预分频 ( 注意:并非所有系列都有此寄存器,详情请查看数据手册 )
    AUXR &= 0x7F; // 定时器时钟12T模式
    TMOD &= 0xF0; // 设置定时器模式
    TL0 = 0xDC;   // 设置定时初始值
    TH0 = 0x0B;   // 设置定时初始值
    TF0 = 0;      // 清除TF0标志
    TR0 = 1;      // 定时器0开始计时
    ET0 = 1;      // 使能定时器0中断
}

void Timer0_Isr(void) interrupt 1 // 3秒执行一次
{
    state = !state;

    P00 = state;
    P01 = !state;
}



回复 支持 反对

使用道具 举报 送花

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

1

主题

12

回帖

71

积分

注册会员

积分
71
发表于 2025-2-3 13:16:02 | 显示全部楼层

第八集 定时器周期性调度任务

学完本集,主要有二点收获:

  1. 代码的模块化管理
  2. 任务的合理分解

随着功能的增加,代码量也直线上升,如何组织代码很关键,对以后的需求变化影响至关重要。

main.c           主模块
└─user
    ├─io.c       io功能
    ├─config.c   配置
    └─task.c     任务

主模块就显得非常简洁明了

#include "config.h"
#include "task.h"
#include "io.h"

void main(void)
{
	Sys_init(); // 系统初始化
	usb_init(); // USB CDC 接口配置

	IE2 |= 0x80;   // 使能USB中断
	Timer0_Init(); // 定时器初始化
	EA = 1;		   // IE |= 0X80;

	P40 = 0;

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

	while (1)
	{

		if (bUsbOutReady) // 如果接收到了数据
		{
			usb_OUT_done(); //
		}
		Task_Pro_Handler_Callback(); // 执行功能函数
	}
}

具体任务分解到了任务模块中

#include "task.h"
#include "io.h"

static TASK_COMPONENTS Task_Comps[] = {
    // 状态  计数  周期  函数
    {0, 300, 300, LED0_Blink}, /* task 1 Period: 300ms */
    {0, 600, 600, LED1_Blink}, /* task 1 Period: 600ms */
    {0, 900, 900, LED2_Blink}, /* task 1 Period: 600ms */
    {0, 10, 10, KEY_Task},     /* task 1 Period: 600ms */
};

u8 Tasks_Max = sizeof(Task_Comps) / sizeof(Task_Comps[0]);

//========================================================================
// 函数: Task_Handler_Callback
// 描述: 任务标记回调函数.
// 参数: None.
// 返回: None.
// 版本: V1.0, 2012-10-22
//========================================================================
void Task_Marks_Handler_Callback(void)
{
    u8 i;
    for (i = 0; i < Tasks_Max; i++)
    {
        if (Task_Comps[i].TIMCount) /* If the time is not 0 */
        {
            Task_Comps[i].TIMCount--;        /* Time counter decrement */
            if (Task_Comps[i].TIMCount == 0) /* If time arrives */
            {
                /*Resume the timer value and try again */
                Task_Comps[i].TIMCount = Task_Comps[i].TRITime;
                Task_Comps[i].Run = 1; /* The task can be run */
            }
        }
    }
}

//========================================================================
// 函数: Task_Pro_Handler_Callback
// 描述: 任务处理回调函数.
// 参数: None.
// 返回: None.
// 版本: V1.0, 2012-10-22
//========================================================================
void Task_Pro_Handler_Callback(void)
{
    u8 i;
    for (i = 0; i < Tasks_Max; i++)
    {
        if (Task_Comps[i].Run) /* If task can be run */
        {
            Task_Comps[i].Run = 0;    /* Flag clear 0 */
            Task_Comps[i].TaskHook(); /* Run task */
        }
    }
}
回复 支持 反对

使用道具 举报 送花

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

1

主题

12

回帖

71

积分

注册会员

积分
71
发表于 2025-2-3 15:21:42 | 显示全部楼层

第九集 数码管

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

AIapp-ISP 工具提供了虚拟显示功能,极大地方便了开发调试。

1.PNG

image.png

代码

u8 SEG_NUM[] =
	{
		0x3F, /*'0', 0*/
		0x06, /*'1', 1*/
		0x5B, /*'2', 2*/
		0x4F, /*'3', 3*/
		0x66, /*'4', 4*/
		0x6D, /*'5', 5*/
		0x7D, /*'6', 6*/
		0x07, /*'7', 7*/
		0x7F, /*'8', 8*/
		0x6F, /*'9', 9*/
		0x77, /*'A', 10*/
		0x7C, /*'B', 11*/
		0x39, /*'C', 12*/
		0x5E, /*'D', 13*/
		0x79, /*'E', 14*/
		0x71, /*'F', 15*/
		0x40, /*'-', 16*/
		0x00, /*' ', 17*/
		0x80, /*'.', 18*/
};

void SEG_PC(void)
{
	u8 cod[8];

	cod[0] = SEG_NUM[shi / 10]; // 小时的十位数的数码管段码
	cod[1] = SEG_NUM[shi % 10];
	cod[2] = SEG_NUM[16]; // 数码管刷段码和位码

	cod[3] = SEG_NUM[fen / 10]; // 分钟
	cod[4] = SEG_NUM[fen % 10];
	cod[5] = SEG_NUM[16]; // 数码管刷段码和位码

	cod[6] = SEG_NUM[miao / 10]; // 分钟
	cod[7] = SEG_NUM[miao % 10];

	SEG7_ShowCode(cod);
}
回复 支持 反对

使用道具 举报 送花

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

1

主题

12

回帖

71

积分

注册会员

积分
71
发表于 2025-2-3 15:24:42 | 显示全部楼层

第十集 虚拟LED数码管

准备好三件套

图片1.png

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

  1. 虚拟显示——LED

11.PNG

2 虚拟显示——数码管

22.PNG

3 虚拟键盘

33.PNG

回复 支持 反对

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2025-6-30 19:07 , Processed in 0.181363 second(s), 97 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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