神农鼎 发表于 2025-4-3 21:34:12

还是从 printf_usb("Hello World !\r\n") 开始,《单片机原理及应用》入门@Ai8051U

最新软件 版本是AiCube@AIapp-ISP V6.95T, 大家直接使用最新版本软件

以下是纯手敲代码, 未使用 AiCube@AIapp-ISP V6.95T :
还是从 printf_usb("Hello World !\r\n") 开始,及不停电自动下载
《单片机原理及应用》入门@Ai8051U
Ai8051U,这是32位8051的USB时代,printf_usb(),及不停电自动下载
https://v.stcai.com/sv/6707e7ef-1960e65e764/6707e7ef-1960e65e764.mp4
实验一:printf_usb("Hello World !\r\n"),
            第一个完整的C语言程序
实验二:查询方式,查询到电脑命令后,
            printf_usb("Hello World !\r\n")或其他
实验三:中断方式,单片机USB中断接收服务函数收到命令后,
            printf_usb("Hello World !\r\n")或其他

最新《单片机原理及应用@Ai8051U》,电子版教材
https://www.stcaimcu.com/data/download/Datasheet/AI8051U.pdf
最新 AIapp-ISP V6.95T 开发工具包
https://www.stcaimcu.com/data/download/Tools/AIapp-ISP-v6.95T.zip
https://v.stcai.com/sv/426d0d7d-1963d548feb/426d0d7d-1963d548feb.mp4
Ai8051U,利用 AiCube@AIapp-ISP
实验一:printf_usb("Hello World !\r\n"),
            第一个完整的C语言程序
实验二:查询方式,查询到电脑命令后,
            printf_usb("Hello World !\r\n")或其他
实验三:中断方式,单片机USB中断接收服务函数收到命令后,
            printf_usb("Hello World !\r\n")或其他

利用 AiCube@AIapp-ISP V6.95Q
AiCube-可视化 图形 I/O配置 及 各种外设 系统框架程序 自动生成 体验
https://v.stcai.com/sv/405d8868-196854dbbb3/405d8868-196854dbbb3.mp4

STC32G12K128,利用 AiCube@AIapp-ISP V6.95M
各功能模块智能配置及启动程序框架程序自动生成器,实现如下的实验:
32位8051单片机入门的第一个完整的C语言程序,
printf_usb("Hello World !\r\n") 及不停电下载
https://v.stcai.com/sv/4912a53-196e6d92db9/4912a53-196e6d92db9.mp4
STC32G12K128:
AiCube 实验一:直接 printf_usb("Hello World !\r\n")
===32位8051单片机入门的第一个完整的C语言程序

AiCube 实验二:查询方式,查询到电脑命令后,
                           printf_usb("Hello World !\r\n")或其他

AiCube 实验三:中断方式,单片机USB中断接收服务函数收到命令后,
                           printf_usb("Hello World !\r\n")或其他

STC8H8K64U:
AiCube 三个实验:
https://v.stcai.com/sv/5806c211-1975d931472/5806c211-1975d931472.mp4

https://v.stcai.com/sv/61b39596-197624e4e06/61b39596-197624e4e06.mp4

神农鼎 发表于 2025-4-15 12:44:44


2025/4/15:
利用 AiCube@AIapp-ISP V6.95M,
智能配置开发工具,实现如下的实验:
AiCube 实验一:直接 printf_usb("Hello World !\r\n")
32位8051单片机入门的第一个完整的C语言程序






2025/4/15:
利用 AiCube@AIapp-ISP V6.95M,
智能配置开发工具,实现如下的实验:
AiCube 实验一:直接 printf_usb("Hello World !\r\n")
32位8051单片机入门的第一个完整的C语言程序



深圳国芯人工智能有限公司-工具软件
keil C51/C251 编译器只支持31以内中断号,超过31编译报错。热心网友提供的简单KEIL中断号拓展工具,可将中断号拓展到254,在KEIL 未打开的状况下,运行【Keil 中断拓展插件】,将中断号拓展到254。

使用 AIapp-ISP V6.95M 或以上版本,在KEIL 未打开的状况下
重新添加一次新的头文件


添加的 新头文件 在这


使用 AIapp-ISP V6.95M 或以上版本中的 ,
AiCube 智能配置工具自动生成强大的初始化程序



