3
1.1 何为 DWIN C Complier?
DWIN C Complier是基于T5 CPU 开发的一款C语言编译器程序。编译又扮演一个什么角色呢?简单来讲,编译器是将“高级语言”翻译为“低级语言”的程序,其工作流程为:源代码 (source code) → 预处理器 (preprocessor) → 编译器 (compiler) → 目标代码 (object code) → 链接器(Linker) → 可执行程序 (executables)。
迪文屏二次开发主要用到的是DWIN OS Builder,也就是汇编语言开发(低级语言),大大提升产品开发的难度。在实际项目开发中,DWIN C Complier的效率提升了30%-40%。举个例子,对于一些极端的项目,使用DWIN OS Builder进行开发需要2-3天;而使用C 语言进行开发可能2个小时就可以完成。
图1:DWIN C Complier主界面
1.2 使用说明
1.2.1 资源介绍
a. 全局变量与局部变量共用 1792 字节空间,正在运行时刻的总变量所占空间不能超
过 1792 字节。
b. VP 空间按照芯片提供进行使用。
c. 程序空间为 32K 字节程序代码。
1.2.2 语法介绍
a. 标准 C 编译器程序语法结构,可以参照网上资源来学习。
注:对于宏定义的使用多语句尽量使用函数进行封装,宏定义每个使用位置都是字
符串的代替不会有代码节省功能。
b. 标准 C 语言库函数此编译器不支持,但是配套迪文产品支持如下列表中的库函数。
库函数放在 00.LIB 与 01.LIB 文件中,请将两个库文件进行烧录。
1.2.3 编译器介绍与开发流程
a. 编译器功能介绍
开始程序编写之前请先设置库文件加载到 VP 空间首地址,首地址范围
0X1000-0XF000,必须为偶数 ,预留空间至少 0X1000 字。
第一步,新建或者打开一个工程文件,文件名为**.dwin。如果是新建工程请先对工程
进行保存。在工程头文件项目中添加*.h 文件,在工程源文件项目中添加*.c 文件。
第二步,在程序编写框中编写程序。
第三步,编译程序,根据编译结果进行调整。对未保存的程序进行编译时会先弹出保存窗口提示保存,此时请先进行保存,如果不保存程序将会丢失。
第四步,下载程序,根据需要进行调试。
注:与 OS 相同最终下载到 FLASH 中为实际保存在芯片中的程序。
图2:图标说明
b. 程序框架与例程
- /*题目:输入数组,最大的与第一个元素交换,最小的与最后一个元素交换,
- 输出数组。*/
- int cs_01=0; //全局变量
- void move(int array[],int n,int offset); //子函数声明
- int main()
- {
- int arr[20]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
- int i,n,offset;
- offset=4;
- n=16;
- move(arr,n,offset); //滚动数组-子函数调用
- write_dgus_vp(0x1280,arr,16); //特殊函数调用
- return 1;
- }
- //滚动数组
- void move(int array[],int n,int offset) //子函数
- {
- int *p,*arr_end; //局部变量
- int last;
- arr_end=array+n; //数组末尾元素的下一个位置
- while(offset) //滚动直到偏移量为 0
- {
- last=*(arr_end-1);
- for(p=arr_end-1;p!=array;--p) //向右滚动一位
- *p=*(p-1);
- *array=last;
- --offset;
- cs_01++;
- }
- }
- void time0_IRQHandler(void) //定时器 0 函数体
- {
- }
- void Time1_IRQHandler(void) //定时器 1 函数体
- {
- }
- void Time2_IRQHandler(void) //定时器 2 函数体
- {
- }
复制代码
注:定时器中断入口函数必须要放在程序中,如果没有定时中断则在此处放置空函数即可,如果有中断则先配置相应中断时钟,然后在中断函数中编写程序。并且,中断函数中不可调用特殊函数和包含特殊函数的子函数,也不能运行库函数。调试过程中如果打开中断程序可能频繁进中断程序,根据需要可以酌情屏蔽。
1.2.4 调试与下载
a.下载
程序编写完毕之后先进行编译,提示编译成功后可以选择将程序下载到芯片 SRAM
中(断点不保存)或者下载到 FLASH 中断电保存。
b. 调试
程序下载完成之后点击 图标,程序进入调试状态。在调试状态可以使用单步调试、单行调试、运行断点等功能,配合编译器右侧的变量显示框可以获取当前状态数据。调试过程中只能在一个文件中打断点,跳转到其他文件执行时之前文件的断点会消失,需要重新补充。
2.0 DWIN C Complier 例程
2.1 例程1:实现密码登陆和改写
密码登录与改写是人机界面非常常见的一个功能,在此将功能利用屏上面独立实现,节省了单片机不必要的代码,另外保存密码也是占用的屏独立的flash存储区域。
- /*
- 软件版本:DWIN C Compiler 1.1.0.4
- 程序功能:T5DGUSos的C编译器入门学习参考系列例程1-密码登录与改写
- 更新时间:2018年11月01日
- DGUS变量地址分配:
- 地址1000-1001H密码登录框
- 地址1002-1003H密码改写框1
- 地址1004-1005H密码改写框2
- 地址1006-1006H重建密码按键返回
- 地址1008-1009地址进行将数据库存放的密码的读出来在屏上面参与比较。
- */
- int main()
- {
- char Variable_Addr[8]={0}; //traditional rules ,not rule C99 (传统的用法必须在一个代码块的开始处声明变量,不能像C99那样)
- char i=0; //
- char Switch_Page[4]={0x5a,0x01,0x00,0x00}; //页面切换07密码正确页面 02错误页面
- char Vp_Clear[10]={0};//清空密码改写框1、2和重建密码按键返回按键
- char Supervisor_Password[4]={0x00,0x02,0x2c,0xc8};//142536=00 02 2c c8 赋值超级密码
- char Read_Flash[8]={0x5a,0x00,0x10,0x08,0x10,0x08,0x00,0x02}; //数据库读操作
- char Write_Flash[8]={0xa5,0x00,0x10,0x08,0x10,0x02,0x00,0x02}; //数据库写操作
- char RW_Flash_Flag[2]={0};
- char RW_Flash_Value[4]={0};
- // char Change_Password_Button[4]={0};
- // *************密码登录***********************
- read_dgus_vp(0x1000,Variable_Addr,2); //读密码框是否为0,如果为0,
- for (i=0;i<4;i++)
- {
- if(Variable_Addr[i]==0) //
- {
- }
- else //
- {
- write_dgus_vp(0x0008,Read_Flash,4); //读5a a5 0b 82 0008 5a00 1008 1008 0002
- read_dgus_vp(0x1008,RW_Flash_Value,2);
- do
- {
- read_dgus_vp(0x0008,RW_Flash_Flag,1);
- }
- while(RW_Flash_Flag[0]==0x5A);
- if (tests(Variable_Addr,RW_Flash_Value,4)==0)
- {
- Switch_Page[3]=7;
- write_dgus_vp(0x0084,Switch_Page,2);
- write_dgus_vp(0x1000,Vp_Clear,2);
- }
- else //先比较是否为万能密码142536=00 02 2c c8
- {
- if (tests(Variable_Addr,Supervisor_Password,4)==0)
- {
- Switch_Page[3]=7;
- write_dgus_vp(0x0084,Switch_Page,2);
- write_dgus_vp(0x1000,Vp_Clear,2);
- }
- else
- {
- Switch_Page[3]=2;
- write_dgus_vp(0x0084,Switch_Page,2);
- write_dgus_vp(0x1000,Vp_Clear,2);
- }
- }
- }
- }
- // *************密码改写***********************
- read_dgus_vp(0x1006,Variable_Addr,2); //读重建密码按钮是否按下如果按下了,说明进行了密码改写操作,
- if((Variable_Addr[0]==0)&&(Variable_Addr[1]==0x5a))//
- {
- read_dgus_vp(0x1002,Variable_Addr,4); //读输入密码框1、2是否为0,如果为0不执行
- for (i=0;i<8;i++)
- {
- if(Variable_Addr[i]==0) //
- {
- write_dgus_vp(0x1006,Vp_Clear,2); // 清空按键值
- }
- else
- {
- if (tests(Variable_Addr,Variable_Addr+4,4)==0) //比较密码改写框1、2是否相等,相等将密码保存到数据库,并跳转提示页面6
- {
- write_dgus_vp(0x0008,Write_Flash,4); //写5a a5 0b 82 0008 a5 00 1008 1002 0002
- do
- {
- read_dgus_vp(0x0008,RW_Flash_Flag,2);
- }
- while(RW_Flash_Flag[0]==0xa5);
-
- Switch_Page[3]=6;
- write_dgus_vp(0x0084,Switch_Page,2);
- write_dgus_vp(0x1002,Vp_Clear,5);
- break;
- }
- else //比较密码改写框1、2是否相等,不相等跳转提示页面6
- {
- Switch_Page[3]=5;
- write_dgus_vp(0x0084,Switch_Page,2);
- write_dgus_vp(0x1002,Vp_Clear,5);
- }
- }
- }
- }
- return 0;
- }
- // *******************************************
- void Time0_IRQHandler(void) //定时器0 函数体
- {
- }
- void Time1_IRQHandler(void) //定时器1 函数体
- {
- }
- void Time2_IRQHandler(void) //定时器2 函数体
- {
- }
复制代码
2.2 例程2
- /************************************file start*******************************************/
- int TIM_SYS=0;
- unsigned char uart6_read[256];
- int uart6_rx_head=0,uart6_rx_tail=0;
- void cs_define(void)
- {
- int a,b;
- a=A;
- a+=A;
- write_dgus_vp(0x1280,&a,2);
- a+=B;
- write_dgus_vp(0X1282,&a,2);
- a=C(100,200,300);
- write_dgus_vp(0X1284,&a,2);
- b=B;
- D(a,b);
- write_dgus_vp(0x1286,&a,2);
- write_dgus_vp(0x1288,&b,2);
- b=3;
- E(a,b);
- write_dgus_vp(0x128a,&a,2);
- }
- int main()
- {
- char data;
- int ii=0,len,x;
- char vp_data[4]={0x5a,0x01,0x00,0x01};
- char vp_data_read[4]={0};
- char lib_data[10]={0x5A,0X00,0X18,0X00,0XE0,0X00,0X08,0X00};
- //float型数定义
- float bonus1,bonus2,bonus4,bonus6,bonus10,bonus,i;
- //define tests
- cs_define();
- //VP操作
- //dgus_page(1); //VP操作--页面切换
- write_dgus_vp(0x1280,vp_data,2); //VP操作-写
- read_dgus_vp(0x1280,vp_data_read,2); //VP操作-读
- //中断配置,接口寄存器操作
- data=0xC0;
- write_register(45,&data); //设置中断
- data=10;
- write_register(46,&data); //定时器0设置
- //IO口设置
- IOconfig(0x0003FDFF); //串口9为输入其他串口为输出
- //串口设置
- com_config(6,0,115200); //串口6设置115200波特率
- //库文件加载到VP空间
- load_lib(3,0xe000,1); //3号库文件,文件在例程中
- //float型数据操作
- i=50000.3f;
- bonus1=100000*0.1f; //浮点数计算
- bonus2=bonus1+100000*0.075f;
- bonus4=bonus2+200000*0.05f;
- bonus6=bonus4+200000*0.03f;
- bonus10=bonus6+400000*0.015f;
- if(i<=100000.00f) { //语句判定
- bonus=i*0.1f;
- } else if(i<=200000.00f) {
- bonus=bonus1+(i-100000.0f)*0.075f;
- } else if(i<=400000.00f) {
- bonus=bonus2+(i-200000.0f)*0.05f;
- } else if(i<=600000.00f) {
- bonus=bonus4+(i-400000.0f)*0.03f;
- } else if(i<=1000000.00f) {
- bonus=bonus6+(i-600000.0f)*0.015f;
- } else if(i>1000000.0f) {
- bonus=bonus10+(i-1000000.0f)*0.01f;
- }
- x=(int)bonus; //类型强制转换
- write_dgus_vp(0x1288,&x,2);
- while(1){
- //串口处理部分
- len=com_data_len(6);
- while(len){
- com_data_read(6,&uart6_read[uart6_rx_head],1);
- uart6_rx_head=(uart6_rx_head+1) & 0XFF; //接受头指针修改
- len--;
- }
- if(uart6_rx_head != uart6_rx_tail){
- send_data_com(6,&uart6_read[uart6_rx_tail],1);
- uart6_rx_tail=(uart6_rx_tail+1) & 0XFF; //处理完毕之后接受尾指针处理
- }
- //IO口操作
- ii=read_io(9); //读取IO口状态
- write_io(3,ii); //写IO口状态
- write_io(5,ii);
- write_io(7,ii);
- //运行库文件
- run_lib(0xe000); //运行库文件,运行效果0X1280变量空间中的数据每个循环增加1
- }
- return 0;
- }
- //中断函数实体
- void Time0_IRQHandler(void)
- {
- TIM_SYS++;
- }
- void Time1_IRQHandler(void)
- {
- }
- void Time2_IRQHandler(void)
复制代码
注:例程详情参照附件。
|
|