保姆级CH552入门教程

本文详细介绍了如何安装和配置KeilC51与WCHISPStudio,包括添加WCH器件库到Keil的步骤,以及在Keil中创建工程、编写代码和编译的过程。此外,还涵盖了CH552与CH554芯片的头文件使用,以及如何进行程序下载和验证串口输出。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

    一、安装 Keil C51

    此步直接参考网上资料,我这里安装的是 Keil3。

二、安装 WCHISPStudio

    去沁恒官网(https://www.wch.cn/downloads/WCHISPTool_Setup_exe.html)下载安装包,按照提示默认安装即可。

三、安装WCH器件库到 Keil

    打开 WCHISPStudio软件,点击菜单栏:“功能” -> “添加 WCH MCU 到 KEIL 器件库” 。

    

    我按此操作是失败的,提示:

    

    点确定后,弹出目录选择对话框。我的 Keil 安装在以下位置:

    
    所以选择 “C:\Program Files (x86)\Keil” 目录,但是又提示:

         

    估计是沁恒默认支持的是 Keil4,而我安装的是 Keil3,没办法只能手动添加了。首先需要获得器件库文件,这得去沁恒的技术论坛搜索资源。下面是我找到的链接:

    解决方案:https://www.wch.cn/bbs/thread-94733-1.html
    文件资源:https://www.wch.cn/uploads/file/20220921/1663759687119278.zip

    将下载到的器件库(wch.cdb)放到 Keil 安装目录的 “UV3” 文件夹下,然后编辑安装目录下的 “TOOLS.INI”,在 “[UV2]” 下面添加一行:CDB0=UV3\WCH.CDB ("WCH MCU Database")

    
    
   至此器件库安装完成。

四、建工程、写代码、编译

    1、建工程

    

    2、写代码

    官方只提供了 CH552 的头文件资料包 CH552EVT.ZIP(https://www.wch.cn/downloads/CH552EVT_ZIP.html)

    代码参考需要使用 CH554 的资料包 CH554EVT.ZIP(https://www.wch.cn/downloads/CH554EVT_ZIP.html),毕竟 CH552 只是比 CH554 少了 USB HOST 支持。

    将 CH552EVT.ZIP 里的 “CH552.H” 复制到项目目录下。

    再将 CH554EVT.ZIP 里 EXAM/Public 目录下的 “Debug.C”、“Debug.H” 复制到项目目录下。

    另外再新建一个 “Main.C” 的空文件。  


    然后将*.C文件添加到 Keil 项目(注意,一定不要落掉 “Debug.C”,我开始就是没添加Debug.C,编写下载都成功了,就是运行无效果。)

      

    修正Debug.C文件中的头文件引用:
    

    编辑Main.C文件,添加如下代码:(main函数里调用的前三个函数是在Debug.C中实现的。printf内容会输出到串口,是Keil对printf底层调用函数putchar进行了重写,重写位置在C:\Program Files (x86)\Keil\C51\LIB\PUTCHAR.C)

   #include "CH552.H"                                                  
   #include "Debug.H"
   #include "stdio.h"
   #include <string.h>

   #pragma  NOAREGS

   void main( )
   {
       CfgFsys();                      //时钟选择配置  
       mDelaymS(20);
       mInitSTDIO();                   //串口0初始化
       printf("start ...\n");

       while(1){

       }
   }

    3、编译

    编译前先设置:

        

    代码保存后编译:

    

    如果要编译CH554EVT.ZIP中的其他示例,比如

    

    只需将CompositeKM.C内容复制到Main.C中,修正头文件引用路径,然后编译即可。

    Keil C51编译器会将所有添加到项目的C文件编译(未添加的,即使在项目文件夹下也不编译),头文件无需添加到项目。

    Keil C51对文件名如何取并无要求,方便识别管理即可,但要求添加到项目的C文件中,有且仅有一个main函数。

五、连接下载

    打开下载软件,按如下设置:

    

    断电状态下按住开发板的下载键,然后连接USB上电,连接成功后就会自动下载了。(下载过程中可以松开下载键)

六、验证

    前面的代码效果是:开发板上电后,会在串口0输出 “start ...” 字符串,下面验证效果。

    我这里用到一个USB转串口模块,方便将串口的输出显示到电脑串口调试软件上。

    先将USB转串口模块连接到电脑,打开串口调试软件,并打开USB转串口模块对应的串口端口,波特率使用57600。(如果USB转串口模块是第一次使用记得先装驱动)

    CH552开发板 与 USB转串口模块 按下图所示连接。

    然后连接开发板的USB接口,给开发板供电,观看串口调试软件有无收到信息。


【2025/05/03 补充说明】

最近玩 STC8G1K08A 这颗单片机,也是51内核、用 Keil 开发,入门过程与本文类似,顺带也复盘了下本文,发现有以下几个点需要补充下:

1)器件库装不上,事实上不一定非要去沁恒论坛下,完全可以手动添加。

首先我们来查看一下 Keil 自带的设备数据库(这里说的设备数据库,跟前面说的器件库,以及后面可能会提到的CPU数据库,都是同一个/同一类东西)。

可以看到右上角有一个 “添加” 按钮。没错!就是可以通过它来添加我们需要的 CH552 芯片。

信息怎么填?对比自动安装成功的器件库信息,照着填即可,这里直接给出:

CPU=IRAM(0-0xFF) XRAM(0-0x3FF)  IROM(0-0x3FFF) CLOCK(24000000)
MON=S8051.DLL TP51.DLL("-p51")
SIM=S8051.DLL DP51.DLL("-pDR8051")
SFILE="LIB\STARTUP.A51" ("Standard 8051 Startup Code")
REGFILE=CH552.H("WCH")


下次建工程时,就可以选择 “Generic CPU Data Base” > “WCH” > “Ch552” 了。

注意,芯片数据只能添加/更改,不能删除。为防止搞乱默认数据库,手动添加时最好备份下默认数据库。默认位置在:C:\Keil\UV3\UV3.cdb,其中的数字3将根据你安装的版本不同而不同。

查看数据库时,双击芯片名称,进入芯片参数设置模式,只能 “更新”,不能 “添加”,单击厂商名称即可退出设置模式,此时可 “添加” 芯片。

2)头文件管理

细心的读者可能会发现,前面添加芯片信息时,最后一行有 “CH552.H” 字样,是的!Keil有专门管理芯片头文件的地方,而不用每次都把头文件放到工程当中。

我们只需把 CH552.H 文件放到 C:\Keil\C51\INC\WCH 下

WCH文件夹名称对应: REGFILE=CH552.H("WCH")  中括号内的名称。

放好后,工程中即可通过 “#include <CH552.H> ”  将头文件包含到工程中。

3)评论区有网友提到以前的方法在编译时有警告,经验证,确实是因为 Debug.c 中有定义了而未调用的代码,可以只拷出用到的代码到 main.c,而不再包含 Debug.c、Debug.h 文件。