对应的在 KEIL C251 中的 项目设置,已是最优,不需要修改


【可视图形化I/O口配置工具】本实验暂时不需要配置


选择用 出厂预置的 40MHz 高速IRC 时钟 跑用户程序
===如在这选择用户程序区用户程序自己去修改频率
===那ISP烧录时的频率会被改为上面的频率


选择使用【USB外设】;
选择本实验程序 使用【USB-CDC 通信协议】;
也可以选择本实验程序 使用【USB-HID 通信协议】;
其他设置本实验程序暂时用不到,直接点击【创建项目】


项目创建成功后,Keil 自动打开该【项目文件】



本程序用

printf_usb("Hello World !\r\n");
//直接打印输出"Hello World !\r\n" 到 主机端的 USB-CDC/HID-串口助手
//取代下面这行 AiCube 自动生成的语句
//USBLIB_OUT_Done();    //查询方式处理USB接收的数据

编译产生的 *.HEX文件在下面目录中


打开该目标文件,
AI8051U实验设备, P3.2按键按下,P3.2为低,
重新上电,点击【下载/编程】按钮, 烧录成功。
单片机/MCU, AI8051U,
自动运行 printf_usb("Hello World !\r\n")程序。



如上,点击【打开串口】


程序运行效果如上

具体程序如下:
////////////////////////////////////////
// 文件名称: main.c
// 文件描述:
// 文件版本: V1.0
// 修改记录:
//   1. (2025-04-15) 创建文件
////////////////////////////////////////


#include "config.h"                     //默认已包含stdio.h、intrins.h、ai_usb.h等头文件


////////////////////////////////////////
// 项目主函数
// 入口参数: 无
// 函数返回: 无
////////////////////////////////////////
void main(void)
{
    SYS_Init();


    while (1)
    {
      printf_usb("Hello World !\r\n");
      //直接打印输出"Hello World !\r\n" 到 主机端的 USB-CDC/HID-串口助手
      //取代下面这行 AiCube 自动生成的语句
                        //USBLIB_OUT_Done();            //查询方式处理USB接收的数据
    }
}


////////////////////////////////////////
// 系统初始化函数
// 入口参数: 无
// 函数返回: 无
////////////////////////////////////////
void SYS_Init(void)
{
    EnableAccessXFR();                  //使能访问扩展XFR
    AccessCodeFastest();                //设置最快速度访问程序代码
    AccessIXramFastest();               //设置最快速度访问内部XDATA
    IAP_SetTimeBase();                  //设置IAP等待参数,产生1us时基


    P0M0 = 0x00; P0M1 = 0x00;         //初始化P0口为准双向口模式
    P1M0 = 0x00; P1M1 = 0x00;         //初始化P1口为准双向口模式
    P2M0 = 0x00; P2M1 = 0x00;         //初始化P2口为准双向口模式
    P3M0 = 0x00; P3M1 = 0x00;         //初始化P3口为准双向口模式
    P4M0 = 0x00; P4M1 = 0x00;         //初始化P4口为准双向口模式
    P5M0 = 0x00; P5M1 = 0x00;         //初始化P5口为准双向口模式
    P6M0 = 0x00; P6M1 = 0x00;         //初始化P6口为准双向口模式
    P7M0 = 0x00; P7M1 = 0x00;         //初始化P7口为准双向口模式


    CLK_Init();                         //时钟模块初始化
    USBLIB_Init();                      //USB库初始化


    EnableGlobalInt();                  //使能全局中断
}


