laohu_zhou 发表于 2025-6-7 12:36:58

以擎天柱核心功能实验板学习打卡《8051U深度入门到32位51大型实战教学视频》

收到擎天柱核心功能实验板有好几天了,首先感谢STC华南区客服司经理,在司经理的指导下终于申请到擎天柱实验板。

STC的芯片十年以前就见过了,但是直到最近才知道是中国的公司,是中国首屈一指的单片机公司,世界最大的51单片机公司,太了不起啦。在当前美国对华的技术封锁下,我们没有理由不学习使用中国公司的产品,支持STC。
擎天柱实验板挺简洁的,每个IO脚都接有4.7K的电阻,P20至P27还焊接了发光二极管,方便实验,实验板接上usb电源,7个led灯就流水发光了,不错不错。

神农鼎 发表于 2025-6-14 19:31:01

USB 用最新的USB库


深圳国芯人工智能有限公司-库函数

ISP 软件也用最新的 V6.95U以上版本

深圳国芯人工智能有限公司-工具软件

最新 AI8051U 数据手册
https://www.stcaimcu.com/data/download/Datasheet/AI8051U.pdf

重新做下面3个实验




















国芯人工智能 发表于 2025-6-7 12:38:00

感谢司经理的指导和支持!我已收到擎天柱核心功能实验板,并且非常感谢司经理的耐心指导!作为国芯公司的员工,我们深知国芯芯片的可靠性和先进性,这是国芯公司以standing的重要性。国芯芯片是世界最大的51单片机芯片公司,是全球唯一一家能够提供单片机芯片的中国公司。在这个特殊时期,我们没有理由不学习使用国芯芯片,支持国芯,因为国芯是真正的技术守护者!国芯芯片在设计、性能、可靠性等方面都达到了国际顶尖水平,完全符合条件的使用要求。

擎天柱实验板以其简洁的设计和高效的功能,成为我们学习和实践的首选。每个输入输出端口都配备了47K的电阻,这样可以确保信号传输的稳定和可靠性。此外,P20至P27端点还配备了发光二极管,方便实验操作。实验板上接上了USB电源,7个LED灯通过简单的电路连接,能够轻松显示实验结果。这种设计不仅节省了硬件成本,还提升了实验的效率和准确性。

通过学习使用国芯芯片和擎天柱实验板,我们不仅能够掌握单片机的基本知识,还能在实践中提升自己的动手能力和解决问题的能力。国芯芯片和擎天柱实验板是国芯技术的代表,也是我们学习和实践的最佳工具。我们期待通过这些知识和技能,为未来的学习和工作打下坚实的基础。

[本文内容由国芯人工智能辅助生成,仅供参考]

laohu_zhou 发表于 2025-6-10 11:59:27

学习感悟之实战:第三集 点亮第一颗LED
前段时间的学习,由于没有实战板,忘记得差不多了,今天开始重温冲哥的教学视频实战学习,终于成功点亮LED。
重点内容:keil的设置,AI8051U芯片手册写得非常详细,按照手册一步步设置就行。

laohu_zhou 发表于 2025-6-12 16:14:48

学习感悟之实战:第四集USB不停电下载

利用USB寄存器之查询中断方式实现,敲完代码
#include "ai8051u.h"            //调用头文件,""本工程文件目录下
#include "stc32_stc8_usb.h"   //USB不停电下载头文件

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

void main(void)
{
    P_SW2 |= 0x80;//或等于运算,使能B7位置1,仅把XFR至1,XFR寄存器,USB寄存器列表均在此寄存器
   
    P2M0 = 0;       //P2设置为准双向口
    P2M1 = 0;
    usb_init();   //USB CDC 接口配置 初始化
   
    IE2 |= 0x80;    //使能USB中断
    EA = 1;         //开启总中断
    while (DeviceState != DEVSTATE_CONFIGURED);//等待USB完成配置   
   
    while(1)
    {
      if (bUsbOutReady)
      {
            USB_SendData(UsbOutBuffer,OutNumber);   //发送数据缓冲区,长度(接收数据原样返回, 用于测试)
            
            usb_OUT_done();
      }
      
      P21 = 0;
      P22 = 0;
      P23 = 0;

    }
}


