找回密码
 立即注册
楼主: srkxrolz

记录我的8051u学习过程

[复制链接]
  • 打卡等级:偶尔看看I
  • 打卡总天数:12
  • 最近打卡:2025-07-08 00:11:07
已绑定手机

1

主题

32

回帖

121

积分

注册会员

积分
121
发表于 2025-6-21 14:49:22 | 显示全部楼层

实验1 USB_Print函数的基本使用过程

  1. 创建项目


图片1.png


图片1.png

图片1.png
图片1.png

  1. 获得最新的头文件和usb库文件

头文件从stc-isp中获取


图片1.png

网站上空用获取USb库文件和其他参考的函数文件


图片2.png

本实验基础程序框架包含4个file

Ai8051u.h

Ai_usb.h

stc_usb_cdc_32g.LIB //这里采用CDC查询方式的库

Main.c //我们的程序主体

  1. 程序工程中添加这几个文件


图片3.png

  1. 编写main文件


图片4.png

  1. 编译下载 ,观察串口助手输出

    图片5.png

upload 附件:实验1.rar

回复

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:12
  • 最近打卡:2025-07-08 00:11:07
已绑定手机

1

主题

32

回帖

121

积分

注册会员

积分
121
发表于 2025-6-21 14:56:28 | 显示全部楼层
实验2 查询方式实现usb输入

