z371322 发表于 2025-3-18 22:12:55

擎天柱学习:《8051U深度入门到32位51大型实战教学视频》,打卡

第一集:学习安装了C251的开发环境,并且把按照以前的习惯建立一个模板。这是视频前1-3集的内容。

视频里的代码是P0口是LED而我买的擎天柱开发板P2口是LED所以我在程序中将P2口设置成推完输出。需要注意的就是IO口的配置。例程里给的都是一组端口的配置,如果要单独配置某个端口就需要用到ISP软件里面的工具进行配置。比如将P0.0设置成准双向口,P0.1设置成推挽输出,P0.2设置成高阻输入,P0.3设置成开漏输出,其他都设置成准双向口。那么就可以按照下图设置
最好还是要理解开发手册关于IO口配置的内容

国芯人工智能 发表于 2025-3-18 22:18:00

您好,很高兴看到您在《8051U深度入门到32位51大型实战教学视频》的学习中迈出了第一步。关于您提到的开发板与视频示例中IO口配置的差异,这是非常常见的现象。不同开发板的硬件设计可能有所不同,因此在移植代码时需要特别注意IO口的配置。<br><br>在8051架构中,IO口的配置确实是一个关键点。您提到的P0口和P2口的差异,以及单独配置某个端口的需求,都需要通过开发工具进行详细设置。建议您在使用ISP软件时,仔细阅读开发板的硬件手册,确保每个端口的配置与硬件设计相匹配。<br><br>此外,理解开发手册中的硬件描述和配置方法,对于后续的开发和调试将大有裨益。希望您在接下来的学习过程中,能够深入掌握这些基础知识,为后续的大型实战项目打下坚实的基础。继续加油!<br><br>[本文内容由国芯人工智能辅助生成,仅供参考]

z371322 发表于 2025-3-18 22:31:38

第二集,学习USB不停电下载,这集基本就是CV大法,为了方便观察我复制里一段延迟代码,做了个闪烁的LED灯进行观察代码如下:
#include "ai8051.h"
#include "stc32_stc8_usb.h"
#include "intrins.h"
//#include "stdio.h"

#define MAIN_Fosc      24000000UL

voiddelay_ms(u8 ms);

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

void main(void)
{
        u8 i=0;
       
        P_SW2 |= 0x80;
       
        P0M1 = 0x00;   P0M0 = 0xff;   //设置为推挽输出
    P1M1 = 0x00;   P1M0 = 0x00;   //设置为准双向口
    P2M1 = 0x00;   P2M0 = 0xff;   //设置为准双向口
    P3M1 = 0x00;   P3M0 = 0x00;   //设置为准双向口
    P4M1 = 0x00;   P4M0 = 0x00;   //设置为准双向口
    P5M1 = 0x00;   P5M0 = 0x00;   //设置为准双向口
    P6M1 = 0x00;   P6M0 = 0x00;   //设置为准双向口
    P7M1 = 0x00;   P7M0 = 0x00;   //设置为准双向口
       
        usb_init();                                     //USB CDC 接口配置
    EA = 1;
    while (DeviceState != DEVSTATE_CONFIGURED);   //等待USB完成配置

       
        while(1)
        {
                if (bUsbOutReady)
      {
            USB_SendData(UsbOutBuffer,OutNumber);   //发送数据缓冲区,长度(接收数据原样返回, 用于测试)
            
            usb_OUT_done();
      }
                i++;
                if(i%128==0)
                {
                        P20=!P20;
                }
                delay_ms(5);
               
        }
}

voiddelay_ms(u8 ms)
{
   u16 i;
   do{
          i = MAIN_Fosc / 6000;
          while(--i);
   }while(--ms);
}

vb2002 发表于 2025-3-19 01:29:09

加油.
我好好多天没有学习了.
看来是要不停的学习才行

z371322 发表于 2025-3-19 22:27:28

第三集学习C语言基础和printf,
按照教程做结果编译报警告,printf打印结果不正常。

搞了半天重新从例程里复制了#include "stdio.h"头文件解决


#include "ai8051.h"
#include "stc32_stc8_usb.h"
#include "intrins.h"
#include "stdio.h"

#define MAIN_Fosc      24000000UL

#define u8 unsigned char
#define u16 unsigned int
      
u8 X=20;
u8 Y=11;
voiddelay_ms(u8 ms);

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

