找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 9718|回复: 6
收起左侧

合泰单片机Holtek C Compiler V3编译器使用手册与FAQ资料下载

[复制链接]
ID:223582 发表于 2018-10-13 22:41 | 显示全部楼层 |阅读模式
合泰单片机编译器和Touch MCU Workshop v3.0使用手冊资料分享给大家学习

本手册主要讲述了 C语言的基础语言,再以此为基础,进而讲述 C compiler V3的语法结构和其优化功能,帮助程序员快速使用 C compiler V3 开发应用程序。C compiler V3 是由 GCC 4.6.2 以上版本移植过来的,除后端输出,其余部份都可参考GCC 与机器无关的相关使用手册。
这里假定读者已具备如下基本素质:
  ● 知道如何编写 C 程序
  ● 已经阅读并理解所使用单片机的数据手册
0.png 0.png
第一章 C 语言基础知识
本章将由浅到深的概括 C 语言的基础语法及结构特点,方便后面学习 C compiler V3,由于受限于单片机的硬件结构,因此本章的描述基于标准 C 语言( 这里指 C99 标准 ),兼容 C compiler V3 之语法。
主要包含如下内容:
  ● 数据类型、运算符与表达式
  ● 函数
  ● 数组与指针
  ● 结构体、联合体与枚举
  ● 预处理
  ● 流程控制
  ● 作用域
1.1 数据类型、运算符与表达式
1.1.1 C的数据类型
数据类型确定了变量在内存中占用的存储单元,所以在声明变量时首先必须要确定变量的类型,数据类型可以分为基本数据类型、构造数据类型、指针类型(Pointer) 和空类型 (void),基本数据类型有整型、字符型、浮点型,构造类型则有数组、结构体、共享体和枚举,利用这些构造类型可以构造出所需要的数据结构。
列举基本数据类型 (C compiler V3) 如表 1-1-1:
0.png
0.png
1.1.2.2 变量及其定义
变量是在程序运行时,其值可以变化的,每个变量都应该有一个名字,以便被引用,并区分大小写,C 语言规定,所有的变量都必须先宣告,后使用,变量在定义时必指定数据类型,这样编译时才可为其分配对应的存储单元。如int a;。标识符是用来标识变量、常量、函数、类型等的字符系列,C 语言规定标识符只能由字母、数字、下划线构成,且必须以字母和下划线作为起始符。
1.1.2.3 变量的存储方式
在 C 语言中每个变量和函数都有两个属性:数据类型和数据的存储方式,存储方式可分为 2 种,静态存储和动态存储,具体又包含 4 种,自动的 (auto)、静态的(static)、寄存器的(register)、外部的(extern)。
1、auto:函数中的局部变量,如果不专门声明为 static 的存储方式,则默认为auto,所以在函数内 auto char a与 char a是等价的。
2、static:可分为全局静态存储和局部静态存储,全局变量加了 static 后,变量只能在本文件中引用,局部静态存储则是局部变量的值在函数调用结束后不消失而保留原值,在下一次调用该函数时,该变量已经有值了。
3、register:上述两种变量是存放在内存中的,而 register 则是把变量存放在寄存器中,基于单片机的特殊情况,这里不展开叙述。
4、extern:使用另一个档中定义的变量,表示该变量是一个已经在外部定义过的变量,只要加上extern 就可以使用该变量了,后面有专门的讲述。

5、volatile:一个类型修饰符 (type specifier)。它是被设计用来修饰被不同程序
访问和修改的变量,使用 volatile 修饰的变量,不会因编译程序的优化而被省去。
建议定义成 volatile 的变量:特殊寄存器,中断函数使用到的变量,为某些特殊用途的代码定义的变量 ( 比如 delay 功能 )。
其它一般变量不建议定义成volatile,这样会大大降低编译程序的优化功能。