////////////////////////////////////////
// 毫秒延时函数
// 入口参数: ms (设置延时的毫秒值)
// 函数返回: 无
////////////////////////////////////////
void delay_ms(uint16_t ms)
{
    uint16_t i;


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




////////////////////////////////////////
// 时钟初始化函数
// 入口参数: 无
// 函数返回: 无
////////////////////////////////////////
void CLK_Init(void)
{
    CLK_SYSCLK_Divider(10);             //切换主时钟前先将系统时钟降频


    HIRC_40M();                         //选择内部预置的频率


    CLK_MCLK_HIRC();                  //选择内部高精度HIRC作为主时钟
    CLK_MCLK2_BYPASS();               //旁路MCLK2,直接使用MCLK选择


    CLK_SYSCLK_Divider(1);            //设置系统时钟分频系数


    CLK_HSIOCK_MCLK();                  //选择MCLK主时钟作为高速外设时钟源
    CLK_HSIOCK_Divider(1);            //设置高速外设时钟预分频系数


    CLK_SPICLK_Divider(1);            //设置SPI时钟预分频系数
    CLK_I2SCLK_Divider(1);            //设置I2S时钟预分频系数
    CLK_PWMACLK_Divider(1);             //设置PWMA时钟预分频系数
    CLK_PWMBCLK_Divider(1);             //设置PWMB时钟预分频系数
    CLK_TFPUCLK_Divider(1);             //设置TFPU时钟预分频系数
}


////////////////////////////////////////
// USB库初始化函数
// 入口参数: 无
// 函数返回: 无
////////////////////////////////////////
void USBLIB_Init(void)
{
    usb_init();                         //初始化USB模块
    USB_SetIntPriority(0);            //设置中断为最低优先级
    set_usb_ispcmd("@STCISP#");         //设置USB不停电下载命令
}


////////////////////////////////////////
// 等待USB配置完成函数
// 入口参数: 无
// 函数返回: 无
////////////////////////////////////////
void USBLIB_WaitConfiged(void)
{
    while (DeviceState != DEVSTATE_CONFIGURED); //等待USB完成配置
}


////////////////////////////////////////
// USB设备接收数据处理程序
// 入口参数: 无
// 函数返回: 无
// bUsbOutReady:USB设备接收数据标志位
// OutNumber:USB设备接收到的数据长度
// UsbOutBuffer:保存USB设备接收到的数据
////////////////////////////////////////
void USBLIB_OUT_Done(void)
{
    if (bUsbOutReady)                   //查询是否有接收到USB主机发送数据
    {
      USB_SendData(UsbOutBuffer, OutNumber); //原路返回, 用于测试
      usb_OUT_done();               //当前包的数据处理完成,通知USB主机可以发送下一包数据
    }
}






神农鼎 发表于 2025-4-15 23:29:56

2025/4/15:
利用 AiCube@AIapp-ISP V6.95M,
智能配置开发工具,实现如下的实验:
AiCube 实验二:查询方式,查询到电脑命令后,
                           printf_usb("Hello World !\r\n")或其他
https://v.stcai.com/sv/426d0d7d-1963d548feb/426d0d7d-1963d548feb.mp4
32位8051单片机入门的第一个完整的C语言程序



2025/4/15:
利用 AiCube@AIapp-ISP V6.95M,
智能配置开发工具,实现如下的实验:
AiCube 实验二:查询方式,查询到电脑命令后,
                           printf_usb("Hello World !\r\n")或其他
32位8051单片机入门的第一个完整的C语言程序



深圳国芯人工智能有限公司-工具软件
keil C51/C251 编译器只支持31以内中断号,超过31编译报错。热心网友提供的简单KEIL中断号拓展工具,可将中断号拓展到254,在KEIL 未打开的状况下,运行【Keil 中断拓展插件】,将中断号拓展到254。
使用 AIapp-ISP V6.95M 或以上版本,在KEIL 未打开的状况下
重新添加一次新的头文件

添加的 新头文件 在这


使用 AIapp-ISP V6.95M 或以上版本中的 ,
AiCube 智能配置工具自动生成强大的初始化程序



对应的在 KEIL C251 中的 项目设置,已是最优,不需要修改


【可视图形化I/O口配置工具】本实验暂时不需要配置


选择用 出厂预置的 40MHz 高速IRC 时钟 跑用户程序
===如在这选择用户程序区用户程序自己去修改频率
===那ISP烧录时的频率会被改为上面的频率


选择使用【USB外设】;
选择本实验程序 使用【USB-CDC 通信协议】;
也可以选择本实验程序 使用【USB-HID 通信协议】;
其他设置本实验程序暂时用不到,直接点击【创建项目】



项目创建成功后,Keil 自动打开该【项目文件】



将下面这段程序
USB_SendData(UsbOutBuffer, OutNumber); //用户修改本行程序去达到自己的目的
改成:
if(UsbOutBuffer==6)
      printf_usb("HelloWorld!\r\n"); //如接收到的数据包的第0个字节是6,打印“HelloWorld!"
else if(UsbOutBuffer==7)
      printf_usb("China!\r\n");//如接收到的数据包的第0个字节是7,打印“China!"

编译产生的 *.HEX文件在下面目录中

用 ISP软件 打开该目标文件,
AI8051U实验设备, P3.2按键按下,P3.2为低,
重新上电,点击【下载/编程】按钮, 烧录成功。
单片机/MCU, AI8051U,
自动运行 printf_usb("Hello World !\r\n")程序。



如上,点击【打开串口】


程序运行效果如上

具体程序如下
////////////////////////////////////////
// 文件名称: main.c
// 文件描述:
// 文件版本: V1.0
// 修改记录:
//   1. (2025-04-15) 创建文件
////////////////////////////////////////

#include "config.h"                     //默认已包含stdio.h、intrins.h、ai_usb.h等头文件

////////////////////////////////////////
// 项目主函数
// 入口参数: 无
// 函数返回: 无
////////////////////////////////////////
void main(void)
{
    SYS_Init();

    while (1)
    {
      USBLIB_OUT_Done();            //查询方式处理USB接收的数据
    }
}

////////////////////////////////////////
// 系统初始化函数
// 入口参数: 无
// 函数返回: 无
////////////////////////////////////////
void SYS_Init(void)
{
    EnableAccessXFR();                  //使能访问扩展XFR
    AccessCodeFastest();                //设置最快速度访问程序代码
    AccessIXramFastest();               //设置最快速度访问内部XDATA
    IAP_SetTimeBase();                  //设置IAP等待参数,产生1us时基

    P0M0 = 0x00; P0M1 = 0x00;         //初始化P0口为准双向口模式
    P1M0 = 0x00; P1M1 = 0x00;         //初始化P1口为准双向口模式
    P2M0 = 0x00; P2M1 = 0x00;         //初始化P2口为准双向口模式
    P3M0 = 0x00; P3M1 = 0x00;         //初始化P3口为准双向口模式
    P4M0 = 0x00; P4M1 = 0x00;         //初始化P4口为准双向口模式
    P5M0 = 0x00; P5M1 = 0x00;         //初始化P5口为准双向口模式
    P6M0 = 0x00; P6M1 = 0x00;         //初始化P6口为准双向口模式
    P7M0 = 0x00; P7M1 = 0x00;         //初始化P7口为准双向口模式

    CLK_Init();                         //时钟模块初始化
    USBLIB_Init();                      //USB库初始化

    EnableGlobalInt();                  //使能全局中断
}

////////////////////////////////////////
// 毫秒延时函数
// 入口参数: ms (设置延时的毫秒值)
// 函数返回: 无
////////////////////////////////////////
void delay_ms(uint16_t ms)
{
    uint16_t i;

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


////////////////////////////////////////
// 时钟初始化函数
// 入口参数: 无
// 函数返回: 无
////////////////////////////////////////
void CLK_Init(void)
{
    CLK_SYSCLK_Divider(10);             //切换主时钟前先将系统时钟降频

    HIRC_40M();                         //选择内部预置的频率

    CLK_MCLK_HIRC();                  //选择内部高精度HIRC作为主时钟
    CLK_MCLK2_BYPASS();               //旁路MCLK2,直接使用MCLK选择

    CLK_SYSCLK_Divider(1);            //设置系统时钟分频系数

    CLK_HSIOCK_MCLK();                  //选择MCLK主时钟作为高速外设时钟源
    CLK_HSIOCK_Divider(1);            //设置高速外设时钟预分频系数

    CLK_SPICLK_Divider(1);            //设置SPI时钟预分频系数
    CLK_I2SCLK_Divider(1);            //设置I2S时钟预分频系数
    CLK_PWMACLK_Divider(1);             //设置PWMA时钟预分频系数
    CLK_PWMBCLK_Divider(1);             //设置PWMB时钟预分频系数
    CLK_TFPUCLK_Divider(1);             //设置TFPU时钟预分频系数
}

////////////////////////////////////////
// USB库初始化函数
// 入口参数: 无
// 函数返回: 无
////////////////////////////////////////
void USBLIB_Init(void)
{
    usb_init();                         //初始化USB模块
    USB_SetIntPriority(0);            //设置中断为最低优先级
    set_usb_ispcmd("@STCISP#");         //设置USB不停电下载命令
}

////////////////////////////////////////
// 等待USB配置完成函数
// 入口参数: 无
// 函数返回: 无
////////////////////////////////////////
void USBLIB_WaitConfiged(void)
{
    while (DeviceState != DEVSTATE_CONFIGURED); //等待USB完成配置
}

////////////////////////////////////////
// USB设备接收数据处理程序
// 入口参数: 无
// 函数返回: 无
// bUsbOutReady:USB设备接收数据标志位
// OutNumber:USB设备接收到的数据长度
// UsbOutBuffer:保存USB设备接收到的数据
////////////////////////////////////////
void USBLIB_OUT_Done(void)
{
    if (bUsbOutReady) //查询模式固定格式,查询是否有接收到USB主机发送数据
    {
      //USB_SendData(UsbOutBuffer, OutNumber); //用户修改本行程序去达到自己的目的
                        //上句是,将接收到的数据,原路返回, 送回主机,用于测试,可任意修改
                        if(UsbOutBuffer==6)
                                                printf_usb("HelloWorld!\r\n"); //如接收到的数据包的第0个字节是 6,打印“HelloWorld!"
                              else if(UsbOutBuffer==7)
                                                printf_usb("China!\r\n");      //如接收到的数据包的第0个字节是7,打印“China!"
                              
      usb_OUT_done();//查询模式固定格式,当前包的数据已处理完成,通知USB主机可以发送下一包数据
    }
}



神农鼎 发表于 2025-4-16 00:35:28


2025/4/16:
利用 AiCube@AIapp-ISP V6.95M,
智能配置开发工具,实现如下的实验:
AiCube 实验三:中断方式,单片机USB中断接收服务函数收到命令后,
                           printf_usb("Hello World !\r\n")或其他
32位8051单片机入门的第一个完整的C语言程序






2025/4/16:
利用 AiCube@AIapp-ISP V6.95M,
智能配置开发工具,实现如下的实验:
AiCube 实验三:中断方式,单片机USB中断接收服务函数收到命令后,
                           printf_usb("Hello World !\r\n")或其他
32位8051单片机入门的第一个完整的C语言程序




keil C51/C251 编译器只支持31以内中断号,超过31编译报错。热心网友提供的简单KEIL中断号拓展工具,可将中断号拓展到254,在KEIL 未打开的状况下,运行【Keil 中断拓展插件】,将中断号拓展到254。


使用 AIapp-ISP V6.95M 或以上版本,在KEIL 未打开的状况下
重新添加一次新的头文件


添加的 新头文件 在这


使用 AIapp-ISP V6.95M 或以上版本中的 ,
AiCube 智能配置工具自动生成强大的初始化程序
对应的在 KEIL C251 中的 项目设置,已是最优,不需要修改【可视图形化I/O口配置工具】本实验暂时不需要配置选择用 出厂预置的 40MHz 高速IRC 时钟 跑用户程序
===如在这选择用户程序区用户程序自己去修改频率
===那ISP烧录时的频率会被改为上面的频率


项目创建成功后,Keil 自动打开该【项目文件】
将下面这段程序
    USB_SendData(UsbOutBuffer, OutNumber); //将接收的数据,直接送回主机,用于演示测试改成:
if(UsbOutBuffer==6)
      printf_usb("HelloWorld!\r\n"); //如接收到的数据包的第0个字节是6,打印“HelloWorld!"
else if(UsbOutBuffer==7)
      printf_usb("China!\r\n");//如接收到的数据包的第0个字节是7,打印“China!"编译产生的 *.HEX文件在下面目录中用 ISP软件 打开该目标文件,
AI8051U实验设备, P3.2按键按下,P3.2为低,
重新上电,点击【下载/编程】按钮, 烧录成功。
单片机/MCU, AI8051U,
自动运行USB中断程序,跟据接收到的命令,执行:printf_usb("Hello World !\r\n")程序。或执行:printf_usb("China !\r\n")程序。

如上,点击【打开串口】
程序运行效果如上
具体程序如下////////////////////////////////////////// 文件名称: main.c// 文件描述: // 文件版本: V1.0// 修改记录://   1. (2025-04-16) 创建文件////////////////////////////////////////
#include "config.h"                     //默认已包含stdio.h、intrins.h、ai_usb.h等头文件
////////////////////////////////////////// 项目主函数// 入口参数: 无// 函数返回: 无////////////////////////////////////////void main(void){    SYS_Init();
    while (1)    {    }}
////////////////////////////////////////// 系统初始化函数// 入口参数: 无// 函数返回: 无////////////////////////////////////////void SYS_Init(void){    EnableAccessXFR();                  //使能访问扩展XFR    AccessCodeFastest();                //设置最快速度访问程序代码    AccessIXramFastest();               //设置最快速度访问内部XDATA    IAP_SetTimeBase();                  //设置IAP等待参数,产生1us时基
    P0M0 = 0x00; P0M1 = 0x00;         //初始化P0口为准双向口模式    P1M0 = 0x00; P1M1 = 0x00;         //初始化P1口为准双向口模式    P2M0 = 0x00; P2M1 = 0x00;         //初始化P2口为准双向口模式    P3M0 = 0x00; P3M1 = 0x00;         //初始化P3口为准双向口模式    P4M0 = 0x00; P4M1 = 0x00;         //初始化P4口为准双向口模式    P5M0 = 0x00; P5M1 = 0x00;         //初始化P5口为准双向口模式    P6M0 = 0x00; P6M1 = 0x00;         //初始化P6口为准双向口模式    P7M0 = 0x00; P7M1 = 0x00;         //初始化P7口为准双向口模式
    CLK_Init();                         //时钟模块初始化    USBLIB_Init();                      //USB库初始化
    EnableGlobalInt();                  //使能全局中断}
////////////////////////////////////////// 毫秒延时函数// 入口参数: ms (设置延时的毫秒值)// 函数返回: 无////////////////////////////////////////void delay_ms(uint16_t ms){    uint16_t i;
    do    {      i = MAIN_Fosc / 6000;      while (--i);    } while (--ms);}