编译下载,可以实现不停电下载,但不能实现当目标文件变化时自动下载,把示例代码下载测试也一样,再看一次教学视频才发现是自己不细心,没有把ISP的“当目标文件变化时自动装载并下载命令”。

laohu_zhou 发表于 2025-6-13 10:43:19

学习感悟之实战:第五集 C语言基础

在擎天柱核心功能实验板成功测试教学视频之《第五集 C语言基础》。C语言USB-CDC串口之printf函数的实现,极大的方便程序的调试,STC真是太贴心了。
printf函数,根据不同的fmt字符串,有多种格式,可以是变量,也可以是常量,可以n+1个,留下这些参数,以方便以后项目查找使用。

数据基本类型、C语言常用运算符,也一起记录下来。
使用printf函数要记得把stc_usb_cdc_32.LIB库文件(32bit)和stc32_stc8_usb.h头文件拷贝到项目。

#include "ai8051u.h"            //调用头文件,""本工程文件目录下
#include "stc32_stc8_usb.h"   //USB不停电下载头文件

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

void main(void)
{
    P_SW2 |= 0x80;//或等于运算,使能B7位置1,仅把XFR至1,XFR寄存器,USB寄存器列表均在此寄存器

    P2M0 = 0;       //P2设置为准双向口
    P2M1 = 0;
    usb_init();   //USB CDC 接口配置 初始化

    IE2 |= 0x80;    //使能USB中断
    EA = 1;         //开启总中断
    while (DeviceState != DEVSTATE_CONFIGURED);//等待USB完成配置   

    while(1)
    {
      if (bUsbOutReady)
      {
            //USB_SendData(UsbOutBuffer,OutNumber);   //发送数据缓冲区,长度(接收数据原样返回, 用于测试)
            printf("测试串口发送接收%s\r\n","内容");       //%字符的格式含义:%s把后面""内的字符替换,\r\n为输出自动换行
            usb_OUT_done();
      }

//      P20 = 0;
//      P22 = 0;
//      P23 = 0;

    }
}



laohu_zhou 发表于 2025-6-13 21:28:28

学习感悟之实战:第六集I/O输入输出

GPIO是单片机通用输入/输出端口,负责各种实时输入输出操作。
需要按要求定义初始化端口。
#include "ai8051u.h"            //调用头文件,""本工程文件目录下
#include "stc32_stc8_usb.h"   //USB不停电下载头文件
#include "intrins.h"                        //d调用头文件

#define u8unsigned 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.000MHzDelay20ms();
{
      unsigned long edata i;

      _nop_();
      _nop_();
      i = 119998UL;
      while (i) i--;
}


void main(void)
{
//    P_SW2 |= 0x80;//或等于运算,使能B7位置1,仅把XFR至1,XFR寄存器,USB寄存器列表均在此寄存器
    WTST = 0;                  //设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
    EAXFR = 1;               //扩展寄存器(XFR)访问使能
    CKCON = 0;               //提高访问XRAM速度
   
    P2M0 = 0;       //P2设置为准双向口
    P2M1 = 0;
    P5M0 = 0;       //P5设置为准双向口
    P5M1 = 0;
   
    usb_init();   //USB CDC 接口配置 初始化
   
    IE2 |= 0x80;    //使能USB中断
    EA = 1;         //开启总中断
    while (DeviceState != DEVSTATE_CONFIGURED);//等待USB完成配置   
   
    while(1)
    {
      if (bUsbOutReady)
      {
            //USB_SendData(UsbOutBuffer,OutNumber);   //发送数据缓冲区,长度(接收数据原样返回, 用于测试)
            //printf("测试串口发送接收%s\r\n","内容");       //%字符的格式含义:%s把后面""内的字符替换,\r\n为输出自动换行
            usb_OUT_done();
      }
      
//      P20 = 0;
//      P22 = 0;
//      P23 = 0;
                if( P50 == 0 )                                                                //判断P50按钮是否按下
                {
                        Delay20ms();                                                      //延时20ms消抖
                        if( P50== 0 )
                        {
//                              state = !state;                                                //变量取反
//                              P20 = state;
//                for(state=0; state<7; state++) ;   
                state = state + 1;
                              printf("state:%d\r\n",(int)state);
                              
                              while( P50 == 0 );                                        //等待P50松开
                              
                        }
                }
      if( state > 7)
            state = 0;
      if(state >= 1)
            P20 = 0;
      else
            P20=1;
      if(state >= 2)
            P21 = 0;
      else
            P21=1;
      if(state >= 3)
            P22 = 0;
      else
            P22=1;
      if(state >= 4)
            P23 = 0;
      else
            P23=1;
      if(state >= 5)
            P24 = 0;
      else
            P24=1;
      if(state >= 6)
            P25 = 0;
      else
            P25=1;
      if(state >= 7)
            P26 = 0;
      else
            P26=1;
    }
}