1.1.3 C语言运算简介
C 语言的运算十分丰富,主要包括算术运算,逻辑运算、位运算、赋值运算、条件运算、逗号运算等,各种运算及其之间的优先级见附录 B。
1.1.3.1 类型转换
类型转换规则:
  ● 混合类型的算术运算
  ♦ 小于int类型的转换为 int 类型
  ♦ 小类型向大类型转换(转换过程见图 2_1_1)
  ● 不同类型之间的赋值
  ♦ 以赋值语句左边的类型为转换后类型
  ● 函数参数 / 返回值的传递
  ♦ 以参数/ 返回值的类型为转换后类型
0.png

FAQ目录:
目录

Part I V3 基本介绍  5
11 V3 的版本历程 ? 5
12 新版改进的功能  5
13 V3 的使用手册有哪些 ? 6
14 V3 不支持的 MCU 有哪些 ?  6
15 什么是长指令架构 MCU?  7
Part II V3 与 V2 的不同  8
21 V3 与 V2 语法有何不同 ? 与 V1, V2,标准 C 的比较 ? 8
22 V3 对 V2 改进的功能  8
23 将 V2 程序改至 V3 常见的错误  8
231 ISR warning  8
232 内嵌汇编 error  9
233 bit 变数 error  9
234 标志位 error  9
235 内部函数 error  9
236 绝对地址变数 error  10
237 函式指标 error  10
Part III V3 的特殊语法及用法  11
31 如何将一个变量定义于指定 bank? 11
32 如何将函数定义于指定地址 ?  11
33 如何在 V3 中使用混合语言 (mixed language)?  11
34 V3 代码生成器  11
Part IV V3 常见的 error, warning 及其解决方式 13
41 error“multi-ram-bank should be equipped with mp1” 13
42 error“internal compiler error:xxxx”  13
43 error (L1038)“RAM (bank0) overflow, memory allocation fails for section …” 13
44 error (L1038)“ROM/RAM (bank*) overflow, memory allocation fails for section …”
13
45 warning (L3010) (absolute address: xxh, length: x) is overlay with (absolute address: xxh, length: x) 13
46 warning (L3009): Same sub function exists between ISR(04H) CMG and MAIN CMG:
_func  13
Part V V3 常见的问题及其解决方式  14
51 如何在 V3 使用 bit 变量 ?  14
52 如何在 V3 使用外部定义 bit 变量 ?  14
53 程序 reset 后,变量被清 0 的解决方式 ?  14
54 指定地址的变量,其他文件如何引用 ?  15
55 对于写 EEPROM 有限制的 MCU( 需连续 set wren, wr, flag),如何使用 V3 写
EEPROM?  15
56 使用 V3 给 bit flag 赋值变量的注意事项  17
57 在 V3 使用 ROM BP 的注意事项  18



58 混合语言使用 ROM BP 的注意事项  18
59 如何使用 CMD 命令编译 C 工程?  19
510  混合语言工程在 asm 文件中使用 table read 的注意事项  19
511  中断函数中使用 inline assembly 注意事项  19
512 用其它方式修改 const 变量值 ( 比如烧录时修改 ROM),compiler 执行结果不变, 如何解决 ?  20
513 使用内嵌汇编语言的注意事项  20
Part VI V3 常见的优化问题 21
61 使用 V3 优化参数后,在 watch window 上看不到某些变数的 debug 信息 ?  21
62 中断与一般函数访问同一个全局变量,此全局变量的相关语句被优化掉 ?  21
63 V3 的优化功能及其对 debug 的影响 ?  21
64 使用 V3 compiler, debug 时行号出错 ? 21
65 使用 V3 compiler,用于延时的循环代码被优化,怎么解决 ?  22
66 使用内嵌汇编,被优化掉 ?  23
67 选择优化参数后,延时函数时间发生变化。  23

1.5 什么是长指令架构 MCU?
A:具有 LMOV,LSET 等长指令(长度为 2word)的 MCU,如 HT66F70A,一颗 MCU 是否有长指令,可以查看它的 datasheet,是否有 LMOV 等长指令,每条 长指令比对应的普通指令增加 1 个指令周期。

2.3 将 V2 程序改至 V3 常见的错误