////////////////////////////////////////// 时钟初始化函数// 入口参数: 无// 函数返回: 无////////////////////////////////////////void CLK_Init(void){    CLK_SYSCLK_Divider(10);             //切换主时钟前先将系统时钟降频
    HIRC_40M();                         //选择内部预置的频率
    CLK_MCLK_HIRC();                  //选择内部高精度HIRC作为主时钟    CLK_MCLK2_BYPASS();               //旁路MCLK2,直接使用MCLK选择
    CLK_SYSCLK_Divider(1);            //设置系统时钟分频系数
    CLK_HSIOCK_MCLK();                  //选择MCLK主时钟作为高速外设时钟源    CLK_HSIOCK_Divider(1);            //设置高速外设时钟预分频系数
    CLK_SPICLK_Divider(1);            //设置SPI时钟预分频系数    CLK_I2SCLK_Divider(1);            //设置I2S时钟预分频系数    CLK_PWMACLK_Divider(1);             //设置PWMA时钟预分频系数    CLK_PWMBCLK_Divider(1);             //设置PWMB时钟预分频系数    CLK_TFPUCLK_Divider(1);             //设置TFPU时钟预分频系数}
////////////////////////////////////////// USB库初始化函数// 入口参数: 无// 函数返回: 无////////////////////////////////////////void USBLIB_Init(void){    usb_init();                         //初始化USB模块    USB_SetIntPriority(3);            //设置中断为最高优先级    set_usb_OUT_callback(USBLIB_OUT_Callback); //设置USB中断回调函数    set_usb_ispcmd("@STCISP#");         //设置USB不停电下载命令}
////////////////////////////////////////// 等待USB配置完成函数// 入口参数: 无// 函数返回: 无////////////////////////////////////////void USBLIB_WaitConfiged(void){    while (DeviceState != DEVSTATE_CONFIGURED); //等待USB完成配置}
////////////////////////////////////////// USB设备接收数据中断回调程序// 入口参数: 无// 函数返回: 无// OutNumber:USB设备接收到的数据长度// UsbOutBuffer:保存USB设备接收到的数据////////////////////////////////////////void USBLIB_OUT_Callback(void){    //USB_SendData(UsbOutBuffer, OutNumber);           //将接收的数据,直接送回主机,用于演示测试    //用户请自行将上句,改成用户自己实际需要的用户代码
//下面是用户自己添加的代码取代上面的演示程序
                if(UsbOutBuffer==6)                              printf_usb("HelloWorld!\r\n"); //如接收到的数据包的第0个字节是 6,打印“HelloWorld!"                else if(UsbOutBuffer==7)                              printf_usb("China!\r\n");      //如接收到的数据包的第0个字节是7,打印“China!"}