void main(void)
{
      u8 i=0;
      
      P_SW2 |= 0x80;
      
      P0M1 = 0x00;   P0M0 = 0xff;   //设置为推挽输出
    P1M1 = 0x00;   P1M0 = 0x00;   //设置为准双向口
    P2M1 = 0x00;   P2M0 = 0xff;   //设置为准双向口
    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;
    EA = 1;
    while (DeviceState != DEVSTATE_CONFIGURED);   //等待USB完成配置

      
      while(1)
      {
                if (bUsbOutReady)
      {
//            USB_SendData(UsbOutBuffer,OutNumber);   //发送数据缓冲区,长度(接收数据原样返回, 用于测试)
//            printf("STC YYDS\r\n");
                        printf("X / Y = %u \r\n",(u16)(X/Y));
                        printf("X %% Y = %u \r\n",(u16)(X%Y));
                        if(X>Y)
                        {
                              printf("条件为真\r\n");
                        }
                        else
                        {
                              printf("条件为假\r\n");
                        }
            usb_OUT_done();
      }
                i++;
                if(i%128==0)
                {
                        P20=!P20;
                }
                delay_ms(10);
               
      }
}

voiddelay_ms(u8 ms)
{
   u16 i;
   do{
          i = MAIN_Fosc / 6000;
          while(--i);
   }while(--ms);
}


z371322 发表于 2025-3-20 21:28:52

第四集学习打卡,视频的第六集,IO输入输出,学习很简单,跟着视频做很容易就能学会,我用的延迟函数是之前从例程里面复制的很好用,不用到ISP里面生成了,很方便。
#include "ai8051.h"
#include "stc32_stc8_usb.h"
#include "intrins.h"
#include "stdio.h"

#define MAIN_Fosc      24000000UL

#define u8 unsigned char
#define u16 unsigned int
       
u8 state=1;

voiddelay_ms(u8 ms);

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

void main(void)
{
        u8 i=0;
       
        WTST = 0;                                                                                                //设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
    EAXFR = 1;                                                                                                 //扩展寄存器(XFR)访问使能
    CKCON = 0;                                                                                                 //提高访问XRAM速度
       
        P_SW2 |= 0x80;
       
        P0M1 = 0x00;   P0M0 = 0xff;   //设置为推挽输出
    P1M1 = 0x00;   P1M0 = 0x00;   //设置为准双向口
    P2M1 = 0x00;   P2M0 = 0xff;   //设置为准双向口
    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;
    EA = 1;
    while (DeviceState != DEVSTATE_CONFIGURED);   //等待USB完成配置

       
        while(1)
        {
                if (bUsbOutReady)
      {
//            USB_SendData(UsbOutBuffer,OutNumber);   //发送数据缓冲区,长度(接收数据原样返回, 用于测试)
                  usb_OUT_done();
      }       
                        //            printf("STC YYDS\r\n");
               
                        //任务1:按下P32按钮灯亮,松开P32按钮灯灭;
//                        if(P32==0)                                                                        //判断P32按钮是否按下
//                        {
//                                P27=0;
//                        }
//                        else
//                        {
//                                P27=1;
//                        }
                       
                       
                        //任务2:按下P32按钮灯灭,松开P32按钮灯亮;
//                        if(P32==0)                                                                        //判断P32按钮是否按下
//                        {
//                                P27=1;
//                        }
//                        else
//                        {
//                                P27=0;
//                        }
                       
                       
                        //任务3:按一下灯亮,按一下灯灭
                        if(P32==0)                                                                        //判断P32按钮是否按下
                        {
                                delay_ms(20);
                                if(P32==0)
                                {
                                        state=!state;
                                        P27=state;
                                        if(state)
                                        {
                                                printf("灯灭了 %u \r\n",state);
                                        }
                                        else
                                        {
                                                printf("灯亮了 %u \r\n",state);
                                        }
                                        while(P32==0);
                                }
                        }       
      
                i++;
                if(i%128==0)
                {
                        P20=!P20;
                }
                delay_ms(5);
               
        }
}

voiddelay_ms(u8 ms)
{
   u16 i;
   do{
          i = MAIN_Fosc / 6000;
          while(--i);
   }while(--ms);
}

z371322 发表于 2025-3-20 21:40:17

IO输入输出课后练习1,要求按下P32一边4个灯亮,再按下P32换另外4颗灯亮。我发现P2端口和89c52一样,可以操作一组8个端口,这样就很方便了,只要给P2赋值0x0f,再或0xf0即可。
#include "ai8051.h"
#include "stc32_stc8_usb.h"
#include "intrins.h"
#include "stdio.h"

#define MAIN_Fosc      24000000UL

#define u8 unsigned char
#define u16 unsigned int
       
u8 state=1;

voiddelay_ms(u8 ms);

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

