找回密码
 立即注册
查看: 602|回复: 6

0.初识8051U

[复制链接]
  • 打卡等级:偶尔看看III
  • 打卡总天数:55
  • 最近打卡:2025-08-22 08:52:09
已绑定手机

3

主题

5

回帖

238

积分

中级会员

积分
238
发表于 2025-6-5 14:59:40 | 显示全部楼层 |阅读模式
第0章 8051U介绍
单价:RMB2.3
Ai8051UUSB 1T 8051,支持32位和8位指令集
管脚兼容天王级别的:  89C52RC,  12C5A60S2
要兼容 88051指令集,可以用 Keil C51/IAR/SDCC 编译器相当于更强大的 8H8K64U
要兼容 328051指令集,可以用 Keil C251 编译器,双核兼容设计相当于更强大的 32G12K128, 32G8K64
参数:
34K SRAM(2K edata, 32K xdata), 64K Flash
TFPU@120MHz, 硬件浮点/硬件三角函数 运算器
DMA支持PWM, DMA支持外设直接到外设, P2P
120MHz-PWM支持硬件移相,16PWM; 12ADC
USB, 4组串口,12ADC, 轨到轨比较器
QSPI, SPI, I2S, I2C,  TFT-i8080/M6800 接口
PDIP40LQFP44LQFP48
对比STC32G优势
1. 屏幕显示和视频播放(flash编程器)
2. IIS录放音
3. PWM_DMA
4. 频谱分析仪(上位机)
5. 手写计算器
6. QSPIPWM移相、硬件乘除、单精度浮点

回复

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:55
  • 最近打卡:2025-08-22 08:52:09
已绑定手机

3

主题

5

回帖

238

积分

中级会员

积分
238
发表于 2025-6-6 09:08:23 | 显示全部楼层
1.初识AI8051U
第一章硬件及软件工具介绍
一、 实验箱电路资源
截图202506060905009394.jpg
二、 软件环境
1.  Keil  C251 编译器
截图202506060906089101.jpg
2. ISP软件
截图202506060906279300.jpg
3. 添加型号与头文件
截图202506060906438611.jpg
4. 下载插件
截图202506060906525293.jpg
5. 下载代码包和手册
截图202506060907045276.jpg

回复

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:55
  • 最近打卡:2025-08-22 08:52:09
已绑定手机

3

主题

5

回帖

238

积分

中级会员

积分
238
发表于 2025-6-6 09:11:09 | 显示全部楼层
2.初始AI8051U
第二章 点灯实验
一、 工程文件
1. 创建空工程(参考手册2.6.2章节)
2. 添加头文件(利用ISP软件,结合手册2.4章节)
3. 输入如下代码,并编译
#include ai8051u.h
void main (  void  )
{
While(1)
{
;
}
}
:头文件< >” ”使用存在区别:
尖括号< > 编译器会在系统路径下查找头文件;
双引号 “ ” ,编译器首先在当前目录下查找头文件,如果没有找到,再到系统路径下查找头文件。
二、 点亮LED
P4.0 低电平 P0.0 低电平 LED0 亮起
#include ai8051u.h
void main (  void  )
{
P0M1 = 0x00 ; P0M0 = 0x00 ;
P4M1 = 0x00 ; P4M0 = 0x00 ;
P40 = 0 ;
While(1)
{
P00 = 0 ;
}
}
配置I/O口工作模式
准双向口(传统8051端口模式,弱上拉)
灌电流可达20mA,拉电流为270~150uA ( 存在制造误差 )

回复

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:55
  • 最近打卡:2025-08-22 08:52:09
已绑定手机

3

主题

5

回帖

238

积分

中级会员

积分
238
发表于 2025-6-9 14:55:28 | 显示全部楼层

3. USB不停电下载-串口一键下载功能

第三章 USB不停电下载-串口一键下载功能
1.实验对比演示,修改完成后可以编译程序完成后自动下载,便于开发验证新功能,简化烧录功能。
2.下载所需文件(STC官网-软件工具-库函数-USB库文件)
3.移植关键部分到工程:
3.1 添加头文件
3.2 USB初始化函数(lib+.h库实现)
3.3 命令参数
3.4 打开P_SW2寄存器和IE2寄存器(只打开一个位!)
#include "ai8051u.h"   // 调用头文件
#include "stc32_stc8_usb.h"  // 调用头文件

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)
        {
            USB_SendData(UsbOutBuffer,OutNumber);   // 发送数据缓冲区,长度(接收数据原样返回,用于测试)
            usb_OUT_done();
        }
  P40 = 0; // P40端口输出0V
  P00 = 0; // P00端口输出0V
  P02 = 0; // P02端口输出0V
  //P01 = 0;  // P01端口输出0V
}
}
// 表示按位或
  P_SW2 |= 0x80; // B7位写1,使能访问XFR
