学习笔记|LED点亮原理|自动下载最小工程的实现及bug排查思路|USB-HID|USB-CDC实现|STC32G单片机视频开发教程(冲哥)|第四集-下:点亮LED

注意

新建工程时待选择的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):
在这里插入图片描述

扫描二维码关注公众号,回复: 16574339 查看本文章

重新编译,提示:

*** 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

在这里插入图片描述

#ifndef __STC_H__
#define __STC_H__

#include <intrins.h>  //系统头文件
#include <stdio.h>
#include <string.h>

#include "stc32g.h"
#include "config.h"

typedef bit BOOL;   //引用名称定义
typedef unsigned char BYTE;

#endif

重点看一下:“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需禁用

手动下载入开发板。
出现了扫描串口STC-USB Cnc (coM14),实现自动不断电下载(CDC协议)。
在这里插入图片描述

完整代码:

#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)
		 //P24 = 0; //设置低电平	(屠龙刀三板载led)
    }
}

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

	P3M0 &= ~0x03;
    P3M1 |= 0x03;

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

	USBCLK = 0x00;  //CDC增加,HID需禁用
    USBCON = 0x90;  //CDC增加,HID需禁用
}

猜你喜欢

转载自blog.csdn.net/Medlar_CN/article/details/132191950