您好,欢迎访问三七文档
当前位置:首页 > 行业资料 > 其它行业文档 > SONIXC语言编程教程1
2020/1/10如何用C来完成SN8系列芯片的程序设计2ReviewSN8Cstudio的安装与使用数据类型与运算程序流程控制函数结构体、联合在SN8C程序中的应用中断位操作内嵌汇编程序结构3SN8Cstudio的安装与使用SN8Cstudio的安装SN8Cstudio应用实例4数据类型与运算数据类型基本类型字符型(char)整型(int)长整型(long)浮点型(float)构造类型数组(array)结构体(struct)共用体(union)枚举(enum)指针类型空类型5专有数据类型数据类型Size(Byte)数据取值范围Signedchar(short、int)1-128~+127Unsignedchar(short、int)10~255Signedlong2-32768~+32767Unsignedlong20~65535float、double4Pointer2enum16常量的定义先来看看汇编的常量定义:door_service_cequ#80;80ms去门抖动t0int_cequ#224;t0中断时间segment_cequ#3;最多3段烹调注:上面数值前的#号,是SN8ASM的符号,用于提示后面的是立即数。7常量的定义NOTE:对习惯于写汇编的人来说,千万注意C对大小写敏感!并从变量定义就要开始注意!再来看看用SN8C是如何定义相同的常量的:#definedoor_service_c80//80ms去门抖动#definet0int_c224//t0中断时间#definesegment_c3//最多3段烹调8数值列表汇编的表:disp_automenu:;显示菜单用第二数字表格dw0000hdw0ae1fh;A-1dw0ae2fh;dw0ae3fh;dw0ae4fh;dw0ae5fh;dw0ae6fh;dw0ae7fh;表的内容都是用DW关键字来定义9变量定义与限制__RAM与__ROM关键字的使用:Unsignedint__RAMramVeriable;__RAMunsignedintramVeriable2;Unsignedint__ROMromVeriable;__ROMunsignedintromVeriable2;将变量存放在RAM中[默认]将变量存放在ROM中10常量数值列表定义C定义的数值列表:unsignedlong__ROMdisp_automenu[]={0x0000,0x0ae1f,0x0ae2f,0x0ae3f,0x0ae4f,0x0ae5f,0x0ae6f,0x0ae7f};定义一个数组来存储这些表的数值11变量的定义汇编的定义变量的方法:.DATAorg0htemp1ds1temp2ds1led_dpds1stepds1Job_modeds2Pow_modeds4分别占用的Byte单位的RAM空间用DS关键字来定义变量空间12变量的定义用C定义变量:unsignedinttemp1;unsignedinttemp2;unsignedintled_dp;unsignedintstep;unsignedlongjob_mode;unsignedlongpower_mode1;floatpowerValue;inttemp1_1;longtemp2_2;C支持不同长度的变量类型,这样就方便了程序员的使用13变量定义的对比ASM.的定义C的定义DS1(un)signedint/short/charDS2(un)signedlongDS4Float/double14变量类型的选择在选择数据类型的时候,在能够顺利完成功能的情况下,请尽量选择占空间少的数据类型,这样不管是在RAM空间使用上还是在产生代码效率上都有很多的好处!能使用无符号数的都使用无符号数,以免处理出错,因为芯片内部是以无符号数处理的。15数据的存储SN8芯片的数据存储区Bank00000H通用存储区128Byte用户存储区007FH0080H系统寄存器区80H~FFH为系统寄存器区域00FFHBank100100通用存储区更多的用户存储区01FFh16系统寄存器系统寄存器表0123456789ABCDEF8LHRZYXPFLAGRBANK--------9AMPM---------------A--------------P4CON-BDAMADMADBADR-----------PEDGEC--P2M-P4MP5M--INTRQINTENOSCM-WDTRTC0RPCLPCHDP0-P2-P4P5--T0M-TC0MTC0CTC1MTC1CTC1RSTKPEP0UR-P2UR-P4URP5UR-@YZ--------FSTK7LSTK7HSTK6LSTK6HSTK5LSTK5HSTK4LSTK4HSTK3LSTK3HSTK2LSTK2HSTK1LSTK1HSTK0LSTK0H17.H档中对系统寄存器定义#includesn8p2708a.h#defineL(*((__RAMunsignedint*)0x80))#defineH(*((__RAMunsignedint*)0x81))#defineR(*((__RAMunsignedint*)0x82))#defineZ(*((__RAMunsignedint*)0x83))#defineY(*((__RAMunsignedint*)0x84))#defineX(*((__RAMunsignedint*)0x85))#definePFLAG(*((__RAMunsignedint*)0x86))……每个程序都要包含相应芯片的.H档这些系统寄存器都是以大写字母进行定义的,在程序中使用时要注意这一点。18程序流程控制顺序结构判断分支结构串行分支结构并行分支结构循环结构19顺序结构顺序结构流程A操作B操作框内A、B操作按顺序执行20顺序结构的实现对比.ASM.Cb0bsetkey_bibi_fmova,#0f0hmovmenu_disp_h,amova,#00hmovmenu_disp_l,amova,#11111111bmovdisp5,akey_bibi_f=1;menu_disp_h=0xf0U;menu_disp_l=0;disp5=0xffU;21判断分支结构判断分支结构的流程P为真?A操作B操作通过判断条件P是否成立来选择A或B进行操作22判断分支结构的实现对比.ASM.Ccmprsa,#0ahnopb0bts0fcjmp$+3b0mova,yretb0mova,yadda,#6hif(result_buf0x0a){result_buf=input+6;}else{result_buf=input;}23串行分支结构串行分支结构流程P1为真?P2为真?Pn为真?C1C2C3CnNYNYNY这就是多级判断分支组合,想想它们又都是怎么实现的呢?24串行分支结构实现对比.ASM.CBuzzer00:b0bts1P1jmpbuzzer10……jmpbuzzer40buzzer10:b0bts1P2jmpbuzzer20……jmpbuzzer40buzzer20:……if(P1){……}elseif(P2){……}elseif(Pn){……}C用if,elseif嵌套来实现串行分支结构25并行分支结构并行分支结构流程P=?A1A2A3AnP=1P=2P=3P=n并行分支结构其实是一个条件判断有多种可能,这又如何实现呢?26并行分支结构实现对比.ASM.Cmova,stepb0bts1fzJmpks82cmprsa,ONE_PRESS_CJmpks83cmprsa,TWO_PRESS_CJmpks84cmprsa,BESPOKE_ING_CJmpks85cmprsa,SELECT_TIME_CJmpks86switch(step){case0:ks81();break;caseONE_PRESS_C:ks82();break;caseTWO_PRESS_C:ks83();break;caseBESPOKE_ING_C:ks84();break;……}C可以用switch…Case来实现27循环结构1——WhileWhile循环流程AP为真?YN先判断,后执行!28While循环实现对比.ASM.CClryLoop:B0mova,yCmprsa,#15Jmp$+2Jmploop90decmsyjmplooploop90:RETtempbuf=0;while(tempbuf==15){++tempbuf;}编译器的转换并非和我们的比较代码一样29循环结构2——do…while循环Do…while循环流程AP为真?YN先执行,后判断!30Do…while循环实现对比.ASM.CClrRAM:clrYb0movZ,#0x7fClrRAM10:clr@YZdecmsZjmpClrRAM10clr@YZmova,#00Hunsignedint*pyz=(unsignedint*)0x7f;do{*pyz=0x00;--i;}while(i);Do…while循环在编译器的转换中具有最高的效率31函数函数的定义函数参数的传递函数参数与全局变量32函数的定义SN8C函数声明方式:返回值类型函数名(形参1数据类型,形参2数据类型,……);如:unsignedintbcd(unsignedint);在C当中,函数都应该先声明,后调用!33函数的定义方式函数定义方式:返回值类型函数名(参数列表)参数类型表;{函数体;}Note:对于无返回值的函数,都要声明是void,以免系统为其预留空间!仅在传统格式当中出现34函数参数传递与返回clock_min=bcd(clock_min);unsignedintbcd(unsignedintinput){………return(result_buf);}函数调用是通过参数传递和返回来传递数值35函数传递的内部实现假设于caller函数内调用callee函式.callee的参数名称为:_callee_arg?;?为参数个数。例如:intfoo(inta,intb,longc)会产生_foo_dataSEGMENTDATAINBANK;OVERLAYABLE_foo_arg0DS1;inta_foo_arg1DS1;intb_foo_arg2DS2;longc这些都由系统来完成!36函数参数传递实现对比.ASM.CMOVA,(_clock_min)__SelectBANK_bcd_arg0MOV_bcd_arg0,A;Endpusharg....call_bcd__SelectBANK(_clock_min)MOV_clock_min,Aclock_min=bcd(clock_min);实际参数clock_min被直接赋值给函数的形参_bcd_arg0,然后在调用函数中参加运算。最后返回值是在A中得到的。37返回值的存放返回值类型寄存器unsigned/signedcharAunsigned/signedshortAunsigned/signedintAunsigned/signedlongA,RfloatA,R,Y,Z返回值是数据结构的,系统则会在调用函数的时候增加一个隐含参数(地址)传递给被调函数,被调函数在完成功能运算后将结果放到指定的位置上,程序从函数里返回后就可以从该地址读取返回值。38尽管从原理上看起来,函数的参数传递与返回值的C与汇编的转换的形式是一样的,但是编译器产生代码时依然可能产生一些冗余代码。所以,在面对单片机这样的资源的硬件编程,过多的参数传递及过于复杂的返回值往往造成代码转换的低效率,这是用户需要注意的。39全局变量与函数参数全局变量函数参数贴近汇编的形式,产生代码的效率高。变量关联性高,模块化,可维护性,封装性差。模块化,可维护性,封装性好。存在数据传递的环节,更增加了转换的代码量。对于面对硬件的单片机编程,我们还是建议多用全局变量来传递数值
本文标题:SONIXC语言编程教程1
链接地址:https://www.777doc.com/doc-2849950 .html