void main(void)
{
//        u8 i=0;
       
        WTST = 0;                                                                                                //设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
    EAXFR = 1;                                                                                                 //扩展寄存器(XFR)访问使能
    CKCON = 0;                                                                                                 //提高访问XRAM速度
       
        P_SW2 |= 0x80;
       
        P0M1 = 0x00;   P0M0 = 0xff;   //设置为推挽输出
    P1M1 = 0x00;   P1M0 = 0x00;   //设置为准双向口
    P2M1 = 0x00;   P2M0 = 0xff;   //设置为准双向口
    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;
    EA = 1;
    while (DeviceState != DEVSTATE_CONFIGURED);   //等待USB完成配置

       
        while(1)
        {
                if (bUsbOutReady)
      {
//            USB_SendData(UsbOutBuffer,OutNumber);   //发送数据缓冲区,长度(接收数据原样返回, 用于测试)
                  usb_OUT_done();
      }       
                        //            printf("STC YYDS\r\n");
               
                        //任务1:按下P32按钮灯亮,松开P32按钮灯灭;
//                        if(P32==0)                                                                        //判断P32按钮是否按下
//                        {
//                                P27=0;
//                        }
//                        else
//                        {
//                                P27=1;
//                        }
                       
                       
                        //任务2:按下P32按钮灯灭,松开P32按钮灯亮;
//                        if(P32==0)                                                                        //判断P32按钮是否按下
//                        {
//                                P27=1;
//                        }
//                        else
//                        {
//                                P27=0;
//                        }
                       
                       
                        //任务3:按一下灯亮,按一下灯灭
                        if(P32==0)                                                                        //判断P32按钮是否按下
                        {
                                delay_ms(20);
                                if(P32==0)
                                {
                                        state=!state;
                                       
                                        if(state)
                                        {
                                                P2=0xf0;
                                                printf("右边灯亮 %u \r\n",state);
                                        }
                                        else
                                        {
                                                P2=0x0f;
                                                printf("左边灯亮 %u \r\n",state);
                                        }
                                        while(P32==0);
                                }
                        }       
      
//                i++;
//                if(i%128==0)
//                {
//                        P20=!P20;
//                }
//                delay_ms(10);
               
        }
}

voiddelay_ms(u8 ms)
{
   u16 i;
   do{
          i = MAIN_Fosc / 6000;
          while(--i);
   }while(--ms);
}

z371322 发表于 2025-3-20 22:02:17

IO输入输出课后练习2,要求按下P32亮一颗灯,再按一下亮两颗灯,直到全亮。这里用到的方法是左移一位再或1,00000001左移一位,等于00000010|00000001=00000011。代码前面加了个if判断,如果变量state加到0xff之后将变量state置零。这里需要注意的是,如果将state变量直接赋值给P2端口,这样的效果是按一下LED除P20之外全量,因为此时的值是00000001,此时可以将变量取反后赋值给P2端口。这里我犯了一个错误,我将取反写成了P2=!state;这当然是错的,因为state结果不为零,取反后P2为0x00,此时灯全亮,正确的用法是P2=~state; "~"这个符号是按位取反符。此时结果正确,为了区分我加了一个变量LED_state来观察取反后的数值,然后用printf打印。
#include "ai8051.h"
#include "stc32_stc8_usb.h"
#include "intrins.h"
#include "stdio.h"

#define MAIN_Fosc      24000000UL

#define u8 unsigned char
#define u16 unsigned int
       
u8 state=0;
u8 LED_state=0;

voiddelay_ms(u8 ms);

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

void main(void)
{
//        u8 i=0;
       
        WTST = 0;                                                                                                //设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
    EAXFR = 1;                                                                                                 //扩展寄存器(XFR)访问使能
    CKCON = 0;                                                                                                 //提高访问XRAM速度
       
        P_SW2 |= 0x80;
       
        P0M1 = 0x00;   P0M0 = 0xff;   //设置为推挽输出
    P1M1 = 0x00;   P1M0 = 0x00;   //设置为准双向口
    P2M1 = 0x00;   P2M0 = 0xff;   //设置为准双向口
    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;
    EA = 1;
    while (DeviceState != DEVSTATE_CONFIGURED);   //等待USB完成配置

       
        while(1)
        {
                if (bUsbOutReady)
      {
//            USB_SendData(UsbOutBuffer,OutNumber);   //发送数据缓冲区,长度(接收数据原样返回, 用于测试)
                  usb_OUT_done();
      }       
                        //            printf("STC YYDS\r\n");
               
                        //任务1:按下P32按钮灯亮,松开P32按钮灯灭;
//                        if(P32==0)                                                                        //判断P32按钮是否按下
//                        {
//                                P27=0;
//                        }
//                        else
//                        {
//                                P27=1;
//                        }
                       
                       
                        //任务2:按下P32按钮灯灭,松开P32按钮灯亮;
//                        if(P32==0)                                                                        //判断P32按钮是否按下
//                        {
//                                P27=1;
//                        }
//                        else
//                        {
//                                P27=0;
//                        }
                       
                       
                        //任务3:按一下灯亮,按一下灯灭
                        if(P32==0)                                                                        //判断P32按钮是否按下
                        {
                                delay_ms(20);
                                if(P32==0)
                                {
                                        if(state==0xff)
                                        {
                                        state=0;
                                        }
                                        state=(state<<1)|1;
                                        LED_state=~state;
                                        P2=LED_state;
                                       
                                        printf("移位变量状态 %u \r\n",state);
                                        printf("LED变量状态 %u \r\n",LED_state);
                                        while(P32==0);
                                }
                        }       
      
//                i++;
//                if(i%128==0)
//                {
//                        P20=!P20;
//                }
//                delay_ms(10);
               
        }
}

