vzvutian 发表于 2025-2-10 16:47:32

深入学习Ai8051U教学视频打卡

今天学习Ai8051U教学视频第一讲,主要有以下功能:
一、 ai8051U相对于STC32G单片机的强化功能部分:
1.优化对QSPI接口的部分flash芯片的读写功能,使屏幕显示和视频播放得到质的提升;并且可充当编程器对flash进行编程下载图像视频文件等等。
2. 支持完整IIS的录放音功能。
3. 增加了PWM支持DMA的功能。
4. 芯片内置硬件浮点乘除单元,能实现频谱分析仪功能。
5. STC单片机从ai8051U开始向AI人工智能单片机转化。
二、 ai8051U脚位兼容89C52,12C5A60S2。
三、 选择不同编译器可以分别兼容8位和32位指令集。

vzvutian 发表于 2025-2-13 10:55:34

今天学习Ai8051U教学视频第二讲,主要讲解了实验箱的各个硬件组成部分,还有下载软件的各项使用功能。下载软件里集成了很多实用工具,范例程序,I/O口配置,软件延时计算器,定时器计算器等都能极大的方便程序的编写。

vzvutian 发表于 2025-2-13 11:04:25

学习Ai8051U教学视频第三讲,进行实际程序编写操作了啊。学单片机都是从点亮一个灯开始。
#include "ai8051u.h"               


void main(void)
{
        P0M0 = 0;                //P0端口(P00-P07)为准双向口
        P0M1 = 0;
       
        P4M0 = 0;                //P4端口为准双向口
        P4M1 = 0;       
       
        while(1)
        {
                P40 = 0;        //P40端口输出0V,把Led的总开关打开
                P00 = 0;        //P00端口输出0V,LED1点亮,低电平有效
                P01 = 0;        //P01端口输出0V,LED2点亮,低电平有效
        }
}

vzvutian 发表于 2025-2-13 14:17:06

学习Ai8051U教学视频第四讲,一个非常有用的功能,就是USB不停电下载,免去了反复按键的麻烦,提高了开发效率。头文件增加#include "stc32_stc8_usb.h" ,并初始化这三个变量
char *USER_DEVICEDESC = NULL;
char *USER_PRODUCTDESC = NULL;
char *USER_STCISPCMD = "@STCISP#";
在主函数中 增加:
P_SW2 |= 0x80;                //B7位写1,使能访问XFR
usb_init(); // 初始化 USB CDC 接口配置

IE2 |= 0x80; // 使能USB中断
EA = 1;      // IE |= 0X80;
while (DeviceState != DEVSTATE_CONFIGURED) ; // 等待USB完成配置
在主循环里增加
if (bUsbOutReady)
      {
            USB_SendData(UsbOutBuffer,OutNumber);   //发送数据缓冲区,长度(接收数据原样返回, 用于测试)
            
            usb_OUT_done();
      }

即可!

vzvutian 发表于 2025-2-13 15:54:37

Ai8051U教学视频第五讲,C语言基础。这一章主要讲了printf函数,可以直接通过串口调试助手查看变量的实时变化,大大的提高了程序调试的效率,及时发现问题。还讲了2进制、10进制、16进制之间的关系,数据的基本类型,每种类型的值的范围不一样,定义的时候一定要考虑到,不能超出范围,不然程序会出现意想不到的错误,而且很难发现。最后讲了运算符,活用运算符可以让程序简洁,提高运行效率。
在程序任意位置加上即可,可以添加变量: printf("向上位机发送的信息\r\n");    // 发送消息给上位机

vzvutian 发表于 2025-2-13 16:35:02

Ai8051U教学视频第六讲,I/O输入输出。本集简要介绍了GPIO,高电平、低电平的概念,当引脚电压为0V代表是低电平,当引脚电压接近于电源正极电压代表是高电平,通过高低电平来判断按键是否按下。其中要加入防抖检测,否则按一下程序会执行多次不可控。把课后小练的程序放上来。
按一下亮一颗灯,再按一下亮两颗灯,直到全亮(变量+加法和乘法)
#include "ai8051u.h"                        //调用头文件
#include "stc32_stc8_usb.h"                //调用头文件
#include "intrins.h"                        //d调用头文件