可以只对需要的数据位写1。


回复

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:55
  • 最近打卡:2025-08-22 08:52:09
已绑定手机

3

主题

5

回帖

238

积分

中级会员

积分
238
发表于 2025-6-9 16:16:21 | 显示全部楼层

4. C语言基础

第4章 C语言基础
1. C语言 USB-CDC串口之printf函数的实现
打开USB库中的PRINTF_HID宏定义(去掉//
PRINTF的函数原型的定义
#define printf  printf_hid
int printf_hid (const char *fmt, ...);
参数fmt -- 是格式控制字符串,包含了两种类型的对象:普通字符和转换说明 。
普通字符:在输出时,普通字符将原样不动地复制到标准输出。
示例:  
printf("8051U深度入门到3251大型实战视频\r\n");
转换说明:不直接输出,用于控制 printf 中参数的转换和打印。每个转换说明都由一个百分号字符(%)开始,以转换说明符结束,从而说明输出数据的类型、宽度、精度等。
示例:
                 printf("8051U深度入门到3251大型实战视频,%s\r\n","加油");
转换说明简介:
1.类型:根据不同的 fmt 字符串,函数可能需要一系列的附加参数,每个参数包含了一个要被插入的值,替换了 fmt 参数中指定的每个 % 标签。关于附加参数,既可以是变量,也可以是常量。
2.位置:printf()函数的普通字符和转换说明放在" "双引号内,附加参数放在双引号外,每个附加参数之间用逗号隔开。
3.数量:printf() 的附加参数与转换说明符是⼀⼀对应关系,如果有 n 个转换说明符, printf() 的参数就应该有 n + 1 个。如果参数个数少于对应的转换说明符,printf() 可能会输出内存中的任意值。
截图202506091609014869.jpg
截图202506091609141213.jpg
截图202506091609261318.jpg
截图202506091609461816.jpg
2. 数的进制:2进制、10进制、16进制
各进制与十进制的换算公式
二进制
1011=1*2^0+1*2^1+0*2^2+1*2^3=1+2+0+8=11
八进制
0123=3*8^0+2*8^1+1*8^2=3+16+64=83
十六进制
0x34A=10*16^0+4*16^1+3*16^2=10+64+768=8423.
截图202506091610198560.jpg
3.数据的基本类型
想要使用64位变量,需要在程序文件里面添加申明:#pragma float64
截图202506091610573614.jpg
4. C语言常用运算符
截图202506091611111835.jpg
截图202506091611204749.jpg
截图202506091611291431.jpg
截图202506091611381800.jpg
截图202506091611494656.jpg
截图202506091612039184.jpg


回复

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:55
  • 最近打卡:2025-08-22 08:52:09
已绑定手机

3

主题

5

回帖

238

积分

中级会员

积分
238
发表于 2025-6-9 17:29:36 | 显示全部楼层
5.按键检测实验
第五章 GPIO输入输出
GPIO 简介
GPIOGeneral Purpose I/O Ports)意思为通用输入/输出端口,通俗地说,就是一些引脚,可以通过它们输出高低电平或者通过它们读入引脚的状态-是高电平或是低电平。
高电平就是指接近于电源正极电压的电平;也叫逻辑“1”
单片机输出高电平就是输出VCC电压,输出低电平就是输出GND的电压。
截图202506091726232437.jpg
截图202506091726315080.jpg
截图202506091726437382.jpg
按键输入检测
代码实现原理:程序直接读取按键的IO的电平即可,一般使用”==”即可
案例1 : 按下P32按钮灯亮,松开P32按钮灯灭;
P40 = 0;
if( P32 == 0 )  //判断P32按钮是否按下
{
  P00 = 0;
}
else
{
  P00 = 1;
}
案例2 : 按下P32按钮灯灭,松开P32按钮灯亮;
P40 = 0;
if( P32 == 1 )  //判断P32按钮是否按下
{
  P00 = 0;
}
else
{
  P00 = 1;
}
案例3 : 按一下灯亮,按一下灯灭;
截图202506091726596741.jpg
u8 state = 0;  //初始状态
void Delay20ms(void) //@24.000MHz  Delay20ms();
{
unsigned long edata i;

_nop_();
_nop_();
i = 119998UL;
while (i) i--;
}
P40 = 0;
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 ); //松键检测
   }
  }