voiddelay_ms(u8 ms)
{
   u16 i;
   do{
          i = MAIN_Fosc / 6000;
          while(--i);
   }while(--ms);
}

z371322 发表于 2025-3-21 22:35:46

第七集 定时器中断,本集主要学习什么是中断,AI5081U 中断的配置方法,并且使用ISP软件的定时器配置工具配置中断。
以下程序为本集课后练习的程序。
课后小练
                电子功德箱
                1:按下按钮1,串口显示”双倍功德时间“,再次按下显示”单倍功德时间“
                2:按下按钮2,双倍功德时间下串口显示”功德+2 当前功德:xxx“
                3:按下按钮2,单倍功德时间下串口显示”功德+1 当前功德:xxx“
                4:功德+1时,LED点亮1秒后熄灭表示功德成功点亮;
                5:功德+2时,LED点亮2秒后熄灭表示功德成功点亮;
               

#include "ai8051.h"
#include "stc32_stc8_usb.h"
#include "intrins.h"
#include "stdio.h"

#define MAIN_Fosc      24000000UL

#define u8 unsigned char
#define u16 unsigned int
       
u8 state=1;

voiddelay_ms(u8 ms);
void Timer0_Init_1(void);
void Timer0_Init_2(void);


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

void main(void)
{
        u8 i=0;
        u16 y=0;
        WTST = 0;                                                                                                //设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
    EAXFR = 1;                                                                                                 //扩展寄存器(XFR)访问使能
    CKCON = 0;                                                                                                 //提高访问XRAM速度
       
        P_SW2 |= 0x80;
       
        P0M1 = 0x00;   P0M0 = 0xff;   //设置为推挽输出
    P1M1 = 0x00;   P1M0 = 0x00;   //设置为准双向口
    P2M1 = 0x00;   P2M0 = 0xff;   //设置为准双向口
    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;
    EA = 1;
    while (DeviceState != DEVSTATE_CONFIGURED);   //等待USB完成配置

       
        while(1)
        {
                if (bUsbOutReady)
      {
//            USB_SendData(UsbOutBuffer,OutNumber);   //发送数据缓冲区,长度(接收数据原样返回, 用于测试)
                  usb_OUT_done();
      }       
                //课后小练
                /*电子功德箱
                1:按下按钮1,串口显示”双倍功德时间“,再次按下显示”单倍功德时间“
                2:按下按钮2,双倍功德时间下串口显示”功德+2 当前功德:xxx“
                3:按下按钮2,单倍功德时间下串口显示”功德+1 当前功德:xxx“
                4:功德+1时,LED点亮1秒后熄灭表示功德成功点亮;
                5:功德+2时,LED点亮2秒后熄灭表示功德成功点亮;
               
                if(P32==0)
                {
                        delay_ms(20);
                        if(P32==0)
                        {       
                */
                                state=!state;
                                if(state)
                                {
                                        printf("双倍功德时间\r\n");
                                        }
                                else
                                {
                                        printf("单倍功德时间\r\n");
                                }
                                while(P32==0);
                        }
                }
               
                if(P33==0)
                {
                        delay_ms(20);
                        if(P33==0)
                        {       
                                if(state)
                                {
                                        y=y+2;
                                        P27=0;
                                        printf("功德+2 当前功德 %u \r\n",y);
                                        Timer0_Init_2();
                                }
                                else
                                {
                                        y++;
                                        printf("功德+1 当前功德 %u \r\n",y);
                                        P27=0;
                                        Timer0_Init_1();
                                }
                                while(P33==0);
                        }
                }               
      
                i++;
                if(i%64==0)
                {
                        P20=!P20;
                }
                delay_ms(5);
               
        }
}

voiddelay_ms(u8 ms)
{
   u16 i;
   do{
          i = MAIN_Fosc / 6000;
          while(--i);
   }while(--ms);
}

void Timer0_Init_1(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_Init_2(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
{
        P27=1;
        TR0 = 0;
}

页: [1]
查看完整版本: 擎天柱学习:《8051U深度入门到32位51大型实战教学视频》,打卡