神农鼎 发表于 2025-4-3 21:41:32





神农鼎 发表于 2025-4-3 21:44:51

Ai8051U-LQFP48,RMB2.3USB 型 32位 8051,1T 8051,支持32位8051指令集和8位8051指令集比普通32位机强太多的地方:1,Ai8051U有TFPU@120MHz, 算力强, uS级硬件三角函数/浮点运算器;2,Ai8051U的抗干扰强;12位ADC全新设计更精准,轨到轨比较器3,Ai8051U内置专业级复位电路,彻底省外部复位;4,Ai8051U的内部高可靠时钟完全满足串口通信要求,4组高速串口;5,Ai8051U有QSPI读Flash,直送i8080/M6800-TFT接口,视频级刷彩屏,C8T6没有;6,Ai8051U的PWM支持硬件移相@120MHz,DMA可以外设直接到外设,P2P7,Ai8051U是 34K SRAM,64K Flash8,Ai8051U是自带硬件USB,1个芯片就能直接USB连接电脑仿真/下载,全球唯一9,有PDIP40,LQFP44,LQFP48封装,管脚兼容经典的89C52RC,12C5A60S210,当32位8051使用,可以用 Keil C251 编译器,双核兼容设计11,当8位8051使用,可以用 Keil C51/IAR/SDCC 编译器Ai8051U-LQFP48,USB 型 32位 8051,RMB2.3含税

