yzhkpli 发表于 昨天 12:02

stc32g 9.4实验箱-冲哥教学视频学习笔记兼对比8051U实验箱学习

打算搞一个8051U实验箱,看了一下冲哥的8051U教学视频,发现因为没有实物没法实验。
以前买过stc32g 9.4的实验箱和stc8H的9.6实验箱(差生文具多{:4_167:})


所以打算先学冲哥的stc32g 9.4实验箱视频,试验跑通后再记录8051U教学视频的笔记。




从冲哥的stc32g 9.4实验箱视频第三集开始:开发环境搭建和程序下载

下载stc-isp软件地址: https://stcai.com/gjrj
我下载了 2026年3月最新版 AiCube-ISP-v6.96T
使用win10 lstc2021,已经不需要安装usb驱动。


yzhkpli 发表于 昨天 12:11

第四集:建立工程点亮第一颗LED上

摘要
1-LED 点亮原理。
2-新建工程
3-点亮第一个 LED
4-实现自动下载工程

烧写程序使用了官方的示例程序

STC32G-DEMO-CODE-V9.4\01-用P6口做跑马灯\C语言

主程序略。

在程序开头注释
使用Keil C251编译器,Memory Model推荐设置XSmall模式,默认定义变量在edata,单时钟存取访问速度快。
edata建议保留1K给堆栈使用,空间不够时可将大数组、不常用变量加xdata关键字定义到xdata空间。

咨询了tongyiqianwen答复是:
根据 Keil C251 编译器的架构特性,您的理解存在偏差。XSmall 模式并不推荐作为通用设置,且其默认变量存储区并非 edata。
在 Keil C251 中,XSmall 模式主要是为了兼容旧版 Keil C251 V2 编译器而保留的,其默认将变量存储在片内 data 区域。
⚙️ Keil C251 内存模型详解
Keil C251 编译器提供了三种内存模型,用于决定未明确指定存储类型的变量的默认存放位置。

内存模型 (Memory Model)        默认存储区        地址范围                特点
XSmall        data        片内 RAM 低 128 字节        访问速度最快,但空间极其有限。主要用于兼容旧项目。
Small        data        片内 RAM 低 128 字节        最常用且推荐的模式。能生成最高效的代码,适用于绝大多数应用。
Large        xdata        外部 RAM (最高64KB)        变量空间巨大,但访问速度相对较慢,因为需要通过数据指针 (DPTR) 间接寻址。

核心要点与建议
        1-推荐设置:对于新的 C251 项目,通常推荐使用 Small 模式。它在代码效率和易用性之间取得了最佳平衡。
        2-默认存储区:XSmall 和 Small 模式的默认存储区都是 data,而不是 edata。edata 通常指扩展的片内 RAM(如 8052 的 128-255 字节),需要通过 idata 关键字间接寻址访问。
        3-灵活管理内存:无论选择哪种模型,您都可以在代码中显式地使用存储类型关键字(如 xdata, idata, pdata 等)来精确控制特定变量的存放位置,以优化程序性能。
                高频访问变量:如循环计数器,应放在 data 区。
                大型数组/缓冲区:建议用 xdata 关键字显式定义,即使在小模式下,也能将其放至外部 RAM,避免耗尽宝贵的片内 RAM。


直接使用官方的project。rebuild,然后
rebuild输出
Program Size: data=8.0 edata+hdata=257 xdata=0 const=0 code=169


咨询了tongyiqianwen coder 模型,

咨询了coder模型

对于 STC32G 这样的现代增强型 8051 芯片,Keil C251 编译器对 XSmall 模式进行了扩展:
传统 8051:在传统的 8051 架构中,XSmall 模式将未指定存储区的变量放入 data (片内 RAM 低 128 字节)。
现代增强型 8051 (如 STC32G):由于芯片功能强大,内部集成了更多的特殊功能寄存器 (SFR) 和额外的片内 RAM。
编译器会将这部分新增的片内 RAM 视为一个独立的、高效的内存区域,即 edata (Extended Data)。
因此,在 XSmall 模式下,编译器会优先将变量分配到这片 edata 空间中。


hdata:为更大内存而生
hdata 是 Keil C251 编译器为支持更大地址空间的新型 8051 单片机(如 STC32G)而引入的存储类型。
        物理位置:扩展的外部 RAM。
        地址范围:理论上可寻址高达 16MB 的空间(地址 0x000000 - 0xFFFFFF)。
        用途:当您的应用程序数据量巨大,连 64KB 的 xdata 空间都不够用时,就需要使用 hdata 来访问更大的内存区域


为什么会这样?
edata 相对于 xdata 有以下优势:
速度快:访问 edata 的速度远快于访问外部 xdata。
效率高:edata 的寻址方式比 xdata 更高效。
所以,当编译器发现一个变量没有被明确指定存储区时,它会优先选择最快的可用内存空间。
对于 STC32G,这片最快的额外空间就是 edata。这就是为什么您的变量 ledIndex 出现在了 edata 区域。

