本帖最后由 打酱油的工程师 于 2023-8-10 14:05 编辑  
 
注意 
新建工程时待选择的Device:如 STC32G12K128 Seies,需要先在下拉菜单中选择“STC MCU Database”,然后可以选择STC32G12K128 Seies了。  
 
 
 
 
 
 
 4.实现自动下载工程不断电下载 
基础代码 
当前以上节课的代码为基础,经过精简后的代码(裸板未添加任何头文件): 需手工下载至开发板(屠龙刀三.1版)。 
			
			
			- sfr P2    = 0xA0;        //P2端口操作完成(屠龙刀三板载led)
 - sfr P2M1  = 0x95;
 - sfr P2M0  = 0x96;
 - 
 - sbit P21 = P2^1;    //定义P2.1引脚(LED控制)(屠龙刀三板载led)
 - 
 - void main()
 - {
 -         P2M0 = 0x00; //配置P2为准双向口(屠龙刀三板载led)
 -         P2M1 = 0x00;
 - //
 -     while(1) //死循环
 -     {
 -                  P21 = 0; //设置低电平        (屠龙刀三板载led)
 -     }
 - }
 
  复制代码
  
当前已实现功能:点亮P2^1端口的板载LED。 
 
将实现功能(自动下载最小工程的实现及bug排查思路) 
依据stc32g用户手册(资料更新日期:2023/7/31)  
 
 
 
 
 
 5.14 用户程序复位到系统区进行USB模式ISP下载的方法(不停电) 当项目处于开发阶段时,需要反复的下载用户代码到目标芯片中进行代码验证,使用USB模式对STC的单片机进行正常的ISP下载,需要先将P3.2口短路到GND,然后对目标芯片进行重新上电,从而会使得项目在开发阶段烧录步骤比较繁琐。为此STC单片机增加了一个特殊功能寄存器IAP_CONTR当用户向此寄存器写入0x60,即可实现软件复位到系统区,进而实现不停电就可进行ISP下载。 注:当用户程序软复位到系统区时,若P3.0/D-和P3.1/D+已经和电脑的USB口相连,则系统代码会自动进入USB下载模式等待ISP下载,此时不需要P3.2连接到地。 这里主要介绍: 2、使用STC-ISP下载软件发送的用户下载命令(USB项目) STC-ISP软件的设置见手册:  
 
 
 
 
 
 需要添加的库文件及代码,根据手册:  
 
 
 
 
 
添加库文件:stc_usb_hid_32g.LIB 
 
 
 
 
 
 
 添加代码: 
 
- char *USER_STCISPCMD = "@STCISP#";                      //设置自动复位到ISP区的用户接口命令,添加至main函数前
 - 
 -         usb_init();        //初始化USB代码,添加至while(主循环)之前
 -         EA = 1;
 
  复制代码
  
编译提示错误:     compiling main.c...     main.c(14): warning C140: 'usb_init' undefined; assuming 'extern int usb_init()'     main.c(15): error C67: 'EA': undefined identifier     Target not created. 应该是缺少定义和预定义,根据手册所述:     详细代码请参考官网上的“STC32G实验箱演示程序”包中的“76-通过USB HID协议打印数据信息-可用于调试”。 打开工程:“76-通过USB HID协议打印数据信息-可用于调试”为参考。  
 
 
 
 
 增加头文件引用: 
#include "stc.h"#include "usb.h" 
编译提示: 
 
 
 
 
 
 
      main.c(1): error C318: can't open file 'stc.h'     main.c(2): error C318: can't open file 'usb.h' 将.\76-通过USB HID协议打印数据信息-可用于调试\src文件夹复制另存在本项目根目录下,将src加入引用路径:  
 
 
 
 
 编译后如果出现类似警告提示: 
 
 
 
 
 
 
 
*** WARNING L14: INCOMPATIBLE MEMORY MODEL    MODULE:  ..\STC32G12K128-LQFP64-DIP64-DEMO-CODE-20230421\COMM\stc_usb_hid_32g.LIB (usb)    MODEL:   XSMALL*** WARNING L14: INCOMPATIBLE MEMORY MODEL    MODULE:  ..\STC32G12K128-LQFP64-DIP64-DEMO-CODE-20230421\COMM\stc_usb_hid_32g.LIB (usb_req_class)    MODEL:   XSMALL 
则设置options-Target中的Memory Model:为XSMALL(默认为Tiny):  
 
 
 
 
 
