基于单片机的数控恒流源设计软件设计.docx

上传人:b****6 文档编号:8210178 上传时间:2023-01-29 格式:DOCX 页数:27 大小:224.18KB
下载 相关 举报
基于单片机的数控恒流源设计软件设计.docx_第1页
第1页 / 共27页
基于单片机的数控恒流源设计软件设计.docx_第2页
第2页 / 共27页
基于单片机的数控恒流源设计软件设计.docx_第3页
第3页 / 共27页
基于单片机的数控恒流源设计软件设计.docx_第4页
第4页 / 共27页
基于单片机的数控恒流源设计软件设计.docx_第5页
第5页 / 共27页
点击查看更多>>
下载资源
资源描述

基于单片机的数控恒流源设计软件设计.docx

《基于单片机的数控恒流源设计软件设计.docx》由会员分享,可在线阅读,更多相关《基于单片机的数控恒流源设计软件设计.docx(27页珍藏版)》请在冰豆网上搜索。

基于单片机的数控恒流源设计软件设计.docx

基于单片机的数控恒流源设计软件设计

3.系统软件设计

本系统的软件设计采用C51语言和汇编语言混合编程。

主体程序采用C51编写,与硬件有关的程序、特别是对时序要求较严格的程序用汇编语言编写,即键盘扫描子程序、写TLC5618子程序、读MC14433子程序、显示缓冲子程序。

因为采用了C51和汇编语言混合编程的方式,故大大提高了本系统软件设计的效率和质量。

数控电流源的软件开发在KeilμVision4集成开发环境下完成的。

KeilμVision4集成开发环境是基于80C51内核的微处理器软件开发平台,内嵌多种符合当前工业标准的开发流程。

可以完成从工程建立、管理、编译连接、目标代码的生成、软件仿真、硬件仿真等完整的开发流程。

尤其是C语言编译工具在产生代码的准确性和效率方面达到了较高的水平,而且可以附加灵活的控制选项,在开发大型项目时非常理想。

KeilμVision4的使用方法是:

1.启动KeilμVision4集成开发环境,创建一个工程文件,并从器件数据库里选择一款CPU芯片(本课题使用AT89C52芯片);2.根据应用要求,在PC上用文本编辑软件编写C语言源程序、汇编语言源程序;利用编译工具软件对源程序进行编译,生成目标文件(.obj文件);利用连接工具对目标程序进行连接定位,生成绝对程序,将程序转化为十六进制代码程序(.hex文件),急可以装载到CPU芯片上运行。

3.1主程序

3.1.1主程序流程框图及程序

主程序流程框图如图3-1所示。

由主程序流程框图可知,其中的“扫描键盘”起到了很重要的作用,扫描键盘函数的返回值作为C51主程序中Switch语句的开关变量,根据不同的返回值进行相应的按键处理,因而主程序流程框图相当简单,并且系统软件整体程序的可读性高。

主程序是数控电流源软件设计的核心,主要由电流给定值设置功能函数、电流步进值设置功能函数、菜单选择功能函数、数码管定时刷新功能函数以及中断设置等构成。

设置电流给定值程序流程框图如图3-2所示,设置电流步进值程序流程框图如图3-3所示。

为完成数控电流源整体系统设计,在C51主程序中适时调用键盘扫描汇编语言子程序、写5618汇编语言子程序、读MC14433汇编语言子程序、显示缓冲汇编语言子程序,从而体现了C51语言程序和汇编语言程序相互调用的方便性。

 

图3-1主程序流程框图

#include

#defineucharunsignedchar

#defineuintunsignedint

sbitledbit=P2^0;/*功能指示灯控制位*/

ucharidatabuffer[8];/*定义键盘输入缓冲区*/

ucharidatakeycode;/*扫描键盘码变量*/

ucharidatastepval=1;/*步进值变量*/

ucharidatashowflag=0;/*当前显示标志,用以决定当前显示内容*/

uintidatagivecur=0;/*电流输出给定值控制变量*/

uintidatatruecur;/*电流实测值变量*/

externucharreadkey(void);/*声明扫描键盘函数为外部函数,此函数使用

汇编语言编写*/

externvoidshowbuffer(uchar*);/*声明缓冲区显示函数为外部函数,入口参数

为全局变量数组buffer的首址*/

externvoidwrite5618(uint);/*声明写TLC5618为外部函数,入口参数为要

写入的16-bit二进制数据,默认为TLC5618

的模拟A通道*/

externuintread14433(void);/*声明读MC14433为外部函数,无入口参数,

出口参数为读出的16-bit二进制数据*/

/*函数原型:

voidde15s(void)*/