而data=8.0 到底是什么?
data=8.0 表示的是 程序总共需要的 data 段(片内低 128 字节 RAM)的大小为 8 字节。
这个值不是指某个特定的变量,而是由多个因素共同构成的总和。它主要包括以下几个部分:
系统/运行时开销 (System Overhead):
        编译器和链接器需要为程序的正常运行预留一些空间。例如,一些内部的工作寄存器、临时变量或函数调用时的参数传递空间等,可能会被分配到这里。
中断向量表 (Interrupt Vector Table):
        虽然中断向量本身在 code 区,但处理中断时所需的现场保护(保存 CPU 寄存器)和恢复操作,通常会在 data 区进行,这会占用少量空间。
堆栈 (Stack):
        这是最主要的部分。在 XSmall、Small 等模式下,系统的硬件堆栈指针 (SP) 通常被初始化指向 data 区域。当发生函数调用、中断或使用 push/pop 指令时,数据会被压入和弹出这个位于 data 区的堆栈。链接器会估算一个最小的堆栈空间需求,并将其计入 data 段的总大小。例如,您的 main 函数调用 delay_ms,delay_ms 函数内的局部变量 i 和函数返回地址都会用到堆栈。
被强制分配到 data 区的变量:
        如果您的代码中有 data u8 someVar; 这样的声明,那么 someVar 就会占用 data 区的空间。
🧠 在您程序中的具体体现
        在您提供的这个简单程序中,data=8.0 基本上可以理解为 系统为您的程序分配的、用于函数调用和中断处理的最小堆栈空间。
        ledIndex 变量本身(以及其他未明确指定存储区的变量)并没有进入 data 区,而是被编译器优化到了速度同样很快的 edata 区。
        ledNum 数组被 code 关键字修饰,它存储在程序代码区,不占用 data 或 xdata。
        delay_ms 函数中的局部变量 i 在函数执行期间需要在堆栈上分配空间,这就构成了对 data 区的需求。
💡 总结
        data=8.0 并不是一个具体的变量名,而是链接器计算出的,您的程序在片内低 128 字节 RAM (data 区) 中所必需使用的总空间量。
        在您的程序中,这 8 字节很可能是为函数调用堆栈预留的最小空间,加上少量的系统开销。

神农鼎 发表于 昨天 12:30

要 做到 USB不停电下载;
要 尝试 AiCube 图形化自动配置生成程序工具;
推荐优先看的:
printf_usb("Hello World !\r\n")及
USB不停电下载, 演示视频链接:
https://www.stcaimcu.com/thread-19077-1-1.html

下载 最新的 AiCube-ISP-V6.96T 或以上版本软件 !
深圳国芯人工智能有限公司-工具软件

下载 最新的 USB库函数,永远用最新的 USB库函数 !
深圳国芯人工智能有限公司-库函数
下载 最新的 用户手册 !
下载 最新的 上机实践指导书 !

下载 最新的 Ai8051U 用户手册
https://www.stcaimcu.com/data/download/Datasheet/AI8051U.pdf

下载 最新的 Ai8051U 实验指导书,
有 AiCube 图形化自动配置生成程序工具使用说明
https://www.stcaimcu.com/data/do ... %AF%BC%E4%B9%A6.pdf

https://v.stcai.com/sv/1c5eec2-197fcd9b766/1c5eec2-197fcd9b766.mp4
上面是 小李 演示:Ai8051U, printf_usb("Hello World !\r\n")及usb不停电下载@AiCube之图形化程序自动生成

下载 最新的 STC32G12K128 用户手册
https://www.stcaimcu.com/data/download/Datasheet/STC32G.pdf

下载 最新的 STC32G12K128 实验指导书
有 AiCube 图形化自动配置生成程序工具使用说明
https://www.stcaimcu.com/data/do ... %AF%BC%E4%B9%A6.pdf

https://v.stcai.com/sv/44b59184-197d39b65f2/44b59184-197d39b65f2.mp4
上面是 小李 演示:STC32G12K128, printf_usb("Hello World !\r\n")及usb不停电下载@AiCube之图形化程序自动生成

神农鼎 发表于 昨天 12:31


yzhkpli 发表于 昨天 15:25

冲哥stc32G第4集:建立工程点亮第一颗LED上
实验箱原理图是首先要P40给与一个低电平,打通Q11 SS8550三极管,
然后P60~P67设置低电平后,则 与之连接的led被点亮。

在原理手册中搜索"I/O 口相关寄存器",查到对应的端口的寄存器

sfr P4   = 0xC0;
sfr P4M1 = 0xB3;
sfr P4M0 = 0xB4;

sfr P6   = 0xE8;
sfr P6M1 = 0xCB;
sfr P6M0 = 0xCC;

sbit P40=P4^0;
sbit P60=P6^0;
sbit P67=P6^7;

void main()
{
    P4M0 = 0x00;
    P4M1 = 0x00;
       
    P6M0 = 0x00;
    P6M1 = 0x00;

    while (1)
    {
                        P40=0;//三极管控制引脚输出低电平
                        P67=0;//led引脚输出低电平
    }
}

