单片机程序基于51单片机的12V数控电源设计 基于51单片机的12V数控电源设计 2008年08月14日 星期四 下午 01:54 忙了三天终于把数控电源搞定了.这次做的数控电源设计思想没什么新意,就是一个数模转换(ADC0809)和一个模数转换(DAC0832),再加上两个单片机分别控制0809和0832,组成一个反馈网络,来得到输入的数字相对应的电压,电压范围很小,只有0~12.75V.显示部分采用四段共阴数码管,为什么不用共阳的?哎,只因为最开始买零件的时候没有注意到单片机的驱动能力问题,买了一堆很不实用的零件.所以...之所以用...
基于51单片机的12V数控电源
基于51单片机的12V数控电源设计 2008年08月14日 星期四 下午 01:54 忙了三天终于把数控电源搞定了.这次做的数控电源设计思想没什么新意,就是一个数模转换(ADC0809)和一个模数转换(DAC0832),再加上两个单片机分别控制0809和0832,组成一个反馈网络,来得到输入的数字相对应的电压,电压范围很小,只有0~12.75V.显示部分采用四段共阴数码管,为什么不用共阳的?哎,只因为最开始买零件的时候没有注意到单片机的驱动能力问
,买了一堆很不实用的零件.所以...之所以用两片单片机,也是因为觉得之前的单片机都没什么用了,以后改学430了,这些旧的单片机就用来做成一些实用的东西吧.呵呵,省得浪费. 整块板子做出来之后有10*7cm那么大,用洞洞板焊的. 实测电路输出精度+/-0.05V在12V范围内. 硬件设计: 第一块单片机P0口接数码管代码段的驱动,P2.4~P2.7接四位的位选线,P2.0~P2.3节四个独立操作按键 [模式] [加] [减] [确定] ,P1口接ADC0809的八位数据输出.P3.0~P3.3口接0809的控制线.P3.5~P3.7和第二块单片机的P2.0,P2.1,P2.2相连,用来控制数模输出增减.三根控制线作用分别为 [输出改变允许控制Control_1] [增减信号Control_2] [增减速度控制Control_speed] 第二块单片机除了前面的三根控制线,就只剩下和DAC0832的控制线了,看电路图. 用0832输出控制LM317可调三端稳压器的输出电压: DAC0809所需时钟脉冲由NE555产生 系统电源:5V 12V GND -12V 程序清单: 第一块单片机:(接0809,四段数码管,四个独立按键) #include
#define uchar unsigned char int i=0,a=0;//定义循环算子 uchar hold=5;//当前操作数[0-led1][1-led2][2-led3][3-led4][4-快速调节][5-无] uchar Get_data=0;//模数转换得到的结果 int Get_data2=0;//将Get_data*5用以方便转化 (做电压表时用) //uchar led[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x00};//阳极驱动不带小数点 uchar led[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0xFF};//阴极驱动 //uchar point[]={0xBF,0x86,0xDB,0xCF,0xE6,0xED,0xFD,0x87,0xFF,0xEF,0x00};//阳极驱动带小数点 uchar point[]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10,0xFF}; uchar V_list[]={30,36,60,66,90,100,120,180,240};//电压值列表 uchar V_index=6;//预置电压索引. uchar num[4]={10,5,0,0};//显示缓存 uchar V_num=100;//显示的电压对应在0~255电之间的值,预置压数5V uchar time=0;//控制模数转换频率变量 uchar times=0;//控制按键允许速度变量 uchar scan_grant=1;//允许输入 uchar hide_flag=0;//隐藏标志[0隐藏][1显示]和hold配合用于控制某一位数码管的亮灭 uchar hide_time=0;//用于控制数码管闪烁快慢 //uchar zhengshu,xiaoshu_1,xiaoshu_2; void delay(int s); void key_mode(); void key_add(); void key_sub(); void key_confirm(); void display(); void ADC(); void convert();//将get_data填入到num[]数组中 void scan_key();//键盘扫描函数 void compare();//比较函数(Control_1 Control_2)[00-正确][11-加][10减] //定义位选线 sbit led_1=P2^7; sbit led_2=P2^6; sbit led_3=P2^5; sbit led_4=P2^4; sbit mode=P2^0; sbit add=P2^1; sbit sub=P2^2; sbit confirm=P2^3; //0809四根控制线 sbit ALE=P3^0; sbit START=P3^1; sbit OE=P3^2; sbit EOC=P3^3; //两根控制线 sbit Control_1=P3^6;//变化控制线[1变化][0不变] sbit Control_2=P3^7;//增减控制线[1增][0减] sbit Control_speed=P3^5;//控制变化速度 sbit close=P3^4;//当电压稳定时为0; void main() { //初始化 led_1=0; led_2=0; led_3=0; led_4=0; //初始化定时器 TMOD=0x01; //定时器0,方式1 TH0=0x3c; TL0=0xb0; ET0=1; //允许定时器0中断 TR0=1; //启动定时器0运行 EA=1; //全部中断允许 Control_1=0; Control_2=0; while(1) { time++; if(time>=10) { time=0; //扫描键盘 if(hold==5) { ADC();//模数转换 compare();//转换结果比较,修改控制变量 } else { Control_1=0; Control_2=0; } } if(scan_grant==0) { scan_key(); convert(); scan_grant=1; EA=1; } hide_time++; if(hide_time>=80) { hide_time=0; if(hide_flag==1) {hide_flag=0;} else {hide_flag=1;} } display(); } } //延时函数 void delay(int s) { for(i=0;i=6) {hold=1;} } } void key_add()//加函数 { delay(1000); if(add==0) { if(hold==0)//当前操作数[0-led1 即num[0]] { } if(hold==1)//当前操作数[1-led2 即num[1]] { if(V_num<=235) {V_num=V_num+20;}//加1V } if(hold==2)//当前操作数[2-led3 即num[2]] { if(V_num<=253) {V_num=V_num+2;}//加0.1V } if(hold==3)//当前操作数[3-led4 即num[3]] { if(V_num<=254) {V_num++;}//加0.05V } if(hold==4)//当前操作数[4-快速调节 即V_index] { if(V_index<=7) {V_index++;} V_num=V_list[V_index]; } if(hold==5)//当前操作数[5-无] { } } } void key_sub()//减函数 { delay(1000); if(sub==0) { if(hold==0)//当前操作数[0-led1 即num[0]] { } if(hold==1)//当前操作数[1-led2 即num[1]] { if(V_num>=20) {V_num=V_num-20;}//减1V } if(hold==2)//当前操作数[2-led3 即num[2]] { if(V_num>=2) {V_num=V_num-2;}//减0.1V } if(hold==3)//当前操作数[3-led4 即num[3]] { if(V_num>=1) {V_num--;}//减0.05V } if(hold==4)//当前操作数[4-快速调节 即V_index] { if(V_index>=1) {V_index--;} V_num=V_list[V_index]; } if(hold==5)//当前操作数[5-无] { } } } void key_confirm() { delay(1000); if(confirm==0) { hold=5; } } //------------------------------------------------------------- void display() { /* led_1=1; if(num[0]==0)//如果第一位是0的话就不显示,led[10]是空 {P0=led[10];} else {P0=led[num[0]];} delay(100); led_1=0; P0=0xFF; led_2=1; P0=point[num[1]]; delay(100); led_2=0; P0=0xFF; led_3=1; P0=led[num[2]]; delay(100); led_3=0; P0=0xFF; led_4=1; P0=led[num[3]]; delay(100); led_4=0; P0=0xFF;*/ if(hide_flag==1) { if(hold==4) { delay(400); return; } if(hold!=1) { led_1=1; if(num[0]==0)//如果第一位是0的话就不显示,led[10]是空 {P0=led[10];} else {P0=led[num[0]];} delay(100); led_1=0; P0=0xFF; led_2=1; P0=point[num[1]]; delay(100); led_2=0; P0=0xFF; } if(hold!=2) { led_3=1; P0=led[num[2]]; delay(100); led_3=0; P0=0xFF; } if(hold!=3) { led_4=1; P0=led[num[3]]; delay(100); led_4=0; P0=0xFF; } } if(hide_flag==0) { led_1=1; if(num[0]==0)//如果第一位是0的话就不显示,led[10]是空 {P0=led[10];} else {P0=led[num[0]];} delay(100); led_1=0; P0=0xFF; led_2=1; P0=point[num[1]]; delay(100); led_2=0; P0=0xFF; led_3=1; P0=led[num[2]]; delay(100); led_3=0; P0=0xFF; led_4=1; P0=led[num[3]]; delay(100); led_4=0; P0=0xFF; } } void ADC() { START=0; OE=0; START=1; delay(65); START=0; while(EOC==1) {} OE=1; delay(65); Get_data=P1; OE=0; // convert(); } void convert() { //基准电压要为12.8V /* Get_data2=Get_data*5; num[0]=Get_data2/1000; Get_data2=Get_data2%1000; num[1]=Get_data2/100; Get_data2=Get_data2%100; num[2]=Get_data2/10; Get_data2=Get_data2%10; num[3]=Get_data2; */ Get_data2=V_num*5; //Get_data2=Get_data*5; num[0]=Get_data2/1000; Get_data2=Get_data2%1000; num[1]=Get_data2/100; Get_data2=Get_data2%100; num[2]=Get_data2/10; Get_data2=Get_data2%10; num[3]=Get_data2; } void scan_key()//键盘扫描后函数分配 { if(mode==0) key_mode(); if(add==0) key_add(); if(sub==0) key_sub(); if(confirm==0) key_confirm(); } void compare()//比较函数(Control_1 Control_2)[00-正确][11-加][10减] { Control_1=0; Control_2=0; if(V_num<(Get_data-1)) { Control_1=1; Control_2=0; if((Get_data-V_num)>=10) { Control_speed=1; close=1; } else { Control_speed=0; close=0; } } if(V_num>(Get_data+1)) { Control_1=1; Control_2=1; if((V_num-Get_data)>=10) { Control_speed=1; close=1; } else { Control_speed=0; close=0; } } } //中断函数: //定时器中断T0用于消除按键等待 //定时器中断T1用于进入AD转换函数 //-------------------------------------------------------------------- //-------------------------定时器中断服务程序------------------------- //--------------------------定时器0工作方式1-------------------------- //任务: //1:限定进入按键扫描程序的时间间隔,避免在短时间内多次进入键盘扫描而造成误操作 //-------------------------------------------------------------------- void clear_key() interrupt 1 using 1 { times=times+1; if(times==7)//这个数字决定了按键上限速度. { times=0; scan_grant=0;//允许输入 EA=0; } TH0=0x3c; //计数器初值重载 TL0=0xb0; } 第二块单片机(接0832) #include #define uchar unsigned char int i; sbit CS12=P3^0;//控制线 sbit WR12=P3^1;//控制线 sbit led=P2^2;//控制led亮灭 sbit Control_1=P2^1;//变化控制线1 [1变化][0不变] sbit Control_2=P2^0;//加减控制线2 [1增][0减] sbit Control_speed=P2^3;//变化速度控制 uchar out=0;//输出数据 uchar a=0; void delay(int s); void main() { P1=0; WR12=0; CS12=0; Control_1=1; Control_2=1; Control_speed=1; while(1) { for(a=0;a<=20;a++) { delay(1000); } //根据控制信号线决定加减. if(Control_1==1) { if(led==0) {led=1;} else {led=0;} if(Control_2==1) { if(out<=254) if(Control_speed==0) {out++;} if(Control_speed==1) {out=out+10;} } if(Control_2==0) { if(out>=1) if(Control_speed==0) {out--;} if(Control_speed==1) {out=out-10;} } //写操作 WR12=0; CS12=0; P1=out; delay(100); CS12=1; WR12=1; } if(Control_1==0) { led=1; } /*if(out>=255) {out=255;} if(out<=1) {out=0;}*/ } } void delay(int s) { for(i=0;i
本文档为【单片机程序】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑,
图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。