/*功能:

信息提示延时显示,按任意键返回*/

/*调用函数:

readkey()*/

/*入口参数:

无*/

/*出口参数:

无*/

voidde15s(void)

{

uintm,n;

for(m=0;m<=2000;m++)

{

if(readkey()!

=0xff)break;/*按任意键跳出循环*/

for(n=0;n<=500;n++){}

}

}

setcur()

setsetp()

/*函数原型:

voidmenufun(void)*/

/*功能:

菜单选择功能函数,通过菜单选择功能函数,以进行相应的功能操作*/

/*调用函数:

readkey()*/

/*入口参数:

无*/

/*出口参数:

无*/

menufun()

{

ucharidatan;

ucharnumcount=0;

showflag=1;

ledbit=1;

P0=0xfe;

ledbit=0;

buffer[0]=0x0a;/*初始化8位数码管显示:

-灭灭灭灭灭灭灭*/

for(n=1;n<8;n++)

{

buffer[n]=0x0d;

}

while(showflag==0x01)

{

do/*不断扫描键盘,直到有键按下*/

{

keycode=readkey();

}while(keycode==0xff);

switch(keycode)/*根据按下的键值,进行相应操作*/

{

case0:

;

case1:

;

case2:

;

case3:

;

case4:

;

case5:

;

case6:

;

case7:

;

case8:

;

case9:

if(numcount!

=1)/*缓冲区只接收1位电流给定值数据输入*/

{

buffer[numcount]=keycode;/*置入键盘输入数据至键盘输入缓冲区*/

numcount++;/*每输入一个数据,缓冲区指针自加1*/}

break;

case0x0b:

showflag=0x00;/*返回键按下,则返回默认的显示状态*/

ledbit=1;

P0=0xff;

ledbit=0;

break;

case0x0c:

if(numcount==0x01)/*撤销键按下,则往前置入一横杠,以撤

{销前面已输入的一位数据*/

numcount--;

buffer[0]=0x0a;

}

break;

case0x0d:

if(numcount==1)/*确定键按下,根据键入的1位数据,进行

switch(buffer[0])相应操作*/

{

case0x01:

setcur();/*选择1号功能则进行给定电流值设置*/

showflag=0;

break;

case0x02:

setstep();/*选择2号功能则进行给定电流值设置*/

showflag=0;

break;

default:

break;

}

default:

break;

}

}

}

/*函数原型:

voidintt0(void)*/

/*功能:

定时中断函数,用于数码显示定时刷新*/

/*调用函数:

showbuffer()*/

/*入口参数:

无*/

/*出口参数:

无*/

voidintt0(void)interrupt1

{

uintidatan;

TH0=0xb8;/*重装定时值*/

TL0=0x00;

switch(showflag)/*根据刷新标志选择不同的刷新内容*/

{

case0:

n=givecur;/*刷新给定电流值千位、百位、十位、各位*/

buffer[0]=(uchar)(n/1000);

buffer[1]=(uchar)((n-(uint)buffer[0]*1000)/100);

buffer[2]=(uchar)((n-(uint)buffer[0]*1000-(uint)buffer[1]*100)/10);

buffer[3]=(uchar)(n-(uint)buffer[0]*1000-(uint)buffer[1]*100

-(uint)buffer[2]*10);

n=truecur;/*刷新实际电流值千位、百位、十位、各位*/

buffer[4]=(uchar)(n/1000);

buffer[5]=(uchar)((n-(uint)buffer[4]*1000)/100);

buffer[6]=(uchar)((n-(uint)buffer[4]*1000-(uint)buffer[5]*100)/10);

buffer[7]=(uchar)(n-(uint)buffer[4]*1000-(uint)buffer[5]*100

-(uint)buffer[6]*10);

showbuffer(buffer);

break;

case1:

showbuffer(buffer);break;

default:

break;

}

}

 

/*函数原型:

voidext0(void)*/

/*功能:

外部中断函数,用于读取MC14433的转换数据*/

/*调用函数:

read14433()*/

/*入口参数:

无*/

/*出口参数:

无*/

voidext0(void)interrupt0

{

uintn;

n=read14433();/*读取MC14433的转换数据,并转换为十进制*/

n=((n&0xf000)>>12)*1000+((n&0x0f00)>>8)*100+((n&0x00f0)>>4)*10+(n&0x000f);

}

 

main()/*主函数*/