神农鼎 发表于 2025-4-3 21:52:21



【新提醒】《8051U深度入门到32位51大型实战视频》,【免费 + 包邮 送】实验箱@Ai8051U,100万套 - 字库生成,图片取模,串口绘图,串口助手,虚拟硬件,外部串行Flash编程 国芯技术交流网站 - AI32位8051交流社区

神农鼎 发表于 2025-4-7 13:23:54

实验一:printf_usb("Hello World !\r\n"),
            第一个完整的C语言程序


#include "ai8051u.h"
#include "ai_usb.h"

void main(void)
{
      EAXFR = 1;      //允许访问扩展的特殊寄存器·XFR
      //P_SW2 |= 0x80;
      //允许访问扩展的特殊寄存器·XFR,8位模式请使用这句,注释上一句
      WTST = 0;      //设置取程序代码等待时间,赋值为0表示不等待,程序以最快速度运行
      CKCON = 0;      //设置访问片内的xdata速度,赋值为0表示用最快速度访问,不增加额外的等待时间
      
      usb_init();    //USB初始化
      EA = 1;      //总中断允许位打开

      while(1)
      {
               printf_usb("Hello World !\r\n");
               //直接打印输出 “Hello World !” 到主机相应软件的USB【CDC/HID-串口助手】
      }
}