#define u8unsigned char                //8位无符号变量(0-255)
#define u16 unsigned int                //16位无符号变量(0-65535)       
       
u8 state = 0xFF;;                                        //初始状态

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

void Delay20ms(void)        //@24.000MHzDelay20ms();
{
        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;
       
        P40 = 0;
       
        while (DeviceState != DEVSTATE_CONFIGURED);   //等待USB完成配置
       
        while(1)
        {
               
      if (bUsbOutReady)                                                        //如果接收到了数据
      {
            //USB_SendData(UsbOutBuffer,OutNumber);   //发送数据缓冲区,长度(接收数据原样返回, 用于测试)
            
            usb_OUT_done();                                                        //
      }
               
            if( P32 == 0 )                                                                //判断P32按钮是否按下
                {
                        Delay20ms();                                                      //延时20ms消抖
                        if( P32 == 0 )
                        {
                           
                              state<<=1;
                              P0 =state;
                              if(state==0x00)
                              state=0XFF;
                              while( P32 == 0 );                                        //等待P32松开
                              
                        }
                }
        }
}

vzvutian 发表于 2025-2-13 17:00:25

Ai8051U教学视频第七讲,定时器中断。
Ai8051U 系列单片机内部设置了 6 个 24 位定时器/计数器(8 位预分频+16 位计数)。6 个 16 位定时器 T0、T1、T2、T3、T4 和 T11 都具有计数方式和定时方式两种工作方式。
定时器/计数器 0 有 4 种工作模式:模式 0(16 位自动重装载模式),模式 1(16 位不可重装载模式),模式 2(8 位自动重装模式),模式 3(不可屏蔽中断的 16 位自动重装载模式)。
定时器/计数器 1 除模式 3 外,其他工作模式与定时器/计数器 0 相同。T1 在模式 3 时无效,停止计数。
定时器 T2 的工作模式固定为 16 位自动重装载模式。T2 可以当定时器使用,也可以当串口的波特率发生器和可编程时钟输出。
定时器 3、定时器 4、定时器 11 与定时器 T2 一样,它们的工作模式固定为 16 位自动重装载模式。T3/T4可以当定时器使用,也可以当串口的波特率发生器和可编程时钟输出。
我们只要知道需要定时的时间,可以用下载软件里附带的定时器计算器把参数设好直接用。
把作业发上来请指正。

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

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

#define u8unsigned char                //8位无符号变量(0-255)
#define u16 unsigned int                //16位无符号变量(0-65535)      
      
u8 state = 0;                                        //初始状态
u8 Run_State = 0;                              //运行状态
u8 gongde=0;                                        //功德
u8 tt=0;                                                      //判断运行是否到规定时间
char *USER_DEVICEDESC = NULL;
char *USER_PRODUCTDESC = NULL;
char *USER_STCISPCMD = "@STCISP#";

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

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


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中断

    EA = 1;                                                                                        //IE |= 0X80;
      
      P40 = 0;
      
      while (DeviceState != DEVSTATE_CONFIGURED);   //等待USB完成配置
      
      while(1)
      {
               
      if (bUsbOutReady)                                                      //如果接收到了数据
      {
            //USB_SendData(UsbOutBuffer,OutNumber);   //发送数据缓冲区,长度(接收数据原样返回, 用于测试)
            
            usb_OUT_done();                                                      //
      }
                if( P32 == 0 )                                                                //判断P32按钮1是否按下
                {
                        Delay20ms();                                                      //延时20ms消抖
                        if( P32 == 0)
                        {
                              Run_State = !Run_State;                              //运行状态取反
                              if( Run_State==1 )                                        //运行
                              {printf("双倍功德时间\r\n");
                                       
                                       
                              
                              }
                              else
                              {
                                       
                                        printf("单倍功德时间\r\n");
                                       
                              }
                              while( P32 == 0 );                                        //等待P32松开
                        }
                }
                if( P33 == 0 )                                                                //判断P33按钮2是否按下
                {
                        Delay20ms();                                                      //延时20ms消抖
                        if( P33== 0&& tt==0)
                        {
                              if( Run_State==1 )                                        //运行
                              {
                                        gongde+=2;
                                        printf("功德+2 当前功德:%d\r\n",(int)gongde);
                                  P00 = 0;
                                        Timer0_2SInit();
                                        tt=1;
                              }
                              else
                              {
                                        gongde+=1;
                                        printf("功德+1 当前功德:%d\r\n",(int)gongde);
                                        P00 = 0;
                                        Timer0_1SInit();
                                        tt=1;
                              }
                              while( P33 == 0 );                                        //等待P33松开
                        }
                }
      }
}