{

ucharidatan;

uintidatam;

SP=0x40;/*修改堆栈指针*/

for(m=0;m<1000;m++)/*延时*/

{

}

EA=1;/*CPU开中断*/

ET0=0;/*允许定时器0定时中断*/

EX0=0;/*允许外部中断0中断*/

IT0=0;/*外部中断采用负边沿触发方式*/

TMOD=0X01;/*定时器采用16位定时工作方式*/

TH0=0XB8;/*设置等时期计数初值*/

TL0=0X00;

TR0=1;/*启动定时器0*/

while

(1)

{

do/*不断扫描按键,直到有键按下*/

{

keycode=readkey();

}while(keycode==0xff);

switch(keycode)/*根据按下键值,进行相应操作*/

{

case0x0a:

menufun();/*菜单键按下,进入菜单选择功能*/

break;

case0x0e:

m=givecur+stepval;/*“+”键按下,将给定值与步进值相加赋值m*/

if(m<=2000)/*若m小于等于2000,将累加值赋值给电流给值

{变量*/

givecur=m;

m=((givecur&0x0fff)*2)|0xc000;/*合成TLC5618数据写入格式*/

EX0=0;/*TLC对5618串口器件进行操作需要首先关闭

ET0=0;一切中断源*/

write5618(m);/*将合成数据写入TLC5618*/

EX0=1;/*串口操作结束之后再回复中断操作*/

ET0=1;

}

break;

case0x0f:

if(givecur!

=0)/*“-”键按下,将给定值与步进值相减*/

{

for(n=0;n

{

givecur--;

if(givecur==0)

break;

}

m=((givecur&0x0fff)*2)|0xc000;/*合成TLC5618数据写入格式*/

EX0=0;/*TLC对5618串口器件进行操作需要首先关闭

ET0=0;一切中断源*/

write5618(m);/*将合成数据写入TLC5618*/

ET0=1;/*串口操作结束之后再回复中断操作*/

EX0=1;

}

default:

break;

}

}

}

3.1.2设置电流给定值程序框图及程序

在菜单选择功能函数中,按下数字键“1”后,再按下“确定”键,显示切换为4个横杠,这是可以通过按数字键,置入电流数值以取代4个横杠,再按下确定键之后,则可将输入的电流给定值设置为当前的输出电流给定值。

但是输入的电流值必须在0~2000mA以内,并且必须置满4位数值,否则会显示出错信息“ERROR”,要求重新输入有效的电流值。

错误提示显示大约5秒后会自动返回该操作的初始化显示状态,也可以通过按任意键返回该操作的初始化显示状态。

如果中途不想再执行该操作,可以按“返回”键返回默认显示状态;如果输入过程中有错误所输入,可以按“撤销”键撤销前面已输入的电流值数据。

设置电流给定值程序框图如图3-2所示。

 

图3-2设置电流给定值程序框图

/*函数原型:

voidsetcur(void)*/

/*功能:

电流给定值设置功能函数,通过矩阵式键盘可快速设置2000mA以内的任意电流*/

/*调用函数:

readkey()、del5s()*/

/*入口参数:

无*/

/*出口参数:

无*/

setcur()

{

uintn;

ucharnumcount=0;

ledbit=1;

P0=0xfd;

ledbit=0;/*初始化功能指示灯不亮,表示正在进行的是

设置电流给定值的操作*/

for(n=0;n<4;n++)/*初始化8位数码管显示:

{----灭灭灭灭*/

buffer[n]=0x0a;

}

for(n=4;n<8;n++)

{

buffer[n]=0x0d;

}

while(showflag==0x01)

{

do/*不断扫描键盘,直到右键按下*/

{

keycode=readkey();

}while(keycode==0xff);

switch(keycode)/*根据按下的键值,进行相应操作*/

{

case0:

;

case1:

;

case2:

;

case3:

;

case4:

;

case5:

;

case6:

;

case7:

;

case8:

;

case9:

if(numcount!

=4)/*缓冲区只接收4位电流给定值数据输入*/

{

buffer[numcount]=keycode;/*置入键盘输入数据至键盘输入缓冲区*/

numcount++;/*每输入一个数据,缓冲区指针自加1*/

}

break;

case0x0b:

showflag=0x00;/*返回键按下,则返回默认的显示状态*/

P0=0xff;

ledbit=1;

ledbit=0;

break;

case0x0c:

if(numcount!

=0x0)/*撤销键按下,则往前置入一横杠,以撤

{销前面已输入的一位数据*/

numcount--;

buffer[numcount]=0x0a;

}

break;

case0x0d:

n=(uint)buffer[0]*1000+(uint)buffer[1]*100+(uint)buffer[2]*

10+(uint)buffer[3];/*确定键按下,且输入电流值为小于2000

if((numcount==4)&&(n<=2000))的4位数,则将给定电流值合成要写入

{TLC5618的16-bit二进制数据*/

givecur=n;

n=((givecur&0x0fff)*2)|0xc000;

EX0=0;

ET0=0;

write5618(n);/*将合成的数据写入TLC5618*/

EX0=1;

ET0=1;

showflag=0;

ledbit=1;

P0=0xff;

ledbit=0;/*恢复默认显示状态*/

}