神农鼎 发表于 2025-4-7 13:24:19








实验二: 查询方式,查询到电脑命令后,
            printf_usb("Hello World !\r\n")或其他


#include "ai8051u.h"
#include "ai_usb.h"

void main(void)
{
      EAXFR = 1;      //允许访问扩展的特殊寄存器·XFR
      //P_SW2 |= 0x80;
      //允许访问扩展的特殊寄存器·XFR,8位模式请使用这句,注释上一句
      WTST = 0;                //设置取程序代码等待时间,赋值为0表示不等待,程序以最快速度运行      
      CKCON = 0;      //设置访问片内的xdata速度,赋值为0表示用最快速度访问,不增加额外的等待时间
      
      usb_init();    //USB初始化
      EA = 1;      //总中断允许位打开

      while(1)
      {
                //printf_usb("Hello World !\r\n");   //直接打印输出 Hello World !

                if(bUsbOutReady)
                {   //查询方式:USB-Device单片机查询是否有接收完成的USB主机送来的数据包
                      //“bUsbOutReady”: 主机发送给 HID/CDC 设备的数据状态标志。
                      //USB 库中有定义 bUsbOutReady 位变量,
                      //状态位为1表示,主机发送给 HID/CDC 设备数据已完成,
                      //设备已成功接收一包数据,等待对数据继续处理。

                      if (UsbOutBuffer == 6)
                           printf_usb("Hello World !\r\n");   //接收到数据6后,打印“HelloWorld!”
                      else if(UsbOutBuffer == 7)
                              printf_usb("China !\r\n");   //接收到数据7后,打印“China!”
                              
                     usb_OUT_done();   //USB 查询方式,Device单片机通知【主机可以发下一个数据包】
                      //当使用査询方式调用 USB 库函数时,数据处理完成后,
                      //必须调用一次“usb_OUT_done();”这样才能接收下一包数据。
                      //如果是使用中断方式调用 USB 库函数,用户程序不需要调用“usb_OUT_done();”
                      //中断方式,USB库函数内部会自动处理。
               }
      }
}



