【51单片机设计】基于51单片机的可调电源设计(实物+资料+论文) 线性调压电源

1、实现功能


1、通过按键可以设置输出电压0-12V调节,步进值0.1V;
2、使用运放搭建放大电路,测量输出电流
3、使用ADC芯片采集输出电压、输出电流
4、通过LCD液晶显示输出电压、电流数据
5、电压控制精度0.01v

可增加的功能:
过流保护、APP控制、显示等

主要元器件:
  51单片机、11.0592M晶振,10pf电容*2,LCD1602,L7805稳压芯片,L7812稳压芯片,SVD9Z24NT PMOS管,LM358运放、TLC5615 DAC芯片、ADC0832 ADC芯片。


2、实物

在这里插入图片描述

3、代码

   单片机代码采用C语言,软件是keil5

/****************主函数**********************/
//宏定义
#define uint unsigned int
#define uchar unsigned char
//头函数
#include <reg52.h>	
#include <intrins.h>
#include <stdio.h>
#include "usart.h"
#define dat P0

sbit beep   =P2^0;		//蜂鸣器驱动引脚

/***************************************************************
* 名称 : delay_ms()
* 功能 : 延时1ms函数
* 输入 : q
* 输出 : 无
****************************************************************/
void delay_ms(unsigned int q)
{
	unsigned int i,j;
	for(i=0;i<q;i++)
		for(j=0;j<120;j++);
}

sbit K1=P3^3;
sbit K2=P3^4;
sbit K3=P3^5;

unsigned char Key_long_Scan()				//按键扫描
{
	static unsigned int key_up,key_num,key_long_time,key_return;		//松手检测
	key_return = 0;
	if(((K1==0)||(K2==0)||(K3==0))&&(key_up==1) )  //按键按下,且第一次按下
	{
		key_up=0;
		delay_ms(10);
		if(K1==0)
			key_num = 1;
		else if(K2==0)
			key_num = 2;
		else if(K3==0)
			key_num = 3;
	}
	else if((K1==0)||(K2==0)||(K3==0))  //只按键是否按下
	{
		delay_ms(10);	//软件消抖
		if(key_long_time++>30)
		{
			if(K1==0)
				key_num=4;
			if(K2==0)
				key_num=5;
			if(K3==0)
				key_num=6;
			key_long_time=30;
			key_return = key_num;
			key_num = 0;
		}
	}
	else if((K1==1)&&(K2==1)&&(K3==1))
	{
		key_long_time = 0;
		key_return = key_num;
		key_num = 0;
		key_up=1;
	}
	return key_return;
}
//LCD1602显示定义
sbit lcd1602_rs=P2^5;			//读/写数据选择引脚
sbit lcd1602_rw=P2^6;			//片选 0 有效
sbit lcd1602_en=P2^7;  		//数据传输使能引脚
//函数  delay(unsigned char z)
//功能能  延时
void lcd1602_delay(unsigned int z)
{
	unsigned int a,b;
	for(a=z;z>0;z--)
	for(b=110;b>0;b--);	
}
void write_com(unsigned char com)  //写命令
{
	lcd1602_rs=0;
  dat=com;
	lcd1602_en=0;
	lcd1602_delay(1);
	lcd1602_en=1;
	lcd1602_delay(1);
	lcd1602_en=0;
}
void write_date(unsigned char date)//写数据
{	
	dat=date;
	lcd1602_rs=1;
	lcd1602_en=0;
	lcd1602_delay(1);
	lcd1602_en=1;
	lcd1602_delay(1);
	lcd1602_en=0;
}
void lcd1602_init()// 1602初始化
{	
	lcd1602_rw=0;
	lcd1602_en=0;
	write_com(0x38);//设置1602显示模式为5*7点阵
	lcd1602_delay(1);
	write_com(0x01);//清屏	
	lcd1602_delay(1);		  				
	write_com(0x0c);//开显示,不显示光标,光标不闪烁
	lcd1602_delay(1);	  	
  write_com(0x06);//设置当读或写一个字符后,地址指针加一,且光标加一	
	lcd1602_delay(1);
}

void lcd1602_show_str(unsigned char x,unsigned char  *s)// 1602显示字符串
{ 
	write_com(x);//设置显示位置
	while(*s != '\0')
		write_date(*s++);
}

//DAC定义
sbit  CS_5615=P1^4;		 //定义片选信号IO口 
sbit CLK_5615=P1^5;		 //定义时钟信号IO口 
sbit DAT_5615=P1^6;		 //定义数据输入IO口 
void tlc_5615(uint buf)			 //DA输出
{
	uint a,c;					 //定义变量
	c=buf;    					 //要输出的数据赋值
  CS_5615=0; 					 //引脚拉低
	for(a=16;a>0;a--)			 //循环16次
	{
         DAT_5615=c>>15;      	 //把数据串行输入进da芯片(把数据右移15位得到最高位数据,赋值给数据脚)
         c=c<<1;				 //将数据左移一位,下次循环时就是传输第二位数据了
         CLK_5615=1;			 //拉高
         CLK_5615=0;	         //拉低
    }
	CLK_5615=1;
	CLK_5615=0;
	CLK_5615=1;
	CLK_5615=0;
	CS_5615=1;
}