图片6.png
图片7.png
#include "ai8051u.h"
#include "ai_usb.h"
void main()
{
        EAXFR=1; //允许访问扩展特殊寄存器
        WTST=0;  //
        CKCON=0; //
        usb_init();
        EA=1;//中断总开关
        while(1){
       
        //printf_usb("Hello World \r\n");
               
                if (bUsbOutReady){
                if(UsbOutBuffer[0]==6)printf_usb("Hello World \r\n");
                if(UsbOutBuffer[0]==7)printf_usb("拆哪? \r\n");
               
                usb_OUT_done();
        }
实验2.rar (75.9 KB, 下载次数: 6)

回复

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:12
  • 最近打卡:2025-07-08 00:11:07
已绑定手机

1

主题

32

回帖

121

积分

注册会员

积分
121
发表于 2025-6-21 15:05:12 | 显示全部楼层
实验3 使用中断的方式进行usbprinf

图片8.png
图片9.png
实验3.rar (398.7 KB, 下载次数: 8)




回复

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:12
  • 最近打卡:2025-07-08 00:11:07
已绑定手机

1

主题

32

回帖

121

积分

注册会员

积分
121
发表于 2025-6-22 00:54:51 | 显示全部楼层
第九课:数码管与HC595芯片的使用
数码管的结构:共阴共阳接法
图片1.png
图片2.png
3461AS7.3AS=单色  BS=双色
试验箱上使用了两个74HC595芯片级联,形成一个用两字节的数据控制这8位数码管的效果,8位用于控制段选(数码管显示的字符),低八位控制位选(选择哪一个位置进行显示).
图片3.png
74hc595时序信号:
图片4.png
SCK 时钟线 上升沿移位寄存器会把SER上的电平读入, RCK出现上升沿的时候会把移位寄存器上的数据通过Q0-Q7进行输出.
移位寄存器在收到超过8位数据的时候会按顺序吧数据通过Q7传送给下一个芯片,
试验箱上的引脚定义
SCk=P32
RCK=P35
SER=P34
两个595共用SCKRCk  第一个的Q7输出给第二个的SER
u8 SMG_POSITION[] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};
u8 SMG_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 hc595_send(u8 dat)
{
    u8 i;
    for (i = 0; i < 8; i++)
    {
        dat <<= 1;
        HC595_DIO = CY;
        HC595_SCK = 1;
        HC595_SCK = 0;
    }
}
void smg_disp(u8 cha, u8 index)
{
    hc595_send(SMG_NUM[cha]);        // 发送段选
    hc595_send(SMG_POSITION[index]); // 发送位选
    HC595_RCK = 1;
    HC595_RCK = 0;
    if (++index >= 7)
        index = 0;
}
void led_40()
{
    u8 cod[8];
    cod[0] = 0x0f; // p0-p3   这八位从高到低代表 p7-p0
    cod[1] = P0;   // P0^1 高电平
    cod[2] = P1;   // P1^1 高电平
    cod[3] = P2;   // P2^1 高电平
    cod[4] = P3;   // P3^1 高电平
    LED40_SendData(cod, 5);
}
void SMG_PC()
{
    SEG7_ShowString("1234567abc");
}
void smg_display()
{
    u8 displayer_buff[] = {1, 2, 3, 4, 5, 6, 7, 8, 9}, i;
    for (i = 0; i < sizeof(displayer_buff) / sizeof(displayer_buff[0]); i++)
    {
        smg_disp(SMG_NUM[displayer_buff], SMG_POSITION);
    }
    // printf("smg_disp! \r\n");
    smg_disp(0, 0);
    SMG_PC();
    led_40();
}

回复

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:12
  • 最近打卡:2025-07-08 00:11:07
已绑定手机

1

主题

32

回帖

121

积分

注册会员

积分
121
发表于 2025-6-22 09:58:12 | 显示全部楼层
第十课:介绍STC-isp中的虚拟调试接口
Stc-isp 提供了一个模拟上位机工具,用于帮助没有试验箱硬件的伙伴调试程序.
DIP40_LED为例介绍了虚拟接口的原理
功能4: 控制DIP40的各个管脚上LED的状态

以此为例,stc-isp的串口助手在收到一串数据后会重绘界面模拟单片机IO口电平效果,
具体单片机通过串口发送给上位机的数据格式为带命令头的数据串,其中数据格式定义为
固定4字节命令”4CH 45H 44H 28H”然后跟一个字节表示后面的具体端口数据长度,后面数据第一个字节通过8位指定要控制p7-p0 ,接着就是具体要设置的端口的具体值,每一个字节代表一组端口从p0-p7,不需要控制的端口不用写在里面,
Usb库中提供了简便函数空用省去命令头的编写,只需要使用数组定义好需要用户设置的部分即可LED40_SendData(cod, 5);


void led_40()
{
    u8 cod[8];
    cod[0] = 0x0f; // p0-p3   这八位从高到低代表 p7-p0
    cod[1] = P0;   // P0^1 高电平
    cod[2] = P1;   // P1^1 高电平
    cod[3] = P2;   // P2^1 高电平
    cod[4] = P3;   // P3^1 高电平
    LED40_SendData(cod, 5);
}

其他还提供几个函数,但功能类似
void LED40_SendData(BYTE *dat, BYTE size);          //发送多个端口组
void LED40_SetPort(BYTE port, BYTE dat);                //设置指定端口组为某组状态
void LED40_SetBit(BYTE port, BYTE bt);                        //设置指定端口组某一位为1
void LED40_ClrBit(BYTE port, BYTE bt);                        //设置指定端口组某一位为0
// p2流水灯  P10 闪烁
void lsd()
{
    static u8 p2_flag = 0xfe, p10_flag = 0;
    p2_flag <<= 1;
    p2_flag = p2_flag + 1;
    // P2 = p2_flag;
    LED40_SetPort(2,p2_flag);
    if (p2_flag == 0xff)
        p2_flag = 0xfe;
    if (p10_flag == 0)
    {
        p10_flag = 1;
        LED40_SetBit(1, 0);
    }
    else
    {
                p10_flag = 0;
        LED40_ClrBit(1, 0);
    }
}



虚拟数码管
int SEG7_ShowString(const char *fmt, ...);
void SEG7_ShowLong(long n, char radix);
void SEG7_ShowFloat(float f);
void SEG7_ShowCode(BYTE *cod);

上位机的虚拟键盘
If(bUsbOutReady){
Num=UsbOutBuffer[0]-48;  //ascii字符转数字
}
回复

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:12
  • 最近打卡:2025-07-08 00:11:07
已绑定手机

1

主题

32

回帖

121

积分

注册会员

积分
121
发表于 2025-6-22 11:16:46 | 显示全部楼层
第十二集 复位系统
单片机提供了五种复位方式
1, 上电复位
2, 低压复位
3, 复位引脚低脉冲复位
4, 看门狗复位
5, 软件复位  给IAP_CONTR的SWRST置1

Stc中对上电复位时间有影响的地方
Stc-isp选项中上电复位使用较长延时        
//此选项默认选中,会影响大概100ms

下次冷启动 p32 p33为0才可下载程序  
//这里悬空的时候默认为0会进入isp下载程序,所以不下载程序空用用5.1K电阻拉高跳过isp, 影响几十毫秒

允许低压复位(禁止低压中断)
//默认选中 也就是VCC低于阈值直接系统复位,不勾选会产生一个软件中断,中断程序中空用点亮一个低压报警led作为提示, 低压状态下不要执行保存数据的操作,容易乱码

复位脚做IO口
//默认勾选的 p47为IO口 ,需要勾选后空用接一个300r电阻和按钮到地, 按下就可以复位

看们狗复位
//有一个独立累加计数器,加到溢出就复位,需要定时清空这个计时器防止复位,
void wdt_init()
{
   
    WDT_CONTR = 0x00; // 设置看门狗定时器时钟分配系数为最低2分频,并重置其他控制位
    IDL_WDT=1; // 设置看门狗定时器在空闲模式下继续计数
    CLR_WDT=1; // 清除看门狗定时器计数值
    EN_WDT =1; // 使能看门狗
}
void wdt_feed()
{
    CLR_WDT = 1; // 清除看门狗计数值
}


软件复位
void soft_reset()
{
    IAP_CONTR = 0x20; // 正常复位到main函数
    IAP_CONTR = 0x60; // 复位到isp下载模式
}

回复

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:12
  • 最近打卡:2025-07-08 00:11:07
已绑定手机

1

主题

32

回帖

121

积分

注册会员

积分
121
发表于 2025-6-22 12:07:45 | 显示全部楼层
第十三集外部中断

1.中断系统
图片1.png
8051u中提供了73个中断源,使用大于31的中断时需要在使用中断号扩展补丁
例INT0:P32按下后捕获到边沿跳变后置位IE0经过EX0中断允许和总开关到用户中断函数
IT0=0, 上下边沿均可触发  IT0=1  下降沿触发
IE0 INt0的中断标志位 ,响应中断函数后硬件自动清零
EX0 允许int0中断
EA=1 打开总开关
//p32 int0中断初始化
void int0_init(){
    IT0 = 1; // 设置INT0为下降沿触发
    EX0 = 1; // 使能INT0中断
    EA = 1;  // 全局中断使能
}
void int0_isr(void) interrupt 0
{
    // 在这里处理INT0中断
    // 例如,切换LED状态或执行其他操作
    P10 = ~P10; // 切换P10的状态
}

2.外部中断
由外部信号触发的中断
3.内部中断
内部因素导致得到中断
回复

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:161
  • 最近打卡:2025-08-23 08:11:44

775

主题

1万

回帖

1万

积分

管理员

积分
18735
发表于 2025-6-22 15:07:39 | 显示全部楼层
截图202506221504237268.jpg

截图202506221505065503.jpg

截图202506221505367823.jpg

截图202506221506071558.jpg

截图202506221506432402.jpg

截图202506221507301458.jpg


截图202506221509276768.jpg
一起学AiCube[url=home.php?mod=space&uid=30331]@Ai8051U 定时器0/1,INT0/INT1,中断组合应用实验打卡 - 学习打卡区 | 感悟 国芯技术交流网站 - AI32位8051交流社区[/url]
截图202506221510064320.jpg
回复

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:161
  • 最近打卡:2025-08-23 08:11:44

775

主题

1万

回帖

1万

积分

管理员

积分
18735
发表于 2025-6-22 15:13:10 | 显示全部楼层
截图202506221512596709.jpg


//外部中断INT0和INT1控制点灯并USB仿真
#include <AI8051U.H>                        //包含AI8051U的头文件
#include "intrins.h"                        //使用_nop_()函数所必须要包含的头文件,
                                                                //否则延时函数中调用的_nop_()函数没有被头文件引用过来,
                                                                //会导致编译器找不到这个而函数而报错。

bit int0_flag = 0;                                //定义1个位变量,INT0事件位变量标志,记录INT0已产生中断
// 供主循环查询INT0是否已产生中断,在主循环中处理INT0的中断事件任务,不堵塞其他中断
bit int1_flag = 0;                                //定义1个位变量,INT1事件位变量标志,记录INT1已产生中断
// 供主循环查询INT1是否已产生中断,在主循环中处理INT1的中断事件任务,不堵塞其他中断

void main (void)
{
        EAXFR = 1;                                          //允许访问扩展的特殊寄存器,XFR
        WTST = 0;                                     //设置取程序代码等待时间,赋值为 0 表示不等待,程序以最快速度运行
        CKCON = 0;                                    //设置访问片内的 xdata 速度,赋值为 0 表示用最快速度访问,不增加额外的等待时间
        P0M0 = 0x00; P0M1 = 0x00;
        P1M0 = 0x00; P1M1 = 0x00;
        P2M0 = 0x00; P2M1 = 0x00;
//        P3M0 = 0x00; P3M1 = 0x00;        //P32、P33设置为准双向口
        P3M0 = 0x00; P3M1 = 0xff;         //P32、P33设置为高阻输入(需要同步开启上拉电阻)
        P4M0 = 0x00; P4M1 = 0x00;
        P5M0 = 0x00; P5M1 = 0x00;
        P6M0 = 0x00; P6M1 = 0x00;
        P7M0 = 0x00; P7M1 = 0x00;
        P3PU = 0x0c;                                 //P32、P33打开上拉电阻
       
        IT0 = 0;                                         //使能 INT0 上升沿和下降沿中断
//        IT0 = 1;                                         //使能 INT0 下降沿中断
        EX0 = 1;                                         //使能 INT0 中断
       
//        IT1 = 0;                                         //使能 INT1 上升沿和下降沿中断
        IT1 = 1;                                         //使能 INT1 下降沿中断
        EX1 = 1;                                         //使能 INT1 中断
       
        IE0 = 0;                                        //清INT0中断标志
        IE1 = 0;                                        //清INT1中断标志
       
        EA = 1;                                         //打开所有中断
        P40 = 0;                                         //打开LED灯供电

        int0_flag = 0;                                //初始化用户标志位
        int1_flag = 0;                                //初始化用户标志位

        while(1)
        {
                if(int0_flag)                        //主循环中查询,INT0是否已产生中断,是否有需要处理的INT 0事件
                {
                        int0_flag = 0;                //清0,INT0事件位变量标志
                        _nop_();                        //用户在此添加需要处理的事件
                        _nop_();
                }
                if(int1_flag)                        //主循环中查询,INT1是否已产生中断,是否有需要处理的INT1事件
                {
                        int1_flag = 0;                //清0,INT1事件位变量标志
                        _nop_();                        //用户在此添加需要处理的事件
                        _nop_();
                }
        }
}

void int0_isr(void) interrupt INT0_VECTOR
{
        int0_flag = 1;                                // int0_flag置1是通知主循环处理部分INT0中断事件不需要特急处理的任务
                                                                //置1,记录INT0已产生中断,供主循环查询判断有无需处理的INT0任务

        if(INT0)                                         //边沿中断,进入后再次判断电平从而判断是什么样的电平
        {
                P00 = 0;                                //判断为高电平,则当前为上升沿,点亮P00端口上的LED灯
                _nop_();                                //可以在这里插入断点进行观察现象
                P00 = 1;                                //关闭LED灯
        }
        else
        {
                P07 = 0;                                //判断为低电平,则当前为下降沿,点亮P07端口上的LED灯
                _nop_();                                //可以在这里插入断点进行观察现象
                P07 = 1;                                //关闭LED灯
        }
}

void int1_isr(void) interrupt INT1_VECTOR
{
        int1_flag = 1;                                // int1_flag置1是通知主循环处理部分INT1中断事件不需要特急处理的任务
                                                                //置1,记录INT1已产生中断,供主循环查询判断有无需处理的INT1任务

        P04 = 0;                                        //点亮P04端口上的LED灯
        _nop_();                                        //可以在这里插入断点观察现象
        P04 = 1;                                        //关闭LED灯
}


回复

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:12
  • 最近打卡:2025-07-08 00:11:07
已绑定手机

1

主题

32

回帖

121

积分

注册会员

积分
121
发表于 2025-6-23 02:37:08 | 显示全部楼层
第十四集 io中断
89c51io中断只有2,现在8051u的所有io端口都可以配置中断并由4级优先级都支持唤醒
Io中断模式有四种
下降沿  m1=0  m0=0  
上升沿  m1=0  m0=1
低电平  m1=1  m0=0
高电平  m1=1  m0=1
每组IO电口有两个配置寄存器P0IM0 P0IM1 可以控制每组中的8IO. 通过M1M0确定触发方式
中断使能寄存器 P0INTE中段每一位控制对应IO口的中断enable
中断标志位     P0INTF 每一位表示中断使得否触发, 有中断触发就置1 软件手动清0
void P33_int_init()
{
    P3IM0 &= ~0x08; // 设置P33为下降沿触发
    P3IM1 &= ~0x08; // 设置P33为下降沿触发
    P3INTE |= 0x08; // 使能P33中断
    EA = 1;         // 全局中断使能
}
void P33_int_isr(void) interrupt 40 // P3整个组的中断服务程序
{
    if (P3INTF & 0x08) // 检测P33中断标志位
    {
        P3INTF &= ~0x08; // 清除P33中断标志位
        // 在这里处理P33中断
        // 例如,切换LED状态或执行其他操作
        P11 = ~P11; // 切换P11的状态
    }
}
优先级寄存器PINIPL  PINIPH
优先级0  最低优先级   PINIPH=0    PINIPL=0
优先级1  低优先级           PINIPH=0    PINIPL=1
优先级2  高优先级            PINIPH=1    PINIPL=0
优先级3  最高优先级   PINIPH=1    PINIPL=1

回复

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2025-8-24 04:10 , Processed in 0.128668 second(s), 90 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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