神农鼎 发表于 2025-4-7 13:24:47










实验三: 中断方式,单片机USB中断接收服务函数收到命令后,
                              printf_usb("Hello World !\r\n")或其他



#include "ai8051u.h"
#include "ai_usb.h"

void USBLIB_OUT_Callback(void)
{
      if (UsbOutBuffer == 6)
      {
                        printf_usb("Hello World !\r\n");
                        //接收到数据6后打印“HelloWorld!”
//                        LED40_ClrBit(0, 0);
//                        LED40_SetPort(0, 0xF0);    //设置P0口输出F0H   
      }
      else if (UsbOutBuffer == 7)
      {
                        printf_usb("China !\r\n");
                        //接收到数据7后打印“China!”
//                        LED40_ClrBit(0, 7);
//                        LED40_SetPort(0, 0x0F);    //设置P0口输出0FH
      }
}
void main(void)
{
      EAXFR = 1;      //允许访问扩展的特殊寄存器·XFR
      //P_SW2 |= 0x80;
      //允许访问扩展的特殊寄存器·XFR,8位模式请使用这句,注释上一句
      WTST = 0;                //设置取程序代码等待时间,赋值为0表示不等待,程序以最快速度运行
      
      CKCON = 0;      //设置访问片内的xdata速度,赋值为0表示用最快速度访问,不增加额外的等待时间
      set_usb_OUT_callback(USBLIB_OUT_Callback); //设置 USB 中断服务程序可以调用的回调函数      


      usb_init();    //USB初始化
      EA = 1;      //总中断允许位打开

      while(1)
      {
//                        printf_usb("Hello World !\r\n");
                        /*      
                        if(bUsbOutReady)      //查询是否有接收到数据
                        {
                              if (UsbOutBuffer == 6)
                                                printf_usb("Hello World !\r\n");
                                                //接收到数据6后打印“HelloWorld!”
                              else if(UsbOutBuffer == 7)
                                                printf_usb("China !\r\n");
                                                //接收到数据7后打印“China!”
                              usb_OUT_done();      //当前包的数据处理完成
                              //查询方式处理USB接收的数据
                              //当前包的数据处理完成

                        }
                        */
      }
}


神农鼎 发表于 2025-4-9 19:35:57

有客服反馈:

第三个实验发送China,出来的是乱码,已跟陈工反馈。
陈工说单片机收到7后就会发送一串数据,这串数据的
第一个字节"H"对应的ASCII码是 48,最后一个字节是 F0。
当第二次输出数据时,串口助手将最后一个字节跟
第二次发送的第一个字节拼接起来解码“F0 48”
是中文“餒”的Unicode码,
于是第二次输出的第一个字符就显示“餒”。
所以要在代码中多添加一行: printf_usb("\r\n");




已验证并成功解决


32G12K128 发表于 2025-4-10 11:27:57

更多设置--- 去掉【智能处理文本接收窗口中被分割的汉字字符】,
也可以解决这个问题:




页: [1] 2 3 4
查看完整版本: 还是从 printf_usb("Hello World !\r\n") 开始,《单片机原理及应用》入门@Ai8051U