2.3.1 ISR warning
e.g.
#pragma vector Int_isr @ 0x04 void Int_isr() {}
warning: ignoring #pragma vector Int_isr [-Wunknown-pragmas]
解决方式:
使用正确的中断函式语法:void    attribute((interrupt(0x04))) Int_isr() {}
详见《C Compiler V3 使用手册》2.2.1 节
注意:
i:因为是 warning,如果不修改也可以编译通过,只是编译程序会将它当一般 函式处理,而不是中断函式
ii:#pragma 的其他关键词 rambank/function 等,也会报此 warning,表示在 V3
版此功能无效。

2.3.2 内嵌汇编 error
e.g.
#asm nop
#endasm
error: invalid preprocessing directive #asm error: invalid preprocessing directive #endasm 解决方式:
选择参数“兼容 Holtek C V2 内嵌汇编语言”
详见语法书《 C Compiler V3 使用手册》2.2.5 节
2.3.3 bit 变数 error
e.g.bit a;
error: unknown type name 'bit'
解决方式:使用 HT-IDE3000 V7.93 以上版本
2.3.4 标志位 error
e.g. _40_1 = 1;
error: '_40_1' undeclared (first use in this function)
解决方式:
1. 用结构体位域定义 bit flag:
bit_type bit_var  attribute  ((at(0x40)));
#define _40_1 bit_var.bit1
详见《C Compiler V3 使用手册》2.2.3 节
2. 使用 bit 定义:
static volatile bit flag1  attribute  ((at(0x40),bitoffset(1)));
详见《C Compiler V3 使用手册》2.2.11 节
2.3.5 内部函数 error
e.g. _delay(2);
Error(L2001): Unresolved external symbol '    delay' in file
解决方式:
改成:
#include “ht66f50.h”
GCC_DELAY(2);
详见《C Compiler V3 使用手册》2.2.3 节



2.3.6 绝对地址变数 error
e.g.
unsigned char a @ 0x40;
error: stray '@' in program
error: expected '=', ',', ';', 'asm' or '    attribute   ' before numeric constant
解决方式:
改成以下语法:
volatile static unsigned char var_name  attribute  ((at(0x40)));
详见《C Compiler V3 使用手册》2.2.2 节
2.3.7 函式指标 error
e.g.
void FileFunc(){} void EditFunc(){} void main()
{
typedef void (*funcp)(void);
funcp pfun= FileFunc;
pfun();
pfun = EditFunc;
pfun();
}
error: incompatible types when initializing type 'funcp' using type 'void()' error: incompatible types when assigning to type 'funcp' from type 'void()' 解决方式:目前 V3 尚不支持 function pointer

Part III V3 的特殊语法及用法
3.1 如何将一个变量定义于指定 bank?
A:若是无长指令架构的 MCU,只能将变量定义在指定地址,如:
volatile static unsigned char var_name    attribute    ((at(0x140)));
详见《C Compiler V3 使用手册》2.2.2 节
若 是 长 指 令 架 构 的 MCU, 无 需 特 别 指 定,linker 会 自 动 分 配 变 量 到 任 意
bank。
3.2 如何将函数定义于指定地址 ?
A:IDE 7.8 以上版本才支持此功能,语法:
char  attribute ((at(0x373))) foo (char parm)
{}
表示将函数 foo 指定在地址 0x373. 详见《C Compiler V3 使用手册》2.2.6 节
3.3 如何在 V3 中使用混合语言 (mixed language)?
A:参考《C Compiler V3 使用手册》第 2.5 节
3.4 V3 代码生成器
为协助用户更好的使用 V3 专用语法,IDE3000 7.83 以上版本增加工具“V3 代 码生成器”,位于菜单栏 → 工具 → V3 代码生成器。它可以成生 bit 变量,中 断语法,绝对地址变量,内嵌汇编,delay 函数及指定其它 bank 的变量等语法, 具体可查看 HT-IDE3000 使用手册第三章“V3 代码生成器”部份。
0.png

Part IV V3 常见的 error, warning 及其解决方式
4.1 error“multi-ram-bank should be equipped with mp1”
A:请确认 MCU 是否为长指令架构,若是,请使用 IDE7.8 以上版本
4.2 error“internal compiler error:xxxx”
A:compiler 内部错误,请与 Holtek 公司返馈

