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程序等进行论述。第五章是系统测试,对实物的制作与调试,功能测试等展开论述。