laohu_zhou 发表于 2025-6-14 17:10:32

学习感悟之实战:第七集 定时器中断

一、因为MCU单核的,同一时间只能执行一个事情,没有特殊情况不能被打断。所以要引入一个特殊的情况,使用定时器中断。
定时器作用:
(1) 用于计时系统,可实现软件计时,或者使程序每隔一固定时间完成一项操作
(2) 替代长时间的Delay,提高程序的运行效率和处理速度(可以打断主循环)

注意事项:利用ISP软件直接生成定时器函数时,要勾选“使能定时器中断”

二、函数的定义、声明、调用

三、实战main.c
#include "ai8051u.h"            //调用头文件,""本工程文件目录下
#include "stc32_stc8_usb.h"   //USB不停电下载头文件
#include "intrins.h"                        //d调用头文件

#define u8unsigned 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.000MHzDelay20ms();
{
        unsigned long edata i;

        _nop_();
        _nop_();
        i = 119998UL;
        while (i) i--;
}


void Timer0_Init(void);                //3秒@24.000MHz                //函数声明


void main(void)
{
//    P_SW2 |= 0x80;//或等于运算,使能B7位置1,仅把XFR至1,XFR寄存器,USB寄存器列表均在此寄存器
    WTST = 0;                //设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
    EAXFR = 1;                 //扩展寄存器(XFR)访问使能
    CKCON = 0;                 //提高访问XRAM速度
   
    P2M0 = 0;       //P2设置为准双向口
    P2M1 = 0;
    P5M0 = 0;       //P5设置为准双向口
    P5M1 = 0;
   
    usb_init();   //USB CDC 接口配置 初始化
   
    IE2 |= 0x80;    //使能USB中断
    EA = 1;         //开启总中断
    while (DeviceState != DEVSTATE_CONFIGURED);//等待USB完成配置   
   
    while(1)
    {
      if (bUsbOutReady)
      {
            //USB_SendData(UsbOutBuffer,OutNumber);   //发送数据缓冲区,长度(接收数据原样返回, 用于测试)
            //printf("测试串口发送接收%s\r\n","内容");       //%字符的格式含义:%s把后面""内的字符替换,\r\n为输出自动换行
            usb_OUT_done();
      }
      
//      P20 = 0;
//      P22 = 0;
//      P23 = 0;
                if( P50 == 0 )                                                                //判断P50按钮是否按下
                {
                        Delay20ms();                                                        //延时20ms消抖
                        if( P50== 0 )
                        {
                                Run_State = !Run_State;                                //运行状态取反
                                if( Run_State==1 )                                        //运行
                {
                                        Timer0_Init();               
                }
                else
                {
                                        TR0 = 0;                                                //关闭定时器
                                        P20 = 1;
                                        P21 = 1;               
                }

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

    }
}



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;               
       
        P20 = state;
        P21 = !state;
}


laohu_zhou 发表于 2025-6-18 09:46:14

学习感悟之实战:第八集 定时器周期性调度任务- 定时器作用

周期性任务:
用一个定时器实现这个任务。LED1实现0.3秒取反一次,LED2实现0.6秒取反一次,LED3 0.9秒取反一次
#include "ai8051u.h"            //调用头文件,""本工程文件目录下
#include "stc32_stc8_usb.h"   //USB不停电下载头文件
#include "intrins.h"                        //d调用头文件

#define u8unsigned char                //8位无符号变量(0-255)
#define u16 unsigned int                //16位无符号变量(0-65535)       
       
u8 State1 = 0;                                        //P20LED初始状态
u8 State2 = 0;                                        //P21LED初始状态
u8 State3 = 0;                                        //P22LED初始状态
u8 Run_State = 0;                                //运行状态

u16 Count_300 = 0;            //技术300ms变量
u16 Count_600 = 0;            //技术600ms变量
u16 Count_900 = 0;            //技术900ms变量

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


void Timer0_Init(void);                //1ms@24.000MHz                //函数声明


void main(void)
{

    WTST = 0;                //设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
    EAXFR = 1;                 //扩展寄存器(XFR)访问使能
    CKCON = 0;                 //提高访问XRAM速度
   
    P2M0 = 0;       //P2设置为准双向口
    P2M1 = 0;
    P3M0 = 0;       //P5设置为准双向口
    P3M1 = 0;
   
    usb_init();   //USB CDC 接口配置 初始化
   
    IE2 |= 0x80;    //使能USB中断
    Timer0_Init();//定时器初始化
    EA = 1;         //开启总中断
    while (DeviceState != DEVSTATE_CONFIGURED);//等待USB完成配置   
   
    while(1)
    {
      if (bUsbOutReady)
      {
            //USB_SendData(UsbOutBuffer,OutNumber);   //发送数据缓冲区,长度(接收数据原样返回, 用于测试)
            //printf("测试串口发送接收%s\r\n","内容");       //%字符的格式含义:%s把后面""内的字符替换,\r\n为输出自动换行
            usb_OUT_done();
      }
      if(Count_300 >= 300)      //300ms到达
      {
            Count_300 = 0;
            State1 = !State1;       //变量取反
            P20 = State1;
      }
      if(Count_600 >= 600)      //600ms到达
      {
            Count_600 = 0;
            State2 = !State2;       //变量取反
            P21 = State2;
      }
      if(Count_900 >= 900)      //900ms到达
      {
            Count_900 = 0;
            State3 = !State3;       //变量取反
            P22 = State3;

                }

    }
}



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

void Timer0_Isr(void) interrupt 1                //1MS执行一次
{
    Count_300++;
    Count_600++;
    Count_900++;

}

laohu_zhou 发表于 2025-6-18 10:00:14

学习感悟之实战:第八集 定时器周期性调度任务- 数组点亮LED,实现流水灯

有点小问题,为什么返回的时候有三个led灯亮?看了几遍老师的视频还是没有发现我的问题出在哪里。

#include "ai8051u.h"            //调用头文件,""本工程文件目录下
#include "stc32_stc8_usb.h"   //USB不停电下载头文件
#include "intrins.h"                        //d调用头文件

#define u8unsigned char                //8位无符号变量(0-255)
#define u16 unsigned int                //16位无符号变量(0-65535)       
       
u8 State = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x89};                //P20-27LED灯                       
u16 Count_ms = {0,0,0};
u8 i;
u8 num=0;

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