机械按键按下或者松开有抖动,一般在20ms内。
WTST = 0;  //设置程序指令延时参数,
EAXFR = 1; //扩展寄存器(XFR)访问使能
CKCON = 0; //提高访问XRAM速度
案例4 : 按一下P32按钮灯亮,按一下P33按钮灯灭;
u8 state = 0;  //初始状态
void Delay20ms(void) //@24.000MHz  Delay20ms();
{
unsigned long edata i;

_nop_();
_nop_();
i = 119998UL;
while (i) i--;
}
P40 = 0;
if( P32 == 0 )  //判断P32按钮是否按下
  {
   Delay20ms(); //延时20ms消抖
   if( P32 == 0 )
   {
    P00 = 0; //灯亮
    while( P32 == 0 ); //松键检测
   }
  }
if( P33 == 0 )  //判断P33按钮是否按下
  {
   Delay20ms(); //延时20ms消抖
   if( P33 == 0 )
   {
    P00 =1; //灯灭
    while( P33 == 0 ); //松键检测
   }
  }

案例5 : 按一下亮一颗灯,在按一下亮两颗灯,直到全亮(变量+加法和乘法)
u8 state = 0;  //初始状态
void Delay20ms(void) //@24.000MHz  Delay20ms();
{
unsigned long edata i;

_nop_();
_nop_();
i = 119998UL;
while (i) i--;
}
P40 = 0;
if( P32 == 0 )  //判断P32按钮是否按下
  {
   Delay20ms(); //延时20ms消抖
   if( P32 == 0 )
   {
    state ++; //变量取反 灯亮数量自加
    Switch( state  )
{
case 1 : P00 = 0; break//1灯亮
case 2 : P01 = 0; break//2灯亮
case 3 : P02 = 0; break//3灯亮
case 4 : P03 = 0; break//4灯亮
case 5 : P04 = 0; break//5灯亮
case 6 : P05 = 0; break//6灯亮
case 7 : P06 = 0; break//7灯亮
case 8 : P07 = 0; state =0;break//8灯亮
default :
P00 = 1;P01 = 1;P02 = 1;P03 = 1;P04 = 1;P05 = 1;P06 = 1;P07 = 1;
break//8灯灭
}
    printf("state:%d\r\n",(int)state);
    while( P32 == 0 ); //松键检测
   }
  }

回复

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:55
  • 最近打卡:2025-08-22 08:52:09
已绑定手机

3

主题

5

回帖

238

积分

中级会员

积分
238
发表于 2025-6-10 10:47:19 | 显示全部楼层

6. 定时器