重新编译,提示: 
*** ERROR L128: REFERENCE MADE TO UNRESOLVED EXTERNAL    SYMBOL:  USER_DEVICEDESC    MODULE:  ..\STC32G12K128-LQFP64-DIP64-DEMO-CODE-20230421\COMM\stc_usb_hid_32g.LIB (usb_req_std)    ADDRESS: FF0941H*** ERROR L128: REFERENCE MADE TO UNRESOLVED EXTERNAL    SYMBOL:  USER_PRODUCTDESC    MODULE:  ..\STC32G12K128-LQFP64-DIP64-DEMO-CODE-20230421\COMM\stc_usb_hid_32g.LIB (usb_req_std)    ADDRESS: FF09A3H 
提示存在:外部未解决的参考,观察“76-通过USB HID协议打印数据信息-可用于调试”,增加定义代码: 
- //USB调试及复位所需定义
 - char *USER_DEVICEDESC = NULL;
 - char *USER_PRODUCTDESC = NULL;
 
  复制代码
  
再次编译,仅出现警告,无错误: 
*** WARNING L57: UNCALLED FUNCTION, IGNORED FOR OVERLAY PROCESS    NAME:    usb_OUT_done/usb*** WARNING L57: UNCALLED FUNCTION, IGNORED FOR OVERLAY PROCESS    NAME:    USB_SendData/usb*** WARNING L57: UNCALLED FUNCTION, IGNORED FOR OVERLAY PROCESS    NAME:    LCD12864_DisplayClear/util 
Tips: 屏蔽警告:WARNING L57: UNCALLED FUNCTION,IGNORED FOR OVERLAY PROCESS 
为软件系统警报问题,当声明的函数未被引用时会出现此警告,尤其对于自己写函数时经常会发生此问题。 解决方法:   在软件配置对话框的"L251 Misc"栏中,有"Misc controls"输入框,写入REMOVEUNUSED,用于屏蔽未引用警告。    
 
 
 
 
 
屏蔽后,再次编译,无警告。 
 
 
 
 
 
选择文件,下载/编程,勾选:每次下载前都先发送自定义命令和当目标文件变化时自动装载并发送下载命令,手动下载,提示不能识别USB:  
 
 
 
 
 
 
 自动下载功能还有问题,没有任何用处。 再观察例程,usb_init()前有一个sys_init()的函数声明,转至定义(先重新编译再跳转):  
 
 
 
 
 
 
  有设置USB使用的时钟源和初始化端口的定义,有USB功能相关,复制加入sample工程中:  
 
 
 
 
 重新编译并手动下载至开发板,正常下载,不能识别USB的提示也没有了: 修改源代码测试,已经能够实现修改后自动下载代码了。 修改keil中的工程代码,也能自动实现下载。 当前的sample带自动下载功能工程中的main.c为: 
- #include "stc.h"
 - #include "usb.h"
 - 
 - sfr P2    = 0xA0;        //P2端口操作完成(屠龙刀三板载led)
 - sfr P2M1  = 0x95;
 - sfr P2M0  = 0x96;
 - 
 - sbit P21 = P2^1;    //定义P2.1引脚(LED控制)(屠龙刀三板载led)
 - 
 - //USB调试及复位所需定义
 - char *USER_DEVICEDESC = NULL;
 - char *USER_PRODUCTDESC = NULL;
 - char *USER_STCISPCMD = "@STCISP#";                      //设置自动复位到ISP区的用户接口命令
 - 
 - void sys_init();    //函数声明,否则需要放在main()函数之前。不声明会提示:Demo.c(74): error C53: redefinition of 'sys_init': different return types
 - 
 - void main()
 - {
 -         P2M0 = 0x00; //配置P2为准双向口(屠龙刀三板载led)
 -         P2M1 = 0x00;
 - 
 -         sys_init();
 -         usb_init();        //初始化USB代码
 -         EA = 1;
 - 
 -     while(1) //死循环
 -     {
 -                  P22 = 0; //设置低电平        (屠龙刀三板载led)
 -                  P23 = 0; //设置低电平        (屠龙刀三板载led)
 -     }
 - }
 - 
 - void sys_init()
 - {
 -     WTST = 0;  //设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
 -     EAXFR = 1; //扩展寄存器(XFR)访问使能
 -             // EAXFR:扩展RAM区特殊功能寄存器(XFR)访问控制寄存器
 -             // 0:禁止访问XFR
 -             // 1:使能访问XFR。
 -             // 当需要访问XFR时,必须先将EAXFR置1,才能对XFR进行正常的读写。建议上电初始化时直接设置为1,后续不要再修改
 -     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));  //等待时钟稳定
 - }
 
  复制代码
  