//ACD定义管脚声明
sbit CS     =P1^2;		//CS定义脚, 连接ADC0832CS脚
sbit SCL    =P1^0;		//SCL定义脚,连接ADC0832CLK脚
sbit DO     =P1^1;		//DO定义脚,连接ADC0832DAT脚
/***********读数模转换数据********************************************************/	
//请先了解ADC0832模数转换的串行协议,再来读本函数,主要是对应时序图来理解,本函数是模拟0832的串行协议进行的
unsigned char ad0832read(bit SGL,bit ODD)
{
	unsigned char i=0,value=0,value1=0;		
	SCL=0;
	DO=1;
	CS=0;		//开始
	SCL=1;	//第一个上升沿	
	SCL=0;
	DO=SGL;
	SCL=1;  	//第二个上升沿
	SCL=0;
	DO=ODD;
	SCL=1;	    //第三个上升沿
	SCL=0;	    //第三个下降沿
	DO=1;
	for(i=0;i<8;i++)
	{
		SCL=1;
		SCL=0; //开始从第四个下降沿接收数据
		value<<=1;
		if(DO)
			value++;						
	}
	for(i=0;i<8;i++)
	{			//接收校验数据
		value1>>=1;
		if(DO)
			value1+=0x80;
		SCL=1;
		SCL=0;
	}
	CS=1;
	SCL=1;	
	if(value==value1)				//与校验数据比较,正确就返回数据,否则返回0	
		return value;
	return 0;
}




unsigned char str[20];
unsigned char key;
float iout;
float vout;
int vset;
unsigned char out_flag;   //按键开关输出电压
unsigned char set_mode; //模式
#define vstep 	8  			//每0.1v对应DAC数值为8
#define vmax  	960 			//
#define vmin  	0  				//

void get_iout(void)//0.01A
{
	unsigned char adc;
	adc = ad0832read(1,1);
	iout= adc*0.017825;   //17.825mA/div  (adc*5/255)/1.1*1000 //放大11倍 mV
}
void get_vout(void)//0.1V
{
//	ad0832read(1,0);
//	vout = ad0832read(1,0)*5*11/255;
	vout = vset/80.0f;//0-12.0;
}
/****************主函数**********************/
void main()
{
	char time_cnt=10;
	delay_ms(100);		//LCD1602初始化需要上电延时一段时间
	lcd1602_init();   //LCD1602初始化
	while(1)	   			//循环
	{
		delay_ms(10);
		
		if(time_cnt++>10)
		{
			time_cnt = 0;
			tlc_5615(vset);				//设定输出电压值
			get_vout();						//获取电压
			get_iout();						//获取电流
			sprintf(str,"V:%04.1fV  ",vout);//格式化数据
			lcd1602_show_str(0x80,str);  		//显示电压
			sprintf(str,"I:%04.2fA    ",iout);	//格式化数据
			lcd1602_show_str(0xC0,str);  		//显示电流
		}
		if(iout>1.0)  //过流保护
		{
			vset = 0;
		}
		key=Key_long_Scan(); 						//按键获取
		if(key>0)time_cnt=10;
		if(key == 1){										//输出开关
			vset = vmax/2;
//			out_flag = !out_flag;
//			set_mode = !set_mode;
		}
		if(key == 2){ //输出电压加
			vset+=vstep;
			if(vset>vmax)
				vset = vmax;
		}
		if(key == 3){ //输出电压减
			vset-=vstep;
			if(vset<vmin)
				vset = 0;
		}
		if(key == 5){ //输出电压加
			vset+=vstep;
			if(vset>vmax)
				vset = vmax;
		}
		if(key == 6){ //输出电压减
			vset-=vstep;
			if(vset<vmin)
				vset = 0;
		}
	}
}


4、原理图/PCB

  原理图和PCB都使用立创EDA绘制,对新手较为友好。可以导出为AD格式的文件
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

5、论文

  章节安排大致分为以下几个部分。第一章作为课题的绪论部分,提出了此课题的研究背景以及研究意义,对数控稳压可调电源的国内外研究现状,阐述了此次课题的主要研究内容。第二章是系统设计的总体方案部分,分析系统设计过程中相应的功能需求提出总体设计框架。第三章是硬件电路设计,分别介绍了单片机最小系统、可调输出电路、整Wi-Fi通信电路、电压检测电路等硬件设计原理及其对应的电路设计。第四章是软件设计,对过主程序、ADC程序、DAC程序等进行论述。第五章是系统测试,对实物的制作与调试,功能测试等展开论述。
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值