else/*确定键按下,但输入电流值无效,则显示{ERROR的错误提示*/

buffer[0]=0x0b;

buffer[1]=0x0c;

buffer[2]=0x0c;

buffer[3]=0x00;

buffer[4]=0x0c;

buffer[5]=0x0d;

buffer[6]=0x0d;

buffer[7]=0x0d;

de15s();/*延时5s自动返回或按任意键返回*/

for(n=0;n<4;n++)/*重新初始化8位数码管显示:

*(buffer+n)=0x0a;----灭灭灭灭*/

for(n=4;n<8;n++)

*(buffer+n)=0x0d;

numcount=0x00;/*恢复缓冲区初始指针*/

}

break;

default:

break;

}

}

}

3.1.3设置电流步进值程序流程框图及程序

在菜单选择功能函数中,按下数字键“2”后,再按下“确定”键,这时可以通过按数字键,置入电流步进值以取代2个横杠,再按下“确定”键之后,则可将输入的电流步进值设置为当前的电流步进值,可以设置的电流步进值范围为0~99mA。

其他功能按键的操作同上。

设置电流步进值程序流程框图如图3-3所示。

比较图3-2和图3-3所示,二者很相似,这种相似性有利于程序代码的编写。

 

 

图3-3设置电流步进值程序流程框图

/*函数原型:

voidsetsetp(void)*/

/*功能:

步进值设置功能函数,用来设置每次“+”、“—”键按下时的步进值*/

/*调用函数:

readkey()、del5s*/

/*入口参数:

无*/

/*出口参数:

无*/

setstep()

{

ucharidatan;

ucharidatanumcount=0;

ledbit=1;

P0=0xfb;

ledbit=0;

for(n=0;n<2;n++)/*初始化8位数码管显示:

{--灭灭灭灭灭灭*/

buffer[n]=0x0a;

}

for(n=2;n<8;n++)

{

buffer[n]=0x0d;

}

while(showflag==0x01)

{

do/*不断扫描键盘,直到有键按下*/

{

keycode=readkey();

}while(keycode==0xff);

switch(keycode)/*根据按下的键值,进行相应操作*/

{

case0:

;

case1:

;

case2:

;

case3:

;

case4:

;

case5:

;

case6:

;

case7:

;

case8:

;

case9:

if(numcount!

=2)/*缓冲区只接收4位电流给定值数据输入*/

{

buffer[numcount]=keycode;/*置入键盘输入数据至键盘输入缓冲区*/

numcount++;/*每输入一个数据,缓冲区指针自加1*/

}

break;

case0x0b:

showflag=0x00;/*返回键按下,则返回默认的显示状态*/

ledbit=1;

P0=0xff;

ledbit=0;

break;

case0x0c:

if(numcount!

=0x0)/*撤销键按下,则往前置入一横杠,以撤

{销前面已输入的一位数据*/numcount--;

buffer[numcount]=0x0a;

}

break;

case0x0d:

if(numcount==2)/*确认键按下,且步进电流值为2位,则将

{设置的2位步进值赋值给步进值变量*/

stepval=buffer[0]*10+buffer[1];

showflag=0;

ledbit=1;

P0=0xff;

ledbit=0;/*恢复默认显示状态*/

}

else/*确定键按下,但输入步进电流值不是2

{位,则显示ERROR的错误提示*/

buffer[0]=0x0b;

buffer[1]=0x0c;

buffer[2]=0x0c;

buffer[3]=0x00;

buffer[4]=0x0c;

buffer[5]=0x0d;

buffer[6]=0x0d;

buffer[7]=0x0d;

de15s();/*延时5s自动返回或按任意键返回*/

for(n=0;n<2;n++)/*重新初始化8位数码管显示:

*(buffer+n)=0x0a;--灭灭灭灭灭灭*/

for(n=4;n<8;n++)

*(buffer+n)=0x0d;

numcount=0x00;/*恢复缓冲区初始指针*/

}

break;

default:

break;

}

}

}

3.2键盘扫描程序流程框图及程序

数控电流源主程序中频繁调用键盘扫描子程序,键盘扫描子程序主要完成键入数值、返回、撤销、确认等功能。

本设计中,4*4矩阵键盘工作在循环扫描工作方式,主要有判断键盘上是否有键按下、去除键的抖动影响、扫描键盘、判断闭合的键是否释放等内容,C51语言程序在调

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 工学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1