代码优化 
先查看引用的头文件。 
 
查看调用的头文件stc.h 
 
 
 
 
 
 - <div style="text-align: left;">#ifndef __STC_H__</div><div style="text-align: left;">#define __STC_H__</div><div style="text-align: left;">
 - </div><div style="text-align: left;">#include <intrins.h>  //系统头文件</div><div style="text-align: left;">#include <stdio.h></div><div style="text-align: left;">#include <string.h></div><div style="text-align: left;">
 - </div><div style="text-align: left;">#include "stc32g.h"</div><div style="text-align: left;">#include "config.h"</div><div style="text-align: left;">
 - </div><div style="text-align: left;">typedef bit BOOL;   //引用名称定义</div><div style="text-align: left;">typedef unsigned char BYTE;</div><div style="text-align: left;">
 - </div><div style="text-align: left;">#endif</div>
 
  复制代码 
 重点看一下:"stc32g.h": 
 
 
  对常见端口已经进行了sfr定义,所以可以将手动的sfr、不需要的定义注释掉。 
 
目前的程序为: 
 
#include "stc.h"  //调用头文件 
#include "usb.h" 
 
//USB调试及复位所需定义 
char *USER_DEVICEDESC = NULL; 
char *USER_PRODUCTDESC = NULL; 
char *USER_STCISPCMD = "@STCISP#";                      //设置自动复位到ISP区的用户接口命令 
 
void sys_init();    //函数声明,否则需要放在main()函数之前。不声明会提示:Demo.c(74): error C53: redefinition of 'sys_init': different return types 
 
void main() 
{ 
        P2M0 = 0x00; //配置P2为准双向口(屠龙刀三板载led) 
        P2M1 = 0x00; 
 
        sys_init(); 
        usb_init();        //初始化USB代码 
        EA = 1; 
 
    while(1) //死循环 
    { 
                 P22 = 0; //设置低电平        (屠龙刀三板载led) 
                 P23 = 0; //设置低电平        (屠龙刀三板载led) 
    } 
} 
 
void sys_init()   //函数定义 
{ 
    WTST = 0;  //设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快 
    EAXFR = 1; //扩展寄存器(XFR)访问使能 
    CKCON = 0; //提高访问XRAM速度 
 
    //设置USB使用的时钟源 
    IRC48MCR = 0x80;    //使能内部48M高速IRC 
    while (!(IRC48MCR & 0x01));  //等待时钟稳定 
} 
编译后能够自动下载和运行(点亮3个led)。 
 
利用CDC.lib实现自动下载 
USB-CDC/串口模式和USB(HD)模式并列,应该能实现同样功能。 
复制例程中的COMM至本工程src文件夹下,删除“stc_usb_hid_32g.LIB”,引用“stc_usb_cdc_32g.LIB”: 
 
 
 
 编译后下载,提示:     设备打开失败!     请检查设备是香与电脑正确连接. 
 
查看例程(70-CDC(Communication Device Class)协议范例): 
 
 
 
 
 
 
 增加代码: 
- //USB调试及复位所需定义
 - char *USER_DEVICEDESC = NULL;
 - char *USER_PRODUCTDESC = NULL;
 - 
 - P3M0 &= ~0x03;
 -    P3M1 |= 0x03;
 - 
 -    //设置USB使用的时钟源
 -    IRC48MCR = 0x80;    //使能内部48M高速IRC
 -    while (!(IRC48MCR & 0x01));  //等待时钟稳定
 - 
 - USBCLK = 0x00;  //CDC增加,HID需禁用
 -    USBCON = 0x90;  //CDC增加,HID需禁用
 
  复制代码
  
 
 
 |