#include <CH552.H>
#include "stdio.h"
#define  FREQ_SYS      12000000          //系统主频12MHz
#ifndef  UART0_BUAD
#define  UART0_BUAD    57600
#define  UART1_BUAD    57600
#endif
/*******************************************************************************
* Function Name  : CfgFsys( )
* Description    : CH554时钟选择和配置函数,默认使用Fsys 6MHz,FREQ_SYS可以通过
                   CLOCK_CFG配置得到,公式如下:
                   Fsys = (Fosc * 4/(CLOCK_CFG & MASK_SYS_CK_SEL);具体时钟需要自己配置
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void    CfgFsys( )
{
//      SAFE_MOD = 0x55;
//      SAFE_MOD = 0xAA;
//     CLOCK_CFG |= bOSC_EN_XT;                          //使能外部晶振
//     CLOCK_CFG &= ~bOSC_EN_INT;                        //关闭内部晶振
        SAFE_MOD = 0x55;
        SAFE_MOD = 0xAA;
//      CLOCK_CFG = CLOCK_CFG & ~ MASK_SYS_CK_SEL | 0x07;  // 32MHz
//      CLOCK_CFG = CLOCK_CFG & ~ MASK_SYS_CK_SEL | 0x06;  // 24MHz
//      CLOCK_CFG = CLOCK_CFG & ~ MASK_SYS_CK_SEL | 0x05;  // 16MHz
        CLOCK_CFG = CLOCK_CFG & ~ MASK_SYS_CK_SEL | 0x04;  // 12MHz
//      CLOCK_CFG = CLOCK_CFG & ~ MASK_SYS_CK_SEL | 0x03;  // 6MHz
//      CLOCK_CFG = CLOCK_CFG & ~ MASK_SYS_CK_SEL | 0x02;  // 3MHz
//      CLOCK_CFG = CLOCK_CFG & ~ MASK_SYS_CK_SEL | 0x01;  // 750KHz
//      CLOCK_CFG = CLOCK_CFG & ~ MASK_SYS_CK_SEL | 0x00;  // 187.5MHz
        SAFE_MOD = 0x00;
}
/*******************************************************************************
* Function Name  : mDelayus(UNIT16 n)
* Description    : us延时函数
* Input          : UNIT16 n
* Output         : None
* Return         : None
*******************************************************************************/
void    mDelayuS( UINT16 n )  // 以uS为单位延时
{
#ifdef  FREQ_SYS
#if     FREQ_SYS <= 6000000
        n >>= 2;
#endif
#if     FREQ_SYS <= 3000000
        n >>= 2;
#endif
#if     FREQ_SYS <= 750000
        n >>= 4;
#endif
#endif
    while ( n ) {  // total = 12~13 Fsys cycles, 1uS @Fsys=12MHz
        ++ SAFE_MOD;  // 2 Fsys cycles, for higher Fsys, add operation here
#ifdef  FREQ_SYS
#if     FREQ_SYS >= 14000000
        ++ SAFE_MOD;
#endif
#if     FREQ_SYS >= 16000000
        ++ SAFE_MOD;
#endif
#if     FREQ_SYS >= 18000000
        ++ SAFE_MOD;
#endif
#if     FREQ_SYS >= 20000000
        ++ SAFE_MOD;
#endif
#if     FREQ_SYS >= 22000000
        ++ SAFE_MOD;
#endif
#if     FREQ_SYS >= 24000000
        ++ SAFE_MOD;
#endif
#if     FREQ_SYS >= 26000000
        ++ SAFE_MOD;
#endif
#if     FREQ_SYS >= 28000000
        ++ SAFE_MOD;
#endif
#if     FREQ_SYS >= 30000000
        ++ SAFE_MOD;
#endif
#if     FREQ_SYS >= 32000000
        ++ SAFE_MOD;
#endif
#endif
        -- n;
    }
}
/*******************************************************************************
* Function Name  : mDelayms(UNIT16 n)
* Description    : ms延时函数
* Input          : UNIT16 n
* Output         : None
* Return         : None
*******************************************************************************/
void    mDelaymS( UINT16 n )                                                  // 以mS为单位延时
{
    while ( n ) {
#ifdef  DELAY_MS_HW
        while ( ( TKEY_CTRL & bTKC_IF ) == 0 );
        while ( TKEY_CTRL & bTKC_IF );
#else
        mDelayuS( 1000 );
#endif
        -- n;
    }
}
/*******************************************************************************
* Function Name  : mInitSTDIO()
* Description    : CH554串口0初始化,默认使用T1作UART0的波特率发生器,也可以使用T2
                   作为波特率发生器
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void    mInitSTDIO( )
{
    UINT32 x;
    UINT8 x2;
    SM0 = 0;
    SM1 = 1;
    SM2 = 0;                                                                   //串口0使用模式1
                                                                               //使用Timer1作为波特率发生器
    RCLK = 0;                                                                  //UART0接收时钟
    TCLK = 0;                                                                  //UART0发送时钟
    PCON |= SMOD;
    x = 10 * FREQ_SYS / UART0_BUAD / 16;                                       //如果更改主频,注意x的值不要溢出
    x2 = x % 10;
    x /= 10;
    if ( x2 >= 5 ) x ++;                                                       //四舍五入
    TMOD = TMOD & ~ bT1_GATE & ~ bT1_CT & ~ MASK_T1_MOD | bT1_M1;              //0X20,Timer1作为8位自动重载定时器
    T2MOD = T2MOD | bTMR_CLK | bT1_CLK;                                        //Timer1时钟选择
    TH1 = 0-x;                                                                 //12MHz晶振,buad/12为实际需设置波特率
    TR1 = 1;                                                                   //启动定时器1
    TI = 1;
    REN = 1;                                                                   //串口0接收使能
}
void main( )
{
   CfgFsys();                      //时钟选择配置
   mDelaymS(20);
   mInitSTDIO();                   //串口0初始化
   printf("test start ...\n");
   while(1){
   }
}

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值