4.3 error (L1038)“RAM (bank0) overflow, memory allocation fails for section ….”
A:对于短指令架构的 MCU,C Compiler 会默认把变量配置到 RAM bank0( 长指 令的 MCU 可以自动配置到任意 bank),当 bank0 满了之后,会报 RAM bank 0 overflow 出现此信息后,做法如下:
● 确认 unsigned int/long 类型的大小 ( 特别是从 V1 C Compiler 移植过来的程序 )
● 若为 multi RAM bank MCU,可手动将全局变量调到其它 bank,参考 3.1

4.4 error (L1038)“ROM/RAM (bank*) overflow, memory allocation fails for section ….”
A:ROM 或 RAM 空间不够出现此信息后,做法如下:
● 检查是否打开优化参数 -Os,参考《C Compiler V3 使用手册》2.1.4 节
● 删减不必要的程序

4.5 warning (L3010) (absolute address: xxh, length: x) is overlay with (absolute address: xxh, length: x)
A:出现此 warning 的情况:
不同变量定义的地址重迭,如下,_b 与 _a 地址重迭,需将 _b 定义在 0x0142
DEFINE_SFR(unsigned int _a, 0x0140); DEFINE_SFR(unsigned char _b, 0x0141);    //error

4.6 warning (L3009): Same sub function exists between ISR(04H) CMG and
MAIN CMG: _func
A:中断服务程序(04H)与主函数共同调用子函数 func,解决方式:
● 避免共同调用
详见《C Compiler V3 使用手册》2.2.1 节

Part V V3 常见的问题及其解决方式
5.1 如何在 V3 使用 bit 变量 ?
A:bit flag1; 详见《C Compiler V3 使用手册》2.2.11 节。
5.2 如何在 V3 使用外部定义 bit 变量 ?
A:extern bit flag1;
5.3 程序 reset 后,变量被清 0 的解决方式 ?
A:IDE7.8 版本将提供选择不初始化的方式:不选择下面选项“将未初始化的…”
即可。
0.png

5.4 指定地址的变量,其他文件如何引用 ?
A:因指定地址的变量 ( 非 const) 需定义成 static,其它作用域只在本文件,所以可 以将其定义在头文件里面,若有其它文件需要用到,直接 include 这个头文件 即可,例:
//Define_var.h
static volatile unsigned var1  attribute  ((at(0x180)));
//test1.c
#include “Define_var.h”
void foo1()
{


}
//test2.c

var1 = 1;

#include “Define_var.h”
void foo2()
{
var1 = 2;
}
注:若是 const 变量,不需要定义成 static,用 extern 即可,例:
//test1.c
const int  attribute ((at(0x3400))) bb[3]={1,2,3};
//test2.c
extern const int bb[3];
int b;
void fun()
{
b=bb[2];
}
5.5 对于写 EEPROM 有限制的 MCU( 需连续 set wren, wr, flag),如何使用
V3 写 EEPROM?
A:
i:在 V3 中,因为 _rden 与 _rd 是在 bank1,使用长指令,与 datasheet 所规定的 指定不同。
ii:这种对指令有严格要求的功能,建议使用内嵌汇编达成,因为 C 不敢保证 按特定的方式翻译。
iii:若要产出与 datasheet 中的连续指令,V3 需改成如下写法:
1.png

5.6 使用 V3 给 bit flag 赋值变量的注意事项
范例:
unsigned char flag;
_pa2=flag;
0.png
说明:
编译程序只关心计算的结果,而不管计算过程,为减少 CODE 的指令输出,编 译程序会翻译左边的指令。
C 语言与汇编不同的是,一条语句不只翻译出一条指令,所以在语句执行结束 前,计算未完成。
影响:
不管 flag 值为多少,PA2 都会被先 CLR,如果在此时进入中断,而中断中有用 到 PA,则会影响到执行结果。
解决方式:
● 在 bit 赋值前先把中断关掉,等计算完后再打开 总结: 多字节变量的计算,如果中断中有判断此变量,在计算未完成前,都不可进入
中断。

