基于单片机的程控电源设计一、项目背景直流稳压源是一种常见的电子仪器,其广泛应用于实验教学和科学研究等领域。
目前使用的直流稳压电源大部分存在诸多缺点,如输出不可调,电压不稳定等等,因而导致实验结果不精确。
本次项目就设计一个基于单片机控制的程控电源。
描述:使用单片机输出PWM去控制电源调压模块以控制电源电压输出,实现步进可调。
二、项目概要分析1、硬件分析:2、软件分析:1)熟悉单片机的原理与应用2)BEEP报警程序设计3)矩阵按键程序设计4)液晶显示驱动程序设计5)产生PWM程序设计6)电压反馈AD采样程序设计三、系统分析1、硬件分析:1)单片机与BEEP、矩阵按键、LM3037液晶显示以及AD采样转换芯片的具体连接。
(单片机控制芯片)(BEEP电路部分)(矩阵按键输入部分)(LM3037液晶显示部分)(TLC549CD A/D转换)2)程控电路部分原理图:2、软件分析:四、程序流程图五、程序设计#include<>#include<>/*--------两个常用的宏定义--------*/#define uint8 unsigned char#define uint16 unsigned int/*-----AD采样时使用的延时定义----*/#define Wait1us {_nop_();}#define Wait2us {Wait1us;Wait1us;}#define Wait4us {Wait2us;Wait2us;}#define Wait10us {Wait4us;Wait4us;Wait2us;} #define Wait20us {Wait10us;Wait10us;}sbit LED_Control = P2^0;/* --------数码管显示函数的声明 -----*/void SEG_Disp(uint8 dat);/*---------扫描按键的说明------------*/void KEY_Scan(void);/*---------延时函数的说明------------*/void Delay_ms(uint16 z);/*---------数码管段选的定义----------*/ sbit HC138_A0 = P1^1;sbit HC138_A1 = P1^2;sbit HC138_A2 = P1^3;/*---------lcd14432的定义----------*/ sbit RS = P1^5;sbit RW = P1^6;sbit EN = P1^7;bit BUSY(void);void Write_cmd(uint8 cmd);void Write_dat(uint8 dat);void LCD14432_Init(void);void HZ_Disp(uint8 *p);void LCD_Test();/*----------AD转换的引脚定义------*/ sbit Tlc549_Dout = P2^3;sbit Tlc549_CS = P2^4;sbit Tlc549_Clock = P2^2;uint8 Read_ADConvert(void);/* ----------T0的函数声明---------*/ void Timer0_Init(void);/*----------PWM的输出端口---------*/sbit PWM0 = P1^2;void PWM_Out(uint8 rate);uint8 key_value=0;;// Write_dat(0x30+temp2);Write_dat('V');// HZ_Disp("8"); //程控电源显示界面// SEG_Disp(temp);KEY_Scan();if(flag==1) //"+"分辨率{rate1 = rate1+2;if(rate1>98)rate1 = 98;flag = 0;}if(flag==2) //"+"分辨率{rate1 = rate1-2;if(rate1<8)rate1 = 8;flag = 0;}// SEG_Disp(count1);}return 0;}/************************************************ 函数名称:void SEG_Disp(uint8 dat)函数功能:数码管的显示函数入口参数:显示0~9出口参数:无调用模块:MAIN************************************************/ void SEG_Disp(uint8 dat){P0 = SEG_data[dat];HC138_A0 = 0;HC138_A1 = 0;HC138_A2 = 0;}void KEY_Scan(void){uint8 temp;P3 = 0xf0; //设置输入输出/*-----------扫描第一行----------*/P3 = 0xfe; //第一行输出 0temp = P3; //读取P3的值temp = temp & 0xf0;//屏蔽高4位,if( temp!= 0xf0) //判断是否有键按下{Delay_ms(100);if( temp!= 0xf0) //判断是否有键按下{switch(temp) //做键值处理{case 0xe0: key_value = 1;break;case 0xd0: key_value = 2;break;case 0xb0: key_value = 3;break;case 0x70: key_value = 4;break;}//有键按下//temp = temp & 0xf0;//判断按键有没有松开,如果按键松开程序继续执行,//如果没有松开,不断读取P3口的值来作为while的判断条件while(temp!=0xf0) //等待松开按键{temp = P3; //读取P3的值temp = temp & 0xf0;//屏蔽高4位,}}}/*-----------扫描第二行----------*/P3 = 0xfd; //第二行输出 0temp = P3; //读取P3的值temp = temp & 0xf0;//屏蔽高4位,if( temp!= 0xf0) //判断是否有键按下{Delay_ms(100);if( temp!= 0xf0) //判断是否有键按下{switch(temp) //做键值处理{case 0xe0: key_value = 5;break;case 0xd0: key_value = 6;break;case 0xb0: key_value = 7;break;case 0x70: key_value = 8;break;}//有键按下//temp = temp & 0xf0;//判断按键有没有松开,如果按键松开程序继续执行,//如果没有松开,不断读取P3口的值来作为while的判断条件while(temp!=0xf0) //等待松开按键{temp = P3; //读取P3的值temp = temp & 0xf0;//屏蔽高4位,}}}/*-----------扫描第三行----------*/P3 = 0xfb; //第二行输出 0temp = P3; //读取P3的值temp = temp & 0xf0;//屏蔽高4位,if( temp!= 0xf0) //判断是否有键按下{Delay_ms(100);if( temp!= 0xf0) //判断是否有键按下{switch(temp) //做键值处理{case 0xe0: key_value = 9;break;case 0xd0: key_value = 0;break;case 0xb0: flag = 1;break; //"+"case 0x70: flag = 2;break; //"-"}//有键按下//temp = temp & 0xf0;//判断按键有没有松开,如果按键松开程序继续执行,//如果没有松开,不断读取P3口的值来作为while的判断条件while(temp!=0xf0) //等待松开按键{temp = P3; //读取P3的值temp = temp & 0xf0;//屏蔽高4位,}}}/*-----------扫描第四行----------*/P3 = 0xf7; //第二行输出 0temp = P3; //读取P3的值temp = temp & 0xf0;//屏蔽高4位,if( temp!= 0xf0) //判断是否有键按下{Delay_ms(100);if( temp!= 0xf0) //判断是否有键按下{switch(temp) //做键值处理case 0xe0: key_value = 3;break;case 0xd0: key_value = 4;break;case 0xb0: key_value = 5;break;case 0x70: key_value = 6;break;}//有键按下//temp = temp & 0xf0;//判断按键有没有松开,如果按键松开程序继续执行,//如果没有松开,不断读取P3口的值来作为while的判断条件while(temp!=0xf0) //等待松开按键{temp = P3; //读取P3的值temp = temp & 0xf0;//屏蔽高4位,}}}}bit BUSY(void){bit Bit;P0 = 0x00;RW = 1;EN = 1;Delay_ms(1);Bit = (bit)(P0 & 0x80); //最高位为忙信号位EN = 0;return Bit;}void Write_cmd(uint8 cmd){// while(BUSY());RS = 0; //写指令RW = 0; //写操作EN = 0; //P0 = cmd; //发送命令Delay_ms(5);EN = 1;P0 = cmd; //发送命令Delay_ms(5);EN = 0; //拉低EN}void Write_dat(uint8 dat){// while(BUSY());RS = 1;RW = 0;EN = 0;P0 = dat;Delay_ms(5);EN = 1;P0 = dat;Delay_ms(5);EN = 0;}void LCD14432_Init(void){_nop_(); //延时1usWrite_cmd(0x30); //使用基本指令集Delay_ms(5);Write_cmd(0x0c); //功能:显示开关ON ,游标OFF,反白OFF Delay_ms(5);Write_cmd(0x01); //清除显示屏幕,把DDRAM 位址计数器调整为"00H"Delay_ms(5);Write_cmd(0x06); //AC自动加1,画面不动// Write_cmd(0x07); //AC自动加1,画面移动_nop_(); //延时1us}void Delay_ms(uint16 z){uint16 x,y;for(x=z;x>0;x--)for(y=124;y>0;y--);}void Timer0_Init(void){TMOD = 0x01; //工作在方式1// TH0 = (65535-50000)/256// TL0 =// TH0 = 0x3C; //定时器初值50ms // TL0 = 0xAF;TH0 = 0xfe; //定时器初值TL0 = 0x3c;EA = 1; //打开总开关ET0 = 1; //开T0中断开关TR0 = 1; //启动定时器}void Timer0_IRQ() interrupt 1{// TH0 = 0x3C; //定时器初值50ms// TL0 = 0xAF;TH0 = 0xfe; //定时器初值TL0 = 0x3c;count++;PWM_Out(rate1);/* if(count==20){count= 0;count1++;if(count1==10){count1 = 0;}}*/}uint8 Read_ADConvert(void){uint8 i=0; //计数脉冲uint8 Convert_value = 0;//保存AD转换的值/*---------------参考时序编写驱动程序-------------*/ Tlc549_Clock = 0; //初始化Tlc549_CS = 1;Wait2us; //延时2USTlc549_CS = 0;Wait2us; //延时2USfor(i=0;i<8;i++) //丢掉前面8个数据{Tlc549_Clock = 1;// Wait2us;Tlc549_Clock = 0;}Tlc549_CS = 1; //准备转换Wait20us; //等待转换结束Wait20us;Tlc549_CS = 0; //准备读取AD数据for(i=0;i<8;i++) //读取数据(下降沿){Tlc549_Clock = 1;Convert_value = Convert_value <<1;if(Tlc549_Dout==1) //根据数据线上得数据,将AD 采样的转换值保存到一个变量中{Convert_value = Convert_value | 0x01;}Tlc549_Clock = 0;}return (Convert_value); }void PWM_Out(uint8 rate) {if(count>99)count=0;if(count<rate)PWM0 = 1;elsePWM0 = 0;}void HZ_Disp(uint8 *p) {while(*p>0){Write_dat(*p);p++;Delay_ms(50);}}void LCD_Test(){Write_cmd(0x01);Delay_ms(5);Write_cmd(0x80);Delay_ms(5);// Write_cmd(0x18);左移HZ_Disp("程控电源- 涉外学院"); //开机界面Write_cmd(0x93);Delay_ms(5);HZ_Disp("X X X 设计");Delay_ms(5000);Write_cmd(0x01);Write_cmd(0x80);HZ_Disp("预设值"); //程控电源显示界面Write_cmd(0x85);HZ_Disp("输出"); //程控电源显示界面Write_cmd(0x90);HZ_Disp("分辨率"); //程控电源显示界面}六、项目总结--------------------------------------------------------------------------------------------------学了些什么,遇到过什么难题,怎么解决的---------------------------------------------------------------------,----------------------------------------------------------------------------------------------------------------------------------------------------------自己搞定-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------随便写些就可以了,你学校不会看的不写也没事呵呵呵---------------------------------------------,----------------------------------------------------------------------------------------------------------------------------------------------------------。