void Timer0_Isr(void) interrupt 1                //3秒执行一次
{
      P00 = 1;
      TR0 = 0;                              //定时器0关闭
      tt=0;
}
TT的作用是防止时间没有到1秒或2秒时再次按下P33重新计时,导致亮灯时间不对。欢迎大家指正!

vzvutian 发表于 2025-2-17 15:26:07

Ai8051U教学视频第八讲,定时器周期性调度任务。用定时器来实现周期性的任务调度,避免了用循环方法,释放单片机资源,提高系统响应速度,改善用户体验。
用一个定时器实现这个任务。LED1实现0.3秒取反一次,LED2实现0.6秒取反一次,LED3 0.9秒取反一次
先是通过数组的方式来定义任务:
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);

void Task_Pro_Handler_Callback(void)
{
    u8 i;
    for (i = 0; i < Tasks_Max; i++)
    {
      if (Task_Comps.Run) /* If task can be run */
      {
            Task_Comps.Run = 0;    /* Flag clear 0 */
            Task_Comps.TaskHook(); /* Run task */
      }
    }
}

vzvutian 发表于 2025-2-17 15:32:57

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

共阴和共阳的编码是不一样的,程序设计前一定要确定是用共阴还是共阳的数码管!!!
在实际的项目中,多采用动态显示模式。利用人眼的视觉暂留原理,逐位动态扫描显示,可以达到多位视觉上同时显示的效果。
void Send_595(u8 dat)
{
      u8 i;

      for (i = 0; i < 8; i++)
      {
                dat <<= 1;                // DAT = (DAT<<1);      //CY
                HC595_SER = CY; // 先把数据写到引脚上
                HC595_SCK = 1;      // 输出上升沿的时钟信号
                HC595_SCK = 0;
      }
}

void Display_Seg(u8 HC595_1, u8 HC595_2)
{
      Send_595(HC595_1); // 数码管段码输出高电平点亮
      Send_595(HC595_2); // 数码管位码      低电平点亮

      HC595_RCK = 1; // 数据输出
      HC595_RCK = 0;
}

void Seg_Task(void)
{
      u8 num = 0;
      if (Seg_no == 0) // 小时十位
      {
                num = shi / 10;
                Display_Seg(SEG_NUM, ~T_NUM); // 数码管刷段码和位码
      }
      else if (Seg_no == 1) // 小时的个位
      {
                num = shi % 10;
                Display_Seg(SEG_NUM, ~T_NUM); // 数码管刷段码和位码
      }
      else if (Seg_no == 2) // 第一个横杠
      {
                Display_Seg(SEG_NUM, ~T_NUM); // 数码管刷段码和位码
      }
      else if (Seg_no == 3) // 分钟的十位
      {
                num = fen / 10;
                Display_Seg(SEG_NUM, ~T_NUM); // 数码管刷段码和位码
      }
      else if (Seg_no == 4)
      {
                num = fen % 10;
                Display_Seg(SEG_NUM, ~T_NUM); // 数码管刷段码和位码
      }
      else if (Seg_no == 5)
      {
                Display_Seg(SEG_NUM, ~T_NUM); // 数码管刷段码和位码
      }
      else if (Seg_no == 6)
      {
                num = miao / 10;
                Display_Seg(SEG_NUM, ~T_NUM); // 数码管刷段码和位码
      }
      else if (Seg_no == 7)
      {
                num = miao % 10;
                Display_Seg(SEG_NUM, ~T_NUM); // 数码管刷段码和位码
      }
      else
      {
      }
      Seg_no++;
      if (Seg_no > 7)
                Seg_no = 0;
}
给大家推荐个数码管编码工具,有些需要特殊字符的时候很方便。

页: [1]
查看完整版本: 深入学习Ai8051U教学视频打卡