5.7 在 V3 使用 ROM BP 的注意事项
对于多 ROM BANK MCU,若整个工程都用 C 语言写,那么,任何时候,用户 都不需要设定 ROM BP,Linker 会自动设置 ROM BP,特别注意,若用户在程 序中改动到 ROM BP,那么程序将有可能跑飞,用户需特别小心,在设置 RAM BP 时,也应注意不要用到 ROM BP。若工程使用混合语言编程,用 C 函数 call 汇编 section 时,应使用 C 语言或 fcall,在汇编 section call C 函数时,需在 CALL 前设 BP,前在 CALL 之后恢复 BP。
范例:
;;Test1.asm
extern _fun2:near public _fun1
_fun1 .section ‘code’
_fun1 proc
mov a, bank _fun2
mov [04H],a ;; 假设 ROM BP 在 04h
call _fun2
mov a,bank_fun1 mov [04H],a
_fun1 endp
//Test2.c
extern void FUN1();
// 或者 asm(“extern _FUN1:near”);
void main()
{
FUN1();
// 或者 asm(“fcall _FUN1”);
}
void fun2()
{}
5.8 混合语言使用 ROM BP 的注意事项
参考 5.7 节
5.9 如何使用 CMD 命令编译 C 工程?
compiler,assembler,linker 的参数详见《V3 C Compiler 使用手册》附录 C
例:
a. 设置环境变量:
set HTCFG=C:\Program Files\Holtek MCU Development Tools\HT-IDE3000V7.x\MCU set HTBIN=C:\Program Files\Holtek MCU Development Tools\HT-IDE3000V7.x\BIN set HTINCLUDE=C:\Program Files\Holtek MCU Development Tools\HT-IDE3000V7. x\INCLUDE_V3
set HTLIB=C:\Program Files\Holtek MCU Development Tools\HT-IDE3000V7.x\LIB

b. 编译 .c 文件
…\hgcc32.exe  t1.c –g –Os –I “%HTINCLUDE%” -o t1.asm
…\hgcc32.exe  t2.c –g –Os –I “%HTINCLUDE%” –o t2.asm

c. 编译 .asm 文件
…\hasmgcc32.exe /hide=12345678 /chip=HT66F50 /case /z “t1.asm”
…\hasmgcc32.exe /hide=12345678 /chip=HT66F50 /case /z “t2.asm”

d. link 所有 obj,lib 产生 .tsk 文件
…\hlinker32.exe /MCU=HT66F50 @ “C:\link-test.bat”
link-test.bat 内容:
“t1.obj”+ “t2.obj”, “test.tsk”, “test.map”, “test.dbg”, “libholtekgcc.lib”;

5.10  混合语言工程在 asm 文件中使用 table read 的注意事项 如果一个工程即有 .c 又有 .asm 文件,那么在 .asm 文件中使用 table read 应注意 , 先将中断关掉,执行完后再打开。比如:
clr emi tabrd r0 inc tblp mov a,tblh

set emi

5.11  中断函数中使用 inline assembly 注意事项 在中断及其调用的函数中如果有使用 inline assembly,且 inline assembly 有使用 到特殊寄存器 ( 如 MP, TBLP, TBHP, TBLH 等 ),则用户需要自己保存这些寄存
器,如下语句:
DEFINE_ISR(isr04,0x04)
{
asm(“mov a,[01h]”); // mp0 = [01h]
asm(“mov temp_mp0,a”); asm(“mov a,80h”); asm(“mov [01h],a ”); asm(“mov a,[00h]”); asm(“mov a,temp_mp0”); asm(“mov [01h],a”);
}

5.12 用其它方式修改 const 变量值 ( 比如烧录时修改 ROM),compiler 执行 结果不变,如何解决 ?
比如:定义
  attribut ((at(0x400)))
