程控电源项目文档.docx
《程控电源项目文档.docx》由会员分享,可在线阅读,更多相关《程控电源项目文档.docx(17页珍藏版)》请在冰点文库上搜索。
![程控电源项目文档.docx](https://file1.bingdoc.com/fileroot1/2023-7/9/d293fcf9-a869-4783-8ed1-816a0beec3f3/d293fcf9-a869-4783-8ed1-816a0beec3f31.gif)
程控电源项目文档
基于单片机的程控电源设计
1、项目背景
直流稳压源是一种常见的电子仪器,其广泛应用于实验教学和科学研究等领域。
目前使用的直流稳压电源大部分存在诸多缺点,如输出不可调,电压不稳定等等,因而导致实验结果不精确。
本次项目就设计一个基于单片机控制的程控电源。
描述:
使用单片机输出PWM去控制电源调压模块以控制电源电压输出,实现步进可调。
项目参数:
1
输入电压8~16V,如果输入电压低于8V或者高于16V,利用BEEP报警,并且关掉PWM的输出
2
输出电压6~14V,如果输出电压低于6V或者高于14V,利用BEEP报警,同样关掉PWM的输出
3
调压分辨率
4
用按键输入电压预设值,然后通过按键的“+”、“-”来步进调节电源的输出,达到预设值允许的范围内
5
通过LM3037(LCD14432)来显示当前的电压预设值,当前电压的输出值以及分辨率
2、项目概要分析
1、硬件分析:
2、软件分析:
1)熟悉单片机的原理与应用
2)BEEP报警程序设计
3)矩阵按键程序设计
4)液晶显示驱动程序设计
5)产生PWM程序设计
6)电压反馈AD采样程序设计
3、系统分析
1、硬件分析:
1)单片机与BEEP、矩阵按键、LM3037液晶显示以及AD采样转换芯片的具体连接。
(单片机控制芯片)
(BEEP电路部分)
(矩阵按键输入部分)
(LM3037液晶显示部分)
(TLC549CDA/D转换)
2)程控电路部分原理图:
2、软件分析:
1)
BEEP报警,P2^2引脚出现低电平,BEEP发出声音。
2)
矩阵按键的扫描,采用逐行扫描模式,扫描每个按键是否按下,并做键值处理。
3)
LM3037液晶的显示,可以采用并行显示或者串行显示,该液晶自带中文字库。
4)
AD549CDA/D转换芯片驱动程序的编写,
5)
定时器程序的编写
6)
外部中断程序的编写
7)
PWM脉宽调制波的产生
4、程序流程图
5、程序设计
#include<>
#include<>
/*--------两个常用的宏定义--------*/
#defineuint8unsignedchar
#defineuint16unsignedint
/*-----AD采样时使用的延时定义----*/
#defineWait1us{_nop_();}
#defineWait2us{Wait1us;Wait1us;}
#defineWait4us{Wait2us;Wait2us;}
#defineWait10us{Wait4us;Wait4us;Wait2us;}
#defineWait20us{Wait10us;Wait10us;}
sbitLED_Control=P2^0;
/*--------数码管显示函数的声明-----*/
voidSEG_Disp(uint8dat);
/*---------扫描按键的说明------------*/
voidKEY_Scan(void);
/*---------延时函数的说明------------*/
voidDelay_ms(uint16z);
/*---------数码管段选的定义----------*/
sbitHC138_A0=P1^1;
sbitHC138_A1=P1^2;
sbitHC138_A2=P1^3;
/*---------lcd14432的定义----------*/
sbitRS=P1^5;
sbitRW=P1^6;
sbitEN=P1^7;
bitBUSY(void);
voidWrite_cmd(uint8cmd);
voidWrite_dat(uint8dat);
voidLCD14432_Init(void);
voidHZ_Disp(uint8*p);
voidLCD_Test();
/*----------AD转换的引脚定义------*/
sbitTlc549_Dout=P2^3;
sbitTlc549_CS=P2^4;
sbitTlc549_Clock=P2^2;
uint8Read_ADConvert(void);
/*----------T0的函数声明---------*/
voidTimer0_Init(void);
/*----------PWM的输出端口---------*/
sbitPWM0=P1^2;
voidPWM_Out(uint8rate);
uint8key_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);
}
return0;
}
/************************************************
函数名称:
voidSEG_Disp(uint8dat)
函数功能:
数码管的显示函数
入口参数:
显示0~9
出口参数:
无
调用模块:
MAIN
************************************************/
voidSEG_Disp(uint8dat)
{
P0=SEG_data[dat];
HC138_A0=0;
HC138_A1=0;
HC138_A2=0;
}
voidKEY_Scan(void)
{
uint8temp;
P3=0xf0;//设置输入输出
/*-----------扫描第一行----------*/
P3=0xfe;//第一行输出0
temp=P3;//读取P3的值
temp=temp&0xf0;//屏蔽高4位,
if(temp!
=0xf0)//判断是否有键按下
{
Delay_ms(100);
if(temp!
=0xf0)//判断是否有键按下
{
switch(temp)//做键值处理
{
case0xe0:
key_value=1;break;
case0xd0:
key_value=2;break;
case0xb0:
key_value=3;break;
case0x70:
key_value=4;break;
}
//有键按下
//temp=temp&0xf0;
//判断按键有没有松开,如果按键松开程序继续执行,
//如果没有松开,不断读取P3口的值来作为while的判断条件
while(temp!
=0xf0)//等待松开按键
{
temp=P3;//读取P3的值
temp=temp&0xf0;//屏蔽高4位,
}
}
}
/*-----------扫描第二行----------*/
P3=0xfd;//第二行输出0
temp=P3;//读取P3的值
temp=temp&0xf0;//屏蔽高4位,
if(temp!
=0xf0)//判断是否有键按下
{
Delay_ms(100);
if(temp!
=0xf0)//判断是否有键按下
{
switch(temp)//做键值处理
{
case0xe0:
key_value=5;break;
case0xd0:
key_value=6;break;
case0xb0:
key_value=7;break;
case0x70:
key_value=8;break;
}
//有键按下
//temp=temp&0xf0;
//判断按键有没有松开,如果按键松开程序继续执行,
//如果没有松开,不断读取P3口的值来作为while的判断条件
while(temp!
=0xf0)//等待松开按键
{
temp=P3;//读取P3的值
temp=temp&0xf0;//屏蔽高4位,
}
}
}
/*-----------扫描第三行----------*/
P3=0xfb;//第二行输出0
temp=P3;//读取P3的值
temp=temp&0xf0;//屏蔽高4位,
if(temp!
=0xf0)//判断是否有键按下
{
Delay_ms(100);
if(temp!
=0xf0)//判断是否有键按下
{
switch(temp)//做键值处理
{
case0xe0:
key_value=9;break;
case0xd0:
key_value=0;break;
case0xb0:
flag=1;break;//"+"
case0x70:
flag=2;break;//"-"
}
//有键按下
//temp=temp&0xf0;
//判断按键有没有松开,如果按键松开程序继续执行,
//如果没有松开,不断读取P3口的值来作为while的判断条件
while(temp!
=0xf0)//等待松开按键
{
temp=P3;//读取P3的值
temp=temp&0xf0;//屏蔽高4位,
}
}
}
/*-----------扫描第四行----------*/
P3=0xf7;//第二行输出0
temp=P3;//读取P3的值
temp=temp&0xf0;//屏蔽高4位,
if(temp!
=0xf0)//判断是否有键按下
{
Delay_ms(100);
if(temp!
=0xf0)//判断是否有键按下
{
switch(temp)//做键值处理
{
case0xe0:
key_value=3;break;
case0xd0:
key_value=4;break;
case0xb0:
key_value=5;break;
case0x70:
key_value=6;break;
}
//有键按下
//temp=temp&0xf0;
//判断按键有没有松开,如果按键松开程序继续执行,
//如果没有松开,不断读取P3口的值来作为while的判断条件
while(temp!
=0xf0)//等待松开按键
{
temp=P3;//读取P3的值
temp=temp&0xf0;//屏蔽高4位,
}
}
}
}
bitBUSY(void)
{
bitBit;
P0=0x00;
RS=0;
RW=1;
EN=1;
Delay_ms
(1);
Bit=(bit)(P0&0x80);//最高位为忙信号位
EN=0;
returnBit;
}
voidWrite_cmd(uint8cmd)
{
//while(BUSY());
RS=0;//写指令
RW=0;//写操作
EN=0;//
P0=cmd;//发送命令
Delay_ms(5);
EN=1;
P0=cmd;//发送命令
Delay_ms(5);
EN=0;//拉低EN
}
voidWrite_dat(uint8dat)
{
//while(BUSY());
RS=1;
RW=0;
EN=0;
P0=dat;
Delay_ms(5);
EN=1;
P0=dat;
Delay_ms(5);
EN=0;
}
voidLCD14432_Init(void)
{
_nop_();//延时1us
Write_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
}
voidDelay_ms(uint16z)
{
uint16x,y;
for(x=z;x>0;x--)
for(y=124;y>0;y--);
}
voidTimer0_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;//启动定时器
}
voidTimer0_IRQ()interrupt1
{
//TH0=0x3C;//定时器初值50ms
//TL0=0xAF;
TH0=0xfe;//定时器初值
TL0=0x3c;
count++;
PWM_Out(rate1);
/*if(count==20)
{
count=0;
count1++;
if(count1==10)
{
count1=0;
}
}*/
}
uint8Read_ADConvert(void)
{
uint8i=0;//计数脉冲
uint8Convert_value=0;//保存AD转换的值
/*---------------参考时序编写驱动程序-------------*/
Tlc549_Clock=0;//初始化
Tlc549_CS=1;
Wait2us;//延时2US
Tlc549_CS=0;
Wait2us;//延时2US
for(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);
}
voidPWM_Out(uint8rate)
{
if(count>99)
count=0;
if(countPWM0=1;
else
PWM0=0;
}
voidHZ_Disp(uint8*p)
{
while(*p>0)
{
Write_dat(*p);
p++;
Delay_ms(50);
}
}
voidLCD_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("XXX设计");
Delay_ms(5000);
Write_cmd(0x01);
Write_cmd(0x80);
HZ_Disp("预设值");//程控电源显示界面
Write_cmd(0x85);
HZ_Disp("输出");//程控电源显示界面
Write_cmd(0x90);
HZ_Disp("分辨率");//程控电源显示界面
}
6、项目总结
--------------------------------------------------------------------------------------------------学了些什么,遇到过什么难题,怎么解决的---------------------------------------------------------------------,----------------------------------------------------------------------------------------------------------------------------------------------------------自己搞定-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------随便写些就可以了,你学校不会看的
不写也没事呵呵呵---------------------------------------------,----------------------------------------------------------------------------------------------------------------------------------------------------------