注意
新建工程時(shí)待選擇的Device:如 STC32G12K128 Seies,需要先在下拉菜單中選擇“STC MCU Database”,然后可以選擇STC32G12K128 Seies了。
4.實(shí)現(xiàn)自動(dòng)下載工程不斷電下載
基礎(chǔ)代碼
當(dāng)前以上節(jié)課的代碼為基礎(chǔ),經(jīng)過(guò)精簡(jiǎn)后的代碼(裸板未添加任何頭文件):
需手工下載至開(kāi)發(fā)板(屠龍刀三.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為準(zhǔn)雙向口(屠龍刀三板載led)
P2M1 = 0x00;
//
while(1) //死循環(huán)
{
P21 = 0; //設(shè)置低電平 (屠龍刀三板載led)
}
}
當(dāng)前已實(shí)現(xiàn)功能:點(diǎn)亮P2^1端口的板載LED。
將實(shí)現(xiàn)功能(自動(dòng)下載最小工程的實(shí)現(xiàn)及bug排查思路)
依據(jù)stc32g用戶手冊(cè)(資料更新日期:2023/7/31)
5.14 用戶程序復(fù)位到系統(tǒng)區(qū)進(jìn)行USB模式ISP下載的方法(不停電)
當(dāng)項(xiàng)目處于開(kāi)發(fā)階段時(shí),需要反復(fù)的下載用戶代碼到目標(biāo)芯片中進(jìn)行代碼驗(yàn)證,使用USB模式對(duì)STC的單片機(jī)進(jìn)行正常的ISP下載,需要先將P3.2口短路到GND,然后對(duì)目標(biāo)芯片進(jìn)行重新上電,從而會(huì)使得項(xiàng)目在開(kāi)發(fā)階段燒錄步驟比較繁瑣。為此STC單片機(jī)增加了一個(gè)特殊功能寄存器IAP_CONTR當(dāng)用戶向此寄存器寫(xiě)入0x60,即可實(shí)現(xiàn)軟件復(fù)位到系統(tǒng)區(qū),進(jìn)而實(shí)現(xiàn)不停電就可進(jìn)行ISP下載。
注:當(dāng)用戶程序軟復(fù)位到系統(tǒng)區(qū)時(shí),若P3.0/D-和P3.1/D+已經(jīng)和電腦的USB口相連,則系統(tǒng)代碼會(huì)自動(dòng)進(jìn)入U(xiǎn)SB下載模式等待ISP下載,此時(shí)不需要P3.2連接到地。
這里主要介紹:
2、使用STC-ISP下載軟件發(fā)送的用戶下載命令(USB項(xiàng)目)
STC-ISP軟件的設(shè)置見(jiàn)手冊(cè):
需要添加的庫(kù)文件及代碼,根據(jù)手冊(cè):
添加庫(kù)文件:stc_usb_hid_32g.LIB
添加代碼:
char *USER_STCISPCMD = "@STCISP#"; //設(shè)置自動(dòng)復(fù)位到ISP區(qū)的用戶接口命令,添加至main函數(shù)前
usb_init(); //初始化USB代碼,添加至while(主循環(huán))之前
EA = 1;
編譯提示錯(cuò)誤:
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.
應(yīng)該是缺少定義和預(yù)定義,根據(jù)手冊(cè)所述:
詳細(xì)代碼請(qǐng)參考官網(wǎng)上的“STC32G實(shí)驗(yàn)箱演示程序”包中的“76-通過(guò)USB HID協(xié)議打印數(shù)據(jù)信息-可用于調(diào)試”。
打開(kāi)工程:“76-通過(guò)USB HID協(xié)議打印數(shù)據(jù)信息-可用于調(diào)試”為參考。
增加頭文件引用:
#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-通過(guò)USB HID協(xié)議打印數(shù)據(jù)信息-可用于調(diào)試\src文件夾復(fù)制另存在本項(xiàng)目根目錄下,將src加入引用路徑:
編譯后如果出現(xiàn)類似警告提示:
*** 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
則設(shè)置options-Target中的Memory Model:為XSMALL(默認(rèn)為T(mén)iny):
重新編譯,提示:
*** 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-通過(guò)USB HID協(xié)議打印數(shù)據(jù)信息-可用于調(diào)試”,增加定義代碼:
//USB調(diào)試及復(fù)位所需定義
char *USER_DEVICEDESC = NULL;
char *USER_PRODUCTDESC = NULL;
再次編譯,僅出現(xiàn)警告,無(wú)錯(cuò)誤:
*** 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
為軟件系統(tǒng)警報(bào)問(wèn)題,當(dāng)聲明的函數(shù)未被引用時(shí)會(huì)出現(xiàn)此警告,尤其對(duì)于自己寫(xiě)函數(shù)時(shí)經(jīng)常會(huì)發(fā)生此問(wèn)題。
解決方法:
在軟件配置對(duì)話框的"L251 Misc"欄中,有"Misc controls"輸入框,寫(xiě)入REMOVEUNUSED,用于屏蔽未引用警告。
屏蔽后,再次編譯,無(wú)警告。
選擇文件,下載/編程,勾選:每次下載前都先發(fā)送自定義命令和當(dāng)目標(biāo)文件變化時(shí)自動(dòng)裝載并發(fā)送下載命令,手動(dòng)下載,提示不能識(shí)別USB:
自動(dòng)下載功能還有問(wèn)題,沒(méi)有任何用處。
再觀察例程,usb_init()前有一個(gè)sys_init()的函數(shù)聲明,轉(zhuǎn)至定義(先重新編譯再跳轉(zhuǎn)):
有設(shè)置USB使用的時(shí)鐘源和初始化端口的定義,有USB功能相關(guān),復(fù)制加入sample工程中:
重新編譯并手動(dòng)下載至開(kāi)發(fā)板,正常下載,不能識(shí)別USB的提示也沒(méi)有了:
修改源代碼測(cè)試,已經(jīng)能夠?qū)崿F(xiàn)修改后自動(dòng)下載代碼了。
修改keil中的工程代碼,也能自動(dòng)實(shí)現(xiàn)下載。
當(dāng)前的sample帶自動(dòng)下載功能工程中的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調(diào)試及復(fù)位所需定義
char *USER_DEVICEDESC = NULL;
char *USER_PRODUCTDESC = NULL;
char *USER_STCISPCMD = "@STCISP#"; //設(shè)置自動(dòng)復(fù)位到ISP區(qū)的用戶接口命令
void sys_init(); //函數(shù)聲明,否則需要放在main()函數(shù)之前。不聲明會(huì)提示:Demo.c(74): error C53: redefinition of 'sys_init': different return types
void main()
{
P2M0 = 0x00; //配置P2為準(zhǔn)雙向口(屠龍刀三板載led)
P2M1 = 0x00;
sys_init();
usb_init(); //初始化USB代碼
EA = 1;
while(1) //死循環(huán)
{
P22 = 0; //設(shè)置低電平 (屠龍刀三板載led)
P23 = 0; //設(shè)置低電平 (屠龍刀三板載led)
}
}
void sys_init()
{
WTST = 0; //設(shè)置程序指令延時(shí)參數(shù),賦值為0可將CPU執(zhí)行指令的速度設(shè)置為最快
EAXFR = 1; //擴(kuò)展寄存器(XFR)訪問(wèn)使能
// EAXFR:擴(kuò)展RAM區(qū)特殊功能寄存器(XFR)訪問(wèn)控制寄存器
// 0:禁止訪問(wèn)XFR
// 1:使能訪問(wèn)XFR。
// 當(dāng)需要訪問(wèn)XFR時(shí),必須先將EAXFR置1,才能對(duì)XFR進(jìn)行正常的讀寫(xiě)。建議上電初始化時(shí)直接設(shè)置為1,后續(xù)不要再修改
CKCON = 0; //提高訪問(wèn)XRAM速度
P0M1 = 0x30; P0M0 = 0x30; //設(shè)置P0.4、P0.5為漏極開(kāi)路(實(shí)驗(yàn)箱加了上拉電阻到3.3V)
P1M1 = 0x32; P1M0 = 0x32; //設(shè)置P1.1、P1.4、P1.5為漏極開(kāi)路(實(shí)驗(yàn)箱加了上拉電阻到3.3V), P1.1在PWM當(dāng)DAC電路通過(guò)電阻串聯(lián)到P2.3
P2M1 = 0x3c; P2M0 = 0x3c; //設(shè)置P2.2~P2.5為漏極開(kāi)路(實(shí)驗(yàn)箱加了上拉電阻到3.3V),設(shè)置開(kāi)漏模式需要斷開(kāi)PWM當(dāng)DAC電路中的R2電阻
P3M1 = 0x50; P3M0 = 0x50; //設(shè)置P3.4、P3.6為漏極開(kāi)路(實(shí)驗(yàn)箱加了上拉電阻到3.3V)
P4M1 = 0x3c; P4M0 = 0x3c; //設(shè)置P4.2~P4.5為漏極開(kāi)路(實(shí)驗(yàn)箱加了上拉電阻到3.3V)
P5M1 = 0x0c; P5M0 = 0x0c; //設(shè)置P5.2、P5.3為漏極開(kāi)路(實(shí)驗(yàn)箱加了上拉電阻到3.3V)
P6M1 = 0xff; P6M0 = 0xff; //設(shè)置為漏極開(kāi)路(實(shí)驗(yàn)箱加了上拉電阻到3.3V)
P7M1 = 0x00; P7M0 = 0x00; //設(shè)置為準(zhǔn)雙向口
//設(shè)置USB使用的時(shí)鐘源
IRC48MCR = 0x80; //使能內(nèi)部48M高速I(mǎi)RC
while (!(IRC48MCR & 0x01)); //等待時(shí)鐘穩(wěn)定
}
代碼優(yōu)化
先查看引用的頭文件。
查看調(diào)用的頭文件stc.h
#ifndef __STC_H__
#define __STC_H__
#include <intrins.h> //系統(tǒng)頭文件
#include <stdio.h>
#include <string.h>
#include "stc32g.h"
#include "config.h"
typedef bit BOOL; //引用名稱定義
typedef unsigned char BYTE;
#endif
重點(diǎn)看一下:“stc32g.h”:
對(duì)常見(jiàn)端口已經(jīng)進(jìn)行了sfr定義,所以可以將手動(dòng)的sfr、不需要的定義注釋掉。
目前的程序?yàn)椋?/h4>
#include "stc.h" //調(diào)用頭文件
#include "usb.h"
//USB調(diào)試及復(fù)位所需定義
char *USER_DEVICEDESC = NULL;
char *USER_PRODUCTDESC = NULL;
char *USER_STCISPCMD = "@STCISP#"; //設(shè)置自動(dòng)復(fù)位到ISP區(qū)的用戶接口命令
void sys_init(); //函數(shù)聲明,否則需要放在main()函數(shù)之前。不聲明會(huì)提示:Demo.c(74): error C53: redefinition of 'sys_init': different return types
void main()
{
P2M0 = 0x00; //配置P2為準(zhǔn)雙向口(屠龍刀三板載led)
P2M1 = 0x00;
sys_init();
usb_init(); //初始化USB代碼
EA = 1;
while(1) //死循環(huán)
{
P22 = 0; //設(shè)置低電平 (屠龍刀三板載led)
P23 = 0; //設(shè)置低電平 (屠龍刀三板載led)
}
}
void sys_init() //函數(shù)定義
{
WTST = 0; //設(shè)置程序指令延時(shí)參數(shù),賦值為0可將CPU執(zhí)行指令的速度設(shè)置為最快
EAXFR = 1; //擴(kuò)展寄存器(XFR)訪問(wèn)使能
CKCON = 0; //提高訪問(wèn)XRAM速度
//設(shè)置USB使用的時(shí)鐘源
IRC48MCR = 0x80; //使能內(nèi)部48M高速I(mǎi)RC
while (!(IRC48MCR & 0x01)); //等待時(shí)鐘穩(wěn)定
}
#include "stc.h" //調(diào)用頭文件
#include "usb.h"
//USB調(diào)試及復(fù)位所需定義
char *USER_DEVICEDESC = NULL;
char *USER_PRODUCTDESC = NULL;
char *USER_STCISPCMD = "@STCISP#"; //設(shè)置自動(dòng)復(fù)位到ISP區(qū)的用戶接口命令
void sys_init(); //函數(shù)聲明,否則需要放在main()函數(shù)之前。不聲明會(huì)提示:Demo.c(74): error C53: redefinition of 'sys_init': different return types
void main()
{
P2M0 = 0x00; //配置P2為準(zhǔn)雙向口(屠龍刀三板載led)
P2M1 = 0x00;
sys_init();
usb_init(); //初始化USB代碼
EA = 1;
while(1) //死循環(huán)
{
P22 = 0; //設(shè)置低電平 (屠龍刀三板載led)
P23 = 0; //設(shè)置低電平 (屠龍刀三板載led)
}
}
void sys_init() //函數(shù)定義
{
WTST = 0; //設(shè)置程序指令延時(shí)參數(shù),賦值為0可將CPU執(zhí)行指令的速度設(shè)置為最快
EAXFR = 1; //擴(kuò)展寄存器(XFR)訪問(wèn)使能
CKCON = 0; //提高訪問(wèn)XRAM速度
//設(shè)置USB使用的時(shí)鐘源
IRC48MCR = 0x80; //使能內(nèi)部48M高速I(mǎi)RC
while (!(IRC48MCR & 0x01)); //等待時(shí)鐘穩(wěn)定
}
編譯后能夠自動(dòng)下載和運(yùn)行(點(diǎn)亮3個(gè)led)。
利用CDC.lib實(shí)現(xiàn)自動(dòng)下載
USB-CDC/串口模式和USB(HD)模式并列,應(yīng)該能實(shí)現(xiàn)同樣功能。
復(fù)制例程中的COMM至本工程src文件夾下,刪除“stc_usb_hid_32g.LIB”,引用“stc_usb_cdc_32g.LIB”:
編譯后下載,提示:
設(shè)備打開(kāi)失敗!
請(qǐng)檢查設(shè)備是香與電腦正確連接.
查看例程(70-CDC(Communication Device Class)協(xié)議范例):
增加代碼:文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-635645.html
//USB調(diào)試及復(fù)位所需定義
char *USER_DEVICEDESC = NULL;
char *USER_PRODUCTDESC = NULL;
P3M0 &= ~0x03;
P3M1 |= 0x03;
//設(shè)置USB使用的時(shí)鐘源
IRC48MCR = 0x80; //使能內(nèi)部48M高速I(mǎi)RC
while (!(IRC48MCR & 0x01)); //等待時(shí)鐘穩(wěn)定
USBCLK = 0x00; //CDC增加,HID需禁用
USBCON = 0x90; //CDC增加,HID需禁用
手動(dòng)下載入開(kāi)發(fā)板。
出現(xiàn)了掃描串口STC-USB Cnc (coM14),實(shí)現(xiàn)自動(dòng)不斷電下載(CDC協(xié)議)。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-635645.html
完整代碼:
#include "stc.h" //調(diào)用頭文件
#include "usb.h"
//USB調(diào)試及復(fù)位所需定義
char *USER_DEVICEDESC = NULL;
char *USER_PRODUCTDESC = NULL;
char *USER_STCISPCMD = "@STCISP#"; //設(shè)置自動(dòng)復(fù)位到ISP區(qū)的用戶接口命令
void sys_init(); //函數(shù)聲明,否則需要放在main()函數(shù)之前。不聲明會(huì)提示:Demo.c(74): error C53: redefinition of 'sys_init': different return types
void main() //程序開(kāi)始運(yùn)行
{
P2M0 = 0x00; //配置P2為準(zhǔn)雙向口(屠龍刀三板載led)
P2M1 = 0x00;
sys_init();
usb_init(); //初始化USB代碼
EA = 1;
while(1) //死循環(huán)
{
P22 = 0; //設(shè)置低電平 (屠龍刀三板載led)
//P23 = 0; //設(shè)置低電平 (屠龍刀三板載led)
//P24 = 0; //設(shè)置低電平 (屠龍刀三板載led)
}
}
void sys_init() //函數(shù)定義
{
WTST = 0; //設(shè)置程序指令延時(shí)參數(shù),賦值為0可將CPU執(zhí)行指令的速度設(shè)置為最快
EAXFR = 1; //擴(kuò)展寄存器(XFR)訪問(wèn)使能
CKCON = 0; //提高訪問(wèn)XRAM速度
P3M0 &= ~0x03;
P3M1 |= 0x03;
//設(shè)置USB使用的時(shí)鐘源
IRC48MCR = 0x80; //使能內(nèi)部48M高速I(mǎi)RC
while (!(IRC48MCR & 0x01)); //等待時(shí)鐘穩(wěn)定
USBCLK = 0x00; //CDC增加,HID需禁用
USBCON = 0x90; //CDC增加,HID需禁用
}
到了這里,關(guān)于學(xué)習(xí)筆記|LED點(diǎn)亮原理|STC32G單片機(jī)視頻開(kāi)發(fā)教程(沖哥)|第四集-下:點(diǎn)亮LED的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!