78K0C编译器
日电电子(中国)有限公司
2007 Jun. 李唐山
内容概要
C语言编程的优势和缺点 NEC的编译流程
CC78K0的扩展关键字 数据类型及类型转换
#pragma 指令
绝对地址访问,directmap 函数调用call,callt,callf 寄存器变量
saddr区域的使用
noauto函数
norec函数
中断函数处理及声明 位域(Bit Field)
循环移位函数
乘除法的运算
静态模式
Pascal函数
闪存区域
C和汇编相互调用
系统启动例行程序 ROM化过程
Bank的使用
PM+的编译选项说明 提高程序效率的建议
算法简单 容易理解 可移植性高 无需学习汇编
int u,x,y,z;void main(void){
z = ( x + y^5 ) * u;}
int u,x,y,z;void main(void){z = ( x + y^5 ) * u;}_main:
movw
ax,!_x
xch a,x add a,!_y xch a,x addc a,!_y+1xch a,x xor a,#05H xch a,x
movw _@RTARG0,ax movw ax,!_u call !@@iumul movw !_z,ax
ret
_main:movw ax,!_x xch a,x add a,!_y xch a,x addc a,!_y+1xch a,x xor a,#05H xch a,x movw _@RTARG0,ax movw ax,!_u call !@@iumul movw !_z,ax ret
不能实时掌握程序
优化程序比较困难
int u,x,y,z;void main(void){
z = ( x + y^5 ) * u;}
int u,x,y,z;void main(void){z = ( x + y^5 ) * u;}@@DATA DSEG _u:DS (2)_x:DS (2)_y:DS (2)_z:DS (2)@@CODE CSEG _main:
movw ax,!!_y movw bc,!!_x addw bc,ax xor c,#05H ; 5movw ax,!!_u muluw bc movw !!_z,bc ret
@@DATA DSEG _u:DS (2)_x:DS (2)_y:DS (2)_z:DS (2)@@CODE CSEG _main:movw ax ,!!_y movw bc ,!!_x addw bc,ax xor c ,#05H ; 5movw ax ,!!_u muluw bc movw !!_z,bc ret
p2 C
编
译
器
开
发
流
程
CC78K0的扩展关键字
p5 _ _callt/callt???????????callt函数的声明
_ _callf/ callf??????????callf函数的声明
_ _sreg/ sreg??????????sreg变量的声明
noauto??????????????noauto函数的声明
_ _leaf / norec??????????norec函数的声明
_ _boolean/ boolean????布尔型变量的声明
_ _interrupt ????????????硬件中断函数
_ _interrupt_brk????????软件中断函数
_ _asm????????????????汇编语句
_ _pascal?????????????pascal函数
_ _directmap??????????绝对地址配置指定
_ _temp ???????????????临时变量
bit ????????????????????bit型变量的声明
memset/memcpy???????存储器操作函数
p6
void --connection of null values
char --size of basic character (ASCII)
int--signed integer (-32768 ~ +32767)
long int--signed integer (-2147483648 ~ +2147483647) float --single precision floating point number
(1.17549435E-38F~3.40282347E+38F)
bit, boolean--integers represented with a single bit (0 or 1)
C 源程序
汇编输出
@@BITS BSEG _i DBIT _j DBIT _k DBIT
@@DATA DSEG
UNITP
_a:DS (1)_b:DS (2)_c:DS (2)_d:DS (2)_e:DS (2)_f:DS (4)_g:DS (4)_h:DS (4)
char a;int b;
short int c;signed d;unsigned e;long int f;float g;double h;bit i;
boolean j;__boolean k;void main(void){a=sizeof(h);}
p59
Int/short型转换为char型。-ZI
对以下没有指定类型的,认为是char型。
A)函数的参数和返回值
B)没有指定类型的变量/函数声明
Long型转换为int型。-ZL
[数据类型转换的设置]
CPU 控制指令#pragma NOP #pragma BRK #pragma HALT #pragma STOP
[#pragma ]指令总览
Directive: #pragma
中断指令#pragma DI #pragma EI 特殊功能寄存器#pragma sfr 汇编指令嵌入#pragma asm 绝对地址存取#pragma access
输出段的名称修改#pragma section
p22
[#pragma]特殊寄存器SFR
PUBLIC _main
_main:
mov PM0,#00H mov P0,#0FFH clr1MK0L.1ret END
#pragma sfr void main(void){
PM0 = 0x00;P0= 0xff;PMK0= 0;
}
C 源程序
汇编输出
特殊寄存器(SFR)位于『FF00h~FFFFh 』的256字节。
p28
[#pragma ]中断函数
PUBLIC _main _main:
di ei ret
#pragma DI #pragma EI void main(void){
DI();EI();
}
#pragma指令在#include之前定义,否则被认为是非法预处理指令。DI( ),EI( )必须大写,必须加括号,必须有#pragma定义。
p38
[#pragma]CPU控制命令#pragma NOP
#pragma BRK #pragma HALT #pragma STOP void main(void) {
NOP();
BRK();
HALT();
STOP(); }PUBLIC_main _main:
nop
brk
halt
stop
ret
进入某种待机状态时,指令后应该加4个以上的NOP语句,确保成功进入。
p39
[#pragma]嵌入汇编程序一PUBLIC
_main
_main:
movw ax,#0fH xch a,x ret END
#pragma asm
void main(void){
#asm
movw ax,#0fH xch a,x #endasm
}
C 源程序
汇编输出
汇编的内容存入CSEG区段,名称为@@CODE。不产生目标模块文件,只生成汇编源文件。
p33
[#pragma]嵌入汇编程序二
PUBLIC _a PUBLIC _b PUBLIC _main
_main:
movw ax,!_a movw !_b,ax ret END
int a;int b;
void main(void){
__asm("\tmovw ax,!_a");__asm("\tmovw !_b,ax");}
这样声明不需要#pragma asm的声明。__asm必须小写,否则无法识别。
__asm的字符串必须符合ANSI标准,可以使用ESC字符。
[#pragma]改变输出段的名称 改变编译器输出段可以独立对每个段进行定位,这样数据单元的数据也可以独立的存储。
如果忽略开始地址,就认为使用默认的空间分配方式。
如果在C代码之后执行#pragma指令,那么会生成汇编源文件而不生成目标模块文件。
#pragma section @@CODE CC1 AT 2400H #pragma section @@DATA ??DATA #pragma section @@DATA DATA2#pragma section @@DATA @@DATA
p45
[#pragma]绝对地址读
PUBLIC _a PUBLIC _b PUBLIC
_main
_main:
mov a,!0fb01H mov !_a,a
mov a,0FE23H mov !_a,a
movw ax,!0fb06H movw !_b,ax
movw ax,0FE68H movw !_b,ax
ret
#pragma access char a;int b;
void main(void){
a = peekb(0xfb01);a = peekb(0xfe23);
b = peekw(0xfb06);b = peekw(0xfe68);}
C 源程序
汇编输出
p41
[#pragma]绝对地址写(慎用)
C 源程序
汇编输出
PUBLIC _a PUBLIC _b PUBLIC
_main
:
_main:
mov a,#05H mov !0fb01H,a mov 0FE23H,#05H movw ax,#07H movw !0fb06H,ax movw 0FE68H,#07H
ret
#pragma access char a;int b;
void main(void){
pokeb(0xfb01,5);pokeb(0xfe23,5);pokew(0xfb06,7);pokew(0xfe68,7);}
[directmap ]绝对地址分配
PUBLIC _c PUBLIC _d PUBLIC _e PUBLIC _xx PUBLIC _main _c EQU 0FE00H _d EQU 0FE20H _e EQU 0FE21H _xx
EQU 0FE30H EXTRN __mmfe00EXTRN __mmfe20EXTRN __mmfe21EXTRN __mmfe30EXTRN __mmfe31_main:
mov a,#01H mov !_c,a
mov _d,#012H set1_e.5
mov _xx,#05H mov _xx+1,#0AH
ret
__directmap char c = 0xfe00;__directmap __sreg char d = 0xfe20;__directmap __sreg char e = 0xfe21;__directmap struct x {char a;char b;
} xx = {0xfe30};void main(void){
c = 1;
d = 0x12;e.5 = 1;xx.a = 5;xx.b = 10;}
p75