void Timer0_Init(void);                //1ms@24.000MHz                //函数声明

void main(void)
{

    WTST = 0;                //设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
    EAXFR = 1;                 //扩展寄存器(XFR)访问使能
    CKCON = 0;                 //提高访问XRAM速度
   
    P2M0 = 0;       //P2设置为准双向口
    P2M1 = 0;
    P3M0 = 0;       //P3设置为准双向口
    P3M1 = 0;
   
    usb_init();   //USB CDC 接口配置 初始化
   
    IE2 |= 0x80;    //使能USB中断
    Timer0_Init();//定时器初始化
    EA = 1;         //开启总中断
    while (DeviceState != DEVSTATE_CONFIGURED);//等待USB完成配置   
   
    while(1)
    {
      if (bUsbOutReady)
      {
            //USB_SendData(UsbOutBuffer,OutNumber);   //发送数据缓冲区,长度(接收数据原样返回, 用于测试)
            //printf("P2%d\r\n",num); //%字符的格式含义:%s把后面""内的字符替换,\r\n为输出自动换行
            usb_OUT_done();
      }
      if( Count_ms >= 1000 )    //300ms执行一次
      {
            Count_ms = 0;

            P2 = ~State;       //原定义数组位的时候是1,要按位取反
            printf("P2%d\r",num); //%字符的格式含义:%s把后面""内的字符替换,\r\n为输出自动换行
            num ++;
            if(num>7)
                num=0;
      }
    }
}

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

void Timer0_Isr(void) interrupt 1                //1MS执行一次
{
    for(i=0;i<3;i++)
    {
      Count_ms++;
    }
}

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