const unsigned char array[] = {0,1,2,3,4,5,6,7};
烧录时把 ROM 的 400H~410H 清 0,执行 temp = array[7]; 时,temp 值仍为 7。
解决方式:
把 array[] 定义在与 temp = array[7]; 不同的 C 文件。
5.13 使用内嵌汇编语言的注意事项
汇编语言中使用到的变量、函数名、寄存器、标志位应遵循汇编语言的定义。
1. 如果全局变量 / 函数本文件只在内嵌汇编语言中使用,应增加汇编语言声明, 比如:
asm(“extern _a:byte”); asm(“extern _func:near”); void main()
{
asm(“clr _a”);
asm(“call _func”);
}
2. 寄存器 / 标志位应先定义后使用,可 include INC 文件,比如:
asm(“#include HT66F60.INC”)
void main()
{
asm(“CLR ACC”); asm(“MOV TBHP,A”); asm(“CLR C”);
}
3. 汇编语言中的名字要区分大小写。
Part VI V3 常见的优化问题
6.1 使用 V3 优化参数后,在 watch window 上看不到某些变数的 debug 信息 ?
A:因启用优化参数,变量有可能被优化删除,故没有 debug 信息,若要在 debug
时观察变量值,可以将此变量暂时定义为 volatile,debug 结束后再删去,比如:
volatile int i, j, k;
6.2 中断与一般函数访问同一个全局变量,此全局变量的相关语句被优化掉 ?
A:一般函数与中断没有调用关系,compiler 不知中断何时发生,会影响到一般函 数中的变量,因此,建议将此变量用 volatile 修饰,比如:
flag 在中断 ISR_INT0 中使用到,又在 main 函数中用到,则应定义成 volatile:
volatile unsigned char flag;
0.png
说明:volatile:一个类型修饰符(type specifier)。它是被设计用来修饰被不同 函数访问和修改的变数,使用 volatile 修饰的变量,不会因编译程序的优 化而被省去。
建议定义成 volatile 的变量:特殊寄存器,中断函式使用到的变量,为某些特殊 用途的代码定义的变量 ( 比如 delay 功能 )。
6.3 V3 的优化功能及其对 debug 的影响 ?
A:详见《C Compiler V3 使用手册》第 3 章
6.4 使用 V3 compiler, debug 时行号出错 ?
A:可能出现的情况:
a. 某些语句被优化掉而不译出 code,自然也没有 debug 信息。
1.png
b. 几条语句翻译出同一堆的 code,只显示一条 line number。
2.png
这些情况会可能会影响 debug,但执行结果不会出错,若不是这两种情况,请回报。


6.5 使用 V3 compiler,用于延时的循环代码被优化,怎么解决 ?
A:如下:
0.png
解决方法:将变量定义为 volatile,如下:
0.png
6.6 使用内嵌汇编,被优化掉 ?
如下:
asm(“mov %0,a”:”=m”(i));// 表示把 ACC 的值赋给 i,
因为之后变量 i 没有被用到,所以这条语句被编译程序优化掉,
0.jpg
如果要保留,可以改成:
asm volatile (“mov %0,a”:”=m”(i));
防止被优化
1.png
6.7 选择优化参数后,延时函数时间发生变化。
A:延时函数的延时时间通常依赖于执行的指令数,选择优化参数后,compiler 编 译出的指令更精简,从而影响延时时间,程序开发者应注意这点,在选择优化 参数后,调整延时函数或使用 compiler 自带的延时函数 GCC_DELAY(n)。

全部资料51hei下载地址:
合泰.pdf (2.21 MB, 下载次数: 80)
回复

使用道具 举报

ID:17771 发表于 2019-5-10 15:29 | 显示全部楼层
刚想用HT单片机,请帮助
回复

使用道具 举报

ID:529540 发表于 2019-5-11 11:44 | 显示全部楼层
ysy6450 发表于 2019-5-10 15:29
刚想用HT单片机,请帮助

同样在学习
回复

使用道具 举报

ID:342848 发表于 2019-8-28 11:05 | 显示全部楼层
合泰单片机性价比高,学习中
回复

使用道具 举报

ID:342848 发表于 2019-8-28 11:07 | 显示全部楼层
正在学习合泰触摸单片机
回复

使用道具 举报

ID:721169 发表于 2020-4-3 12:48 来自手机 | 显示全部楼层
谢谢分享
回复

使用道具 举报

ID:465596 发表于 2023-9-22 17:32 | 显示全部楼层
下载文件是 Touch MCU Workshop v3.0
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表