基于IAP15单片机的BUCKD电路代码
/KMUST**********
- Project Name : SMPS(Switching Mode Power Supply)
- Description : 适用于STC15F2Kxxxx系列单片机,频率20M
-
4路AD分别用于输入输出电压电流的采样
-
显示用LCD1602,显示输入输出电压电流
-
按键4个,用于设定输出值,
- Author : lidy
- Version : V1.0
- Date : 2017.05.26
*******************************************************************************/
#include “STC15F2K60S2.h”
#define uchar unsigned char
#define uint unsigned int
#define _KEY_UP 0x0b //1011
#define _KEY_DWN 0x07 //0111
#define _KEY_SET 0x0d //1101
#define _KEY_OK 0x0e ///1110
#define LCD_DAT P0
sbit LCD_RS = P2^7;
sbit LCD_RW = P2^6;
sbit LCD_EN = P2^5;
sbit TEST_PORT = P4^5;
bit ADC_CtrlFlag,UpdateDisFlag,KeyFlag,SetFlag;
uchar KeyValue,SetUnit;
uchar KeyTime,BaseTime,DispTime;
uchar AD_Channel,AD_SampleNum,AD_ChannelNum,AD_TimeNum;
uint VoltageIn,VoltageOut,CurrentIn,CurrentOut,VoltageSet,CurrentSet;
uint xdata AD_Value[3][10];
uchar xdata VoltageDis[]={“Ui 99.9 Uo 9.99”};
uchar xdata CurrentDis[]={“Ii 9.99 Io 9.99”};
uchar code AD_ChannelTab[]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x11,0x01,0x10,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x12,0x02,0x10,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x13,0x03,0x10};
bit CheckKey(void);
void UpdateAllDis(void);
void InitSystem(void);
void LCD_Init(void);
void LCD_WriteString(uchar x,uchar y,uchar pStr);
void AlignGroup(uint pdat, uchar num);
void DealControl(void);
void SystemTimer(void);
void SetDisplay(void);
void LCD_WriteCmd(uchar cmd);
/*******************************************************************************
主程序
/
void main(void)
{
InitSystem();
VoltageSet=500;
SetFlag=1;
UpdateDisFlag=1;
while(1)
{
if(CheckKey())
{
switch(KeyValue)
{
case _KEY_UP:
if(SetFlag)
{
VoltageSet+=SetUnit;
UpdateDisFlag=1;
}
break;
case _KEY_DWN:
if(SetFlag)
{
VoltageSet-=SetUnit;
UpdateDisFlag=1;
}
break;
case _KEY_SET:
if(SetFlag)
{
if(SetUnit==1)
{
SetUnit=10;
}
else
{
SetUnit=1;
}
}
else
{
LCD_WriteCmd(0x01);
SetUnit=10;
SetFlag=1;
}
UpdateDisFlag=1;
break;
case _KEY_OK:
SetFlag=0;
LCD_WriteString(0,0,VoltageDis);
LCD_WriteString(0,1,CurrentDis);
break;
default:
break;
}
KeyFlag = 0;
}
if(SetFlag)
{
if(UpdateDisFlag)
{
UpdateDisFlag=0;
SetDisplay();
}
}
else
{
if(DispTime>250)
{
if(VoltageIn>999)
{
VoltageIn=999;
}
if(VoltageOut>999)
{
VoltageOut=999;
}
if(CurrentIn>999)
{
CurrentIn=999;
}
if(CurrentOut>999)
{
CurrentOut=999;
}
UpdateAllDis( );
}
}
SystemTimer();
}
}
/
更新显示
/
void UpdateAllDis( )
{
VoltageDis[6]=0x30+VoltageIn%10;
VoltageDis[4]=0x30+(VoltageIn%100)/10;
VoltageDis[3]=0x30+VoltageIn/100;
VoltageDis[15]=0x30+VoltageOut%10;
VoltageDis[14]=0x30+(VoltageOut%100)/10;
VoltageDis[12]=0x30+VoltageOut/100;
CurrentDis[6]=0x30+CurrentIn%10;
CurrentDis[5]=0x30+(CurrentIn%100)/10;
CurrentDis[3]=0x30+CurrentIn/100;
CurrentDis[15]=0x30+CurrentOut%10;
CurrentDis[14]=0x30+(CurrentOut%100)/10;
CurrentDis[12]=0x30+CurrentOut/100;
LCD_WriteString(0,0,VoltageDis);
LCD_WriteString(0,1,CurrentDis);
}
/
设置状态显示
*/
void SetDisplay()
{
uchar VoltageSetDis[]={“Uo 9.99”};
uchar AccuracySetDis[]={" 1 "};
LCD_WriteCmd(0x02);
VoltageSetDis[3]=‘0’+VoltageSet/100;
VoltageSetDis[5]=‘0’+(VoltageSet%100)/10;
VoltageSetDis[6]=‘0’+VoltageSet%10;
LCD_WriteString(5,0,VoltageSetDis);
if(SetUnit==1)
{
AccuracySetDis[4]=’ ';
LCD_WriteString(5,1,AccuracySetDis);
}
else
{
AccuracySetDis[4]=‘0’;
LCD_WriteString(5,1,AccuracySetDis);
}
}
/
按键检测
/
bit CheckKey( )
{
uchar KeyTmp;
KeyTmp=(P1&0xf0);
KeyTmp=KeyTmp>>4;
KeyFlag = 0;
if(KeyTmp!=0x0f)
{
if((KeyTime>30)&&(KeyValue!=KeyTmp))
{
KeyValue=KeyTmp;
KeyFlag=1;
}
}
else
{
KeyTime=0;
KeyValue=0x00;
}
return KeyFlag;
}
/
定时器中断 100us中断一次
*******************************************************************************/
void Timer1ISR() interrupt 3
{
BaseTime++;
AD_Value[AD_TimeNum/10][AD_TimeNum%10]=(ADC_RES<<8)|ADC_RESL;
AD_TimeNum++;
if(AD_TimeNum>=30)
{
AD_TimeNum=0x00;
VoltageIn=AD_Value[0][8];
CurrentIn=AD_Value[1][8];
CurrentOut=AD_Value[2][8];
}
AD_Channel=AD_ChannelTab[AD_TimeNum];
if(AD_Channel>3)
{
ADC_CONTR=ADC_CONTR&0xf8; //通道切换
ADC_CONTR=ADC_CONTR|(AD_Channel&0x03);
if(AD_Channel&0x03)
{
AlignGroup(AD_Value[AD_TimeNum/10],7);
VoltageOut=AD_Value[AD_TimeNum/10][3];
DealControl();
}
}
ADC_CONTR|=0x08; //启动
// TEST_PORT = !TEST_PORT;
}
/*******************************************************************************
时基2ms
/
void SystemTimer(void)
{
if(BaseTime>20)
{
BaseTime=0x00;
KeyTime++;
DispTime++;
}
}
/
系统初始化
*******************************************************************************/
void InitSystem(void)
{
P0M1=0x00;
P0M0=0xff;
P2M1=0x00;
P2M0=0xff;
AUXR = 0x40;
TMOD = 0x01;
TH1 = 0xf8;
TL1 = 0x30;
P1ASF = 0x0f;
ADC_RES = 0x00;
ADC_RESL = 0x00;
ADC_CONTR= 0xe8;
CLK_DIV= 0x20;
AUXR1=0x10; //P3.5-CCP0_2
CCON = 0;
CL = 0;
CH = 0;
CMOD = 0x08;
PCA_PWM0 = 0x00;
CCAP0H = 0x80;
CCAP0L = 0x20;
CCAPM0 = 0x42;
CR =1;
LCD_Init( );
TR1 = 1;
ET1 = 1;
EA = 1;
}
/*******************************************************************************
100us演示
/
void delay_100us(uint cnt)
{
uint i;
for( ;cnt!=0;cnt–)
for (i=0;i<135;i++);
}
/
向LCD写命令
/
void LCD_WriteCmd(uchar cmd)
{
LCD_EN=0;
LCD_RS=0;
LCD_RW=0;
LCD_DAT=cmd;
LCD_EN=1;
delay_100us(20);
LCD_EN=0;
}
/
向LCD写数据
/
void LCD_WriteDat(uchar dat)
{
LCD_EN=0;
LCD_RS=1;
LCD_RW=0;
LCD_DAT=dat;
LCD_EN=1;
delay_100us(1);
LCD_EN=0;
}
/
LCD初始化
/
void LCD_Init(void)
{
LCD_WriteCmd(0x38); //8位数据总线,2行显示,57点阵
LCD_WriteCmd(0x0c); //显示开,无光标,不闪烁
LCD_WriteCmd(0x06); //写入新数据后光标右移
LCD_WriteCmd(0x01); //清除显示屏
}
/*
LCD显示字符串
*/
void LCD_WriteString(uchar x,uchar y,uchar pStr)
{
if (y <= 1)
{
LCD_WriteCmd(0x80+y0x40 + x);
}
while (pStr)
{
LCD_WriteDat( pStr);
pStr++;
}
}
/
数据排序
/
void AlignGroup(uint pdat, uchar num)
{
uchar i,j;
uint tmp;
for(i=0;i<num-1;i++)
{
for(j=num-1;j>i;j–)
{
if((pdat+j)<(pdat+j-1))
{
tmp = (pdat+j);
(pdat+j)=(pdat+j-1);
(pdat+j-1)=tmp;
}
}
}
}
/
输出控制
*******************************************************************************/
void DealControl(void)
{
if(SetFlag)
{
CCAP0H=230;
}
else
{
if(VoltageOut<VoltageSet)
{
if(CCAP0H>20)
{
CCAP0H–;
}
}
else
{
if(CCAP0H<255)
{
CCAP0H++;
}
}
}
}