第六章 定时器
单核CPU,单次只能执行一个任务
1. 定时器的介绍
定时器作用:
( 1 ) 用于计时系统,可实现软件计时,或者使程序每隔一固定时间完成一项操作
( 2 ) 替代长时间的Delay;提高程序的运行效率和处理速度(可以打断主循环)
2. 定时器的应用
案例1LED灯三秒取反一次,这期间任意时刻按下按钮,串口打印按键次数。
void Timer0_Init(void)  //3秒@20.000MHz
{
TM0PS = 0x4C;//设置定时器时钟预分频 ( 注意:并非所有系列都有此寄存器,详情请查看数据手册 )
AUXR &= 0x7F;//定时器时钟12T模式
TMOD &= 0xF0;//设置定时器模式
TL0 = 0x59; //设置定时初始值
TH0 = 0x02; //设置定时初始值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
}
int count=1; //按键计数变量
u8 state = 0; //初始状态
//放主循环
if( P32 == 0 ) //判断P32按钮是否按下
{
Delay20ms(); //延时20ms消抖
if( P32 == 0 )
{
  printf("按键按下次数\xfd:%d 次\r\n",(int)count);
  count++;

  while( P32 == 0 ); //等待P32松开
}
}
void Timer0_Isr(void) interrupt 1 //3秒执行一次
{
state = !state;  
P00 = state;
}
3. 函数的定义、声明、调用
定义:包含返回值,函数名和入口参数,并定义了函数具体功能。
返回值类型 函数名(入口参数)
    {
        // 函数体
        // 函数执行的代码
        return 返回值;
}
void Delay20ms(void)
{
unsigned long edata i;
_nop_();
_nop_();
i = 119998UL;
while (i) i--;
}
函数的名称应当能够描述函数的功能,便于代码的阅读和理解。
函数名称应当使用有意义的英文单词或者组合的英文单词,避免使用特殊字符或数字。
函数名称不能与C语言的关键字同名。
返回值类型 函数名(入口参数)
void Delay20ms(void);
声明:在头文件或者被调用之前使用,注意末尾要加分号
函数名(入口参数)
Delay20ms();
调用:在需要调用的地方直接使用函数名,加上括号和分号。如果有入口参数的,需要在括号的多个参数之间加逗号隔开。
案例2:灯按一下点亮三秒后熄灭
案例3:救护车灯控制器,按下报警按钮,红蓝交替闪烁(LED1LED2表示红灯和蓝灯),再按一下报警按钮,红蓝灯停止。
提高案例:电子功德箱:(已实现)
1. 按下按钮1,串口显示“双倍功德时间”,再次按下显示“单倍功德时间”
2. 按下按键2,双倍功德时间下串口显示“功德+2 当前功德:xxx”;
3. 按下按键2,单倍功德时间下串口显示“功德+1 当前功德:xxx”;
4. 功德+1时,LED点亮1秒后熄灭表示功德成功点亮;
5. 功德+2时,LED点亮2秒后熄灭表示功德成功点亮;
/*
电子功德箱
1. 按下按钮1,串口显示“双倍功德时间”,再次按下显示“单倍功德时间”
2. 按下按键2,双倍功德时间下串口显示“功德+2 当前功德:xxx”;
3. 按下按键2,单倍功德时间下串口显示“功德+1 当前功德:xxx”;
4. 功德+1时,LED点亮1秒后熄灭表示功德成功点亮;
5. 功德+2时,LED点亮2秒后熄灭表示功德成功点亮;
*/
#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 = 1;                                //运行状态
// 功德运行 状态 1:功德+1
//                        状态 2:功德+2
u8 Run_Sum = 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_delay1S_Init(void);                //1秒@24.000MHz
void Timer0_delay2S_Init(void);                //2秒@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中断
       
    EA = 1;                                                                                        //IE |= 0X80;
       
        P40 = 0;
       
        while (DeviceState != DEVSTATE_CONFIGURED);     //等待USB完成配置
       
        while(1)
        {
               
        if (bUsbOutReady)                                                        //如果接收到了数据
        {
            //USB_SendData(UsbOutBuffer,OutNumber);   //发送数据缓冲区,长度(接收数据原样返回, 用于测试)
            
            usb_OUT_done();                                                        //
        }
                //任务3:救护车灯控制器,按下报警按钮,红蓝交替闪烁(LED1和LED2              表示红和蓝灯),再按一下报警按钮,红蓝灯停止。
                if( P32 == 0 )                                                                //判断P32按钮是否按下
                {
                        Delay20ms();                                                        //延时20ms消抖
                        if( P32 == 0 )
                        {       
                                if( Run_State==1 )                                        //运行
                                {
                                        Run_State = 2 ;
                                        printf("双倍功德时间\r\n");
                                }
                                else
                                {
                                        Run_State = 1 ;
                                        printf("单倍功德时间\r\n");
                                }
                                while( P32 == 0 );                                        //等待P32松开
                        }
                }
                if( P33 == 0 )                                                                //判断P33按钮是否按下
                {
                        Delay20ms();                                                        //延时20ms消抖
                        if( P33 == 0 )
                        {       
                                if( Run_State==1 )                                        //运行
                                {
                                        Run_Sum += 1 ;
                                        P00 = 0;
                                        Timer0_delay1S_Init();
                                        printf("功德+1 当前功德:%d 次\r\n",(int)Run_Sum);
                                }
                                else
                                {
                                        Run_Sum += 2 ;
                                        P00 = 0;
                                        Timer0_delay2S_Init();
                                        printf("功德+2 当前功德:%d 次\r\n",(int)Run_Sum);
                                }
                                while( P33 == 0 );                                        //等待P33松开
                        }
                }
        }
}

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

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

void Timer0_Isr(void) interrupt 1                //3秒执行一次
{
        P00 = 1;
        TR0 = 0;                                //定时器0停止计时
        ET0 = 0;                                //失能定时器0中断
}

回复

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2025-8-24 02:38 , Processed in 0.113867 second(s), 78 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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