build的时候报告
Build target 'Target 1'
Target has no object modules
Target not created.
Build Time Elapsed:00:00:01

错误信息 "Target has no object modules" 表明 Keil C251 编译器没有找到任何需要编译的源文件,
或者虽然找到了源文件但没有成功将其编译成目标模块(.obj 文件)。
这个问题通常由以下几个原因造成,请按顺序检查:
1. 检查文件是否已添加到项目中
这是最常见的原因。即使你创建了 main.c 文件,也必须将它添加到项目的 "Source Group" 中。
打开你的项目。
在左侧的 "Project" 窗口中,展开 "Target 1"。
检查 "Source Group 1" 下面是否有 main.c 文件。
如果没有:
        右键点击 "Source Group 1"。
        选择 "Add Files to Group 'Source Group 1'..."。
        在弹出的对话框中,找到并选中你的 main.c 文件,点击 "Add"。
        点击 "Close"。


这次编译成功,下载后,实验箱的最左边的led点亮。

原理图上显示三极管Q11和P60管脚连接R95+led最相近,但是实际布局中三极管Q11紧靠着P6.7连接的R102电阻+led。
所以P67管脚 设置为低电平时候,靠近Q11的那个,也是最左边的led被点亮。

yzhkpli 发表于 3 小时前

第四课的时候遇到一个麻烦事,使用最新的AiCube-ISP-v6.96T,写入程序卡住了,右下角显示:
正在等待HID-ISP ...

注意左上角的com6,显示是2CDC

换用老式的 stc-isp-v6.94L

com6的显示就不一样了,显示是2CDC+HID。最后用6.94L烧写成功了。

yzhkpli 发表于 半小时前

第四讲不断电下载的程序例子
参考 STC32G-DEMO-CODE-V9.4\76-通过USB HID协议打印数据信息-可用于调试

代码如下,GPIO端口模式无所谓,可以都设置为0x00
#include "./COMM/stc.h"
#include "./COMM/usb.h"


void sys_init();

//USB调试及复位所需定义
char *USER_DEVICEDESC = NULL;
char *USER_PRODUCTDESC = NULL;
char *USER_STCISPCMD = "@STCISP#";                      //设置自动复位到ISP区的用户接口命令

BYTE xdata cod;

//// 示例:编写一个回调函数
//void my_usb_in_callback(void) {
//    // 在这里处理USB IN传输完成后的逻辑
//    // 例如,点亮一个LED,设置一个标志位等
//}
BYTE xdata cod;
void main()
{
                //USER_STCISPCMD = "@STCISP#";
    sys_init();
                usb_init();//该函数声明在stc32_stc8_usb.h中,定义在stc_usb_hid_32g.LIB中
                EA=1;
       
// 注册回调函数(这行代码“调用”了 set_usb_IN_callback)
//   set_usb_IN_callback(my_usb_in_callback);
//// 例如,通过函数调用来设置ISP命令
//    set_usb_ispcmd("@MY_CUSTOM_ISP_COMMAND#");
    while (1)
    {
      if (bUsbOutReady)
      {
//            memcpy(UsbInBuffer,UsbOutBuffer,64);//接收数据存放发送缓冲区
//            usb_IN();//原样返回接收数据,用于测试
            
            usb_OUT_done(); //接收应答(固定格式)
      }
                                //codes
    }
}

void sys_init()
{
    WTST = 0;//设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
    EAXFR = 1; //扩展寄存器(XFR)访问使能
    CKCON = 0; //提高访问XRAM速度

    P0M1 = 0x30;   P0M0 = 0x30;   //设置P0.4、P0.5为漏极开路(实验箱加了上拉电阻到3.3V)
    P1M1 = 0x32;   P1M0 = 0x32;   //设置P1.1、P1.4、P1.5为漏极开路(实验箱加了上拉电阻到3.3V), P1.1在PWM当DAC电路通过电阻串联到P2.3
    P2M1 = 0x3c;   P2M0 = 0x3c;   //设置P2.2~P2.5为漏极开路(实验箱加了上拉电阻到3.3V),设置开漏模式需要断开PWM当DAC电路中的R2电阻
    P3M1 = 0x50;   P3M0 = 0x50;   //设置P3.4、P3.6为漏极开路(实验箱加了上拉电阻到3.3V)
    P4M1 = 0x3c;   P4M0 = 0x3c;   //设置P4.2~P4.5为漏极开路(实验箱加了上拉电阻到3.3V)
    P5M1 = 0x0c;   P5M0 = 0x0c;   //设置P5.2、P5.3为漏极开路(实验箱加了上拉电阻到3.3V)
    P6M1 = 0xff;   P6M0 = 0xff;   //设置为漏极开路(实验箱加了上拉电阻到3.3V)
    P7M1 = 0x00;   P7M0 = 0x00;   //设置为准双向口

          //设置USB使用的时钟源
    IRC48MCR = 0x80;    //使能内部48M高速IRC
    while (!(IRC48MCR & 0x01));//等待时钟稳定
}

页: [1]
查看完整版本: stc32g 9.4实验箱-冲哥教学视频学习笔记兼对比8051U实验箱学习