基于STC12系列单片机的串联型开关电源设计与实现.docx

上传人:b****7 文档编号:9731927 上传时间:2023-02-06 格式:DOCX 页数:26 大小:198.16KB
下载 相关 举报
基于STC12系列单片机的串联型开关电源设计与实现.docx_第1页
第1页 / 共26页
基于STC12系列单片机的串联型开关电源设计与实现.docx_第2页
第2页 / 共26页
基于STC12系列单片机的串联型开关电源设计与实现.docx_第3页
第3页 / 共26页
基于STC12系列单片机的串联型开关电源设计与实现.docx_第4页
第4页 / 共26页
基于STC12系列单片机的串联型开关电源设计与实现.docx_第5页
第5页 / 共26页
点击查看更多>>
下载资源
资源描述

基于STC12系列单片机的串联型开关电源设计与实现.docx

《基于STC12系列单片机的串联型开关电源设计与实现.docx》由会员分享,可在线阅读,更多相关《基于STC12系列单片机的串联型开关电源设计与实现.docx(26页珍藏版)》请在冰豆网上搜索。

基于STC12系列单片机的串联型开关电源设计与实现.docx

基于STC12系列单片机的串联型开关电源设计与实现

单片机及模数综合系统设计

课题名称:

基于STC12系列单片机的串联型开关电源设计与实现

--单片机控制部分

 

学院

专业

班级

学号

姓名

 

实验目的:

通过编程显示开关电源的输入输出电压。

实验内容:

程序功能主要包括如下几个部分:

1、键盘输入数据部分;

2、数码管数据显示部分;

3、控制PWM输出部分;

4、AD转换部分(完成万用表的功能,即测量开关电源输出电

压);

5、难点:

闭环控制算法。

即通过AD采集数据控制PWM输出,

PWM控制开关电源输出,以达到稳定。

即让开关电源输出电压

稳定在用户键盘设定的电压

设计思路:

程序主要包括:

A/D转换部分,PWM部分,键盘输入设置电压部分,数码管显示部分。

 

(1)主程序

先进行数码管初始显示,然后通过比较获取电压与预设电压之间的误差,调节占空比,减小误差,得到更准确的数值。

#include"Include.h"

voidMain_System_Init(void)

{

//相关资源初始化

PWM_Drv_Init();

}

voidmain(void)

{

unsignedinti=0x00;

externunsignedintADC_Result[8];

ucharc=128;

//charxdataDigitBit[8]={0x31,0x38,'.',0x35,0x35,0x00};

//charxdataDispCharBuf[12]={0x00};

externfloatsetkey;

externfloatb;

for(i=0x00;i<3000;i++);//开机延时

Main_System_Init();//系统相关资源初始

while

(1)

{

PWM0_Drv_SetDuty(c);//设置初始占空比

keysetV();//调用键盘模块程序,

if(b

{

for(;b

{PWM0_Drv_SetDuty(c);//设置占空比

ADC_Drv_Service();//ADC中断函数调用,处理ADC结果b=ADC_Result[ADC_channel]*5.0/1024;

ADC_Drv_Demo();//显示获取的电压值

keysetV();

}

}

elseif(b>setkey)

{for(;b>setkey;c++)

{PWM0_Drv_SetDuty(c);

ADC_Drv_Service();

b=ADC_Result[ADC_channel]*5.0/1024;

ADC_Drv_Demo();

keysetV();

}

}

elseif(b==setkey)

{PWM0_Drv_SetDuty(c);

ADC_Drv_Service();

b=ADC_Result[ADC_channel]*5.0/1024;

ADC_Drv_Demo();

keysetV();

}

}

}

 

头文件如下:

#ifndef__INCLUDE_H__

#define__INCLUDE_H__

#defineTRUE1

#defineFALSE0

#include"stc12c5a60s2.h"

#include"math.h"

#include"stdio.h"

#include"intrins.h"

#include"KeyBoard_Drv.h"

#include"PWM_Drv.h"

#include"ADC_Drv.h"

#include"SMG.h"

#include"stdlib.h"

#defineucharunsignedchar

#endif

(2)键盘设置输入电压部分

预置初始输入电压为3V。

K1按下之后电压减少0.1V;K2按下之后电压增加0.1V;程序当中引用了郭老师的按键消抖程序。

电压最大为4.1V最小为1.1V。

键盘部分程序如下:

include"Include.h"

/************************公有变量定义区****************************/

sbitk1=P2^4;

sbitk2=P2^5;

sbitk3=P2^6;

sbitk4=P2^7;

floatsetkey;

/*********************************************************************

*函数名:

key

*函数功能:

k1控制电压加0.1;k2控制电压减0.1

*函数参数:

*返回类型:

*********************************************************************/

voidkeysetv()

{

staticfloata=3.0;

if(k1==0)

{

delay(200);

if(k1==0)

a=a+0.1;

while(!

k1);

delay(200);

while(!

k1);

}

if(k2==0)

{

delay(200);

if(k2==0)

a=a-0.1;

while(!

k2);

delay(200);

while(!

k2);

}

if(a>4.1)a=1.1;

if(a<1.1)a=4.1;

setkey=a;

show1(a*10);

}

键盘头文件如下:

#ifndef__KEYBOARD_DRV_H__

#define__KEYBOARD_DRV_H__

externvoidkeysetv();

#endif

 

(3)数码管显示部分

实验采用的是4个共阳级数码管。

前两位显示获取的电压,后两位显示的是设置的电压。

数码管部分给获取与预置的电压都预先放大了10倍,然后分别除以10进行取整取余运算,如何分别显示;由于小数点一直存在,所以我选择了小数点常亮语句。

程序如下:

#include"include.h"

sbitSMG_q=P3^0;//定义数码管阳级控制脚(千位)

sbitSMG_b=P3^1;//定义数码管阳级控制脚(百位)

sbitSMG_s=P3^2;//定义数码管阳级控制脚(十位)

sbitSMG_g=P3^3;//定义数码管阳级控制脚(个位)

unsignedcharcodeTab[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};

unsignedintk;

unsignedintj;

unsignedintn;

/*********************************************************************

*函数名:

delay

*函数功能:

快速动态扫描

*函数参数:

*返回类型:

*说明:

*********************************************************************/

voiddelay(unsignedintn)

{

unsignedinta,b;

unsignedintm;

for(m=0;m

{

{for(b=12;b>0;b--)//一毫秒

for(a=29;a>0;a--);

}

}

}

 

/*********************************************************************

*函数名:

show1

*函数功能:

后2位数的数码显示器显示设置电压

*函数参数:

k

*返回类型:

*说明:

*********************************************************************/

voidshow1(unsignedintk)//后两位数码管显示数字k即设定的电压值

{

SMG_s=0;//P1.2引脚输出低电平,数码管十位接通

P0=Tab[k/10];//显示k十位上的数

delay(5);

SMG_s=1;

SMG_g=0;//P1.3引脚输出低电平,数码管个位接通

P0=Tab[k%10];//显示k个位上的数

delay(5);

SMG_g=1;

SMG_s=0;

P0=0x7f;

delay(5);

SMG_s=1;

}

/*********************************************************************

*函数名:

show2

*函数功能:

前2位数的数码显示器显示获取电压(只用于ADC_Drv_Demo函数)

*函数参数:

j

*返回类型:

*说明:

*********************************************************************/

voidshow2(unsignedintj)//前两位数码管显示数字j即获取的电压值

{SMG_q=0;//P1.0引脚输出低电平,数码管千位接通

P0=Tab[j/10];//显示j十位上的数

delay(5);

SMG_q=1;

SMG_b=0;//P1.1引脚输出低电平,数码管百位接通

P0=Tab[j%10];//显示j个位上的数

delay(5);

SMG_b=1;//关闭所有显示器

SMG_q=0;

P0=0x7f;

delay(5);

SMG_q=1;

}

数码管头文件如下:

#ifndef__SMG_H__

#define__SMG_H__

externunsignedchari;

externunsignedintx;

externvoiddelay(unsignedintn);

externvoidshow1(unsignedintk);

externvoidshow2(unsignedintj);

#endif

 

(4)A/D转换

与A/D转换相关的寄存器

*1.P1ASF:

P1口模拟功能控制寄存器(只能写,不能读;不可位寻址)

*B7B6B5B4B3B2B1B0

*P17ASFP16ASFP15ASFP14ASFP13ASFP12ASFP11ASFP10ASF

*P1nASF:

=1时,P1.n作为模拟功能A/D使用;=0时,P1.n作为普通I/O口

*

*2.ADC_CONTR:

ADC控制寄存器(不可位寻址)

*!

!

建议使用MOV赋值语句,不要用‘与’和‘或’语句

*B7B6B5B4B3B2B1B0

*ADC_POWERSPEED1SPEED0ADC_FLAGADC_STARTCHS2CHS1CHS0

*ADC_POWER:

ADC电源控制位。

0关闭;1开启

*SPEED1,SPEED0:

ADC转换速度控制位

*SPEED1SPEED0A/D转换所需时间

*1190个时钟转换一次,SYSClk=21MHz,AD速度可达250KHz

*10180个时钟转换一次

*01360个时钟转换一次

*00540个时钟转换一次

*ADC_FLAG:

ADC转换结束标志位。

完成时置1,由软件清0!

*ADC_START:

ADC转换启动控制位,置1时开始转换,转换结束后为0

*CHS2/CHS1/CHS0:

模拟输入通道选择

*CHS2CHS1CHS0AnalogChannelSelect

*000选择P1.0作为A/D输入来用

*001选择P1.1作为A/D输入来用

*010选择P1.2作为A/D输入来用

*011选择P1.3作为A/D输入来用

*100选择P1.4作为A/D输入来用

*101选择P1.5作为A/D输入来用

*110选择P1.6作为A/D输入来用

*111选择作为A/D输入来用

*

*!

注意:

由于是2套时钟,所以设置ADC_CONTR控制寄存器后,要加4个空操作

*作延时才可以正确读到ADC_CONTR寄存器的值!

*

*3.ADC_RES:

A/D转换结果高位寄存器;ADC_RESL:

A/D转换结果低位寄存器

*调整AUXR1寄存器(不可位寻址)中的第二位ADRJ控制数据存放格式。

*ADRJ=0时,(ADC_RES[7:

0],ADC_RESL[1:

0])

*取10位:

ADC'Result=1024*Vin/Vcc

*取8位:

ADC'Result=256*Vin/Vcc

*

*ADRJ=1时,(ADC_RES[1:

0],ADC_RESL[7:

0])

*取10位:

ADC'Result=1024*Vin/Vcc

*取8位:

ADC'Result=256*Vin/Vcc

*

*4.中断寄存器:

IE——EA,EADC(1允许ADC中断,0禁止)

*

*5.中断优先级寄存器IP、IP2和IPH、IP2H

*IP、IP2中的中断优先控制位分别对应IE各中断允许位

*IPH、IPH2中的中断优先控制位分别对应IE2各中断允许位

*IPH:

中断优先级控制寄存器高(不可位寻址)

*B7B6B5B4B3B2B1B0

*PPCAHPLVDHPADCHPSHPT1HPX1HPT0HPX0H

*IP:

中断优先级控制寄存器低(可位寻址)

*B7B6B5B4B3B2B1B0

*PPCAPLVDPADCPSPT1PX1PT0PX0

*

*IP2H:

中断优先级控制寄存器2高(不可位寻址)

*B7B6B5B4B3B2B1B0

*------PSPIHPS2H

*IP2:

中断优先级控制寄存器2低(不可位寻址)

*B7B6B5B4B3B2B1B0

*------PSPIPS2

*PADCHPADC优先级

*00最低优先级(优先级0)

*01较低优先级(优先级1)

*10较高优先级(优先级2)

*11最高优先级(优先级3)

A/D实验程序:

#include"Include.h"

/************************公有变量定义区****************************/

unsignedcharADC_channel=7;//选中哪一个通道的变量(范围0--7)

unsignedintADC_Result[8]=0;//保存ADC转换结果

bitADC_Finish_Flag=FALSE;//ADC完成标志

floatb;

 

/*********************************************************************

*函数名:

ADC_Drv_StartCh

*函数功能:

*函数参数:

ChNo,P1.N作为转换通道来用,范围为0~7

*返回类型:

void

*说明:

*********************************************************************/

voidADC_Drv_StartCh(unsignedcharChNo)

{

unsignedintDelay=0x00;

P1ASF=P1ASF|(0x01<

ADC_RES=0;//Clearpreviousresult

ADC_CONTR=ADC_POWER|ADC_SPEEDLL|ADC_START|ChNo;//

for(Delay=0x00;Delay<500;Delay++);//ADCpower-onanddelay

IE=0xA0|IE;

EA=1;

}

 

/*********************************************************************

*函数名:

ADC_Drv_Service

*函数功能:

ADC中断函数调用,处理ADC结果

*函数参数:

*返回类型:

void

*说明:

*********************************************************************/

voidADC_Drv_Service(void)

{

ADC_Result[ADC_channel]=ADC_RES;

ADC_Result[ADC_channel]=(ADC_Result[ADC_channel]<<2)|ADC_RESL;

ADC_Finish_Flag=TRUE;

}

 

/*********************************************************************

*函数名:

ADCDrv_Demo

*函数功能:

显示获取的电压值

*函数参数:

*返回类型:

void

*说明:

*********************************************************************/

voidADC_Drv_Demo(void)

{

if(ADC_Finish_Flag==TRUE)

{

ADC_Finish_Flag=FALSE;

ADC_Drv_StartCh(ADC_channel);

show2((ADC_Result[ADC_channel]*5.0/1024)*10);

b=ADC_Result[ADC_channel]*5.0/1024;

}

}

A/D头文件如下:

#ifndef__ADC_DRV_H__

#define__ADC_DRV_H__

externunsignedcharADC_channel;//选中哪一个通道的变量

externbitADC_Finish_Flag;//ADC完成标志

externvoidADC_Drv_InitCh(unsignedcharChNo);

externvoidADC_Drv_StartCh(unsignedcharChNo);

externvoidADC_Drv_Service(void);

externvoidADC_Drv_Demo(void);

#endif

 

(5)PWM部分

*1.PCA工作模式寄存器:

CMOD

*CMOD:

(不可位寻址)

*B7B6B5B4B3B2B1B0

*CIDL---CPS2CPS1CPS0ECF

*CIDL:

空闲模式下是否停止PCA计数的控制位。

*当CIDL=1时,空闲模式下PCA计数器继续工作;

*当CIDL=0时,空闲模式下PCA计数器停止工作。

*CPS2、CPS1、CPS0:

PCA计数脉冲源选择控制位。

如下表:

*CPS2CPS1CPS0选择PCA/PWM时钟源输入

*0000,SYSclk/12

*0011,SYSclk/2

*0102,定时器0的溢出脉冲。

通过改变定时器0的溢出率,

*可以实现可调频率的PWM输出

*0113,ECI/P1.2(P1.4)脚输入的外部时钟(Vmax=SYSclk/2)

*1004,SYSclk

*1015,SYSclk/4

*1106,SYSclk/6

*1117,SYSclk/8

*ECF:

PCA计数溢出中断使能位。

*当ECF=0时,禁止寄存器CCON中CF位的中断;

*当ECF=1时,允许寄存器CCON中CF位的中断.

*

*2.PCA控制寄存器:

CCON

*CCON:

(可位寻址)

*B7B6B5B4B3B2B1B0

*CFCR----CCF1CCF0

*CF:

PCA计数器阵列溢出标志位。

当PCA计数器溢出时,CF由硬件置位。

如果

*CMOD寄存器的ECF位置位,测CF标志可用来产生中断。

CF位可通过硬件或软件

*置位,但必须通过软件清零。

*CR:

PCA计数器阵列运行控制位。

该位通过软件置位,用来启动PCA计数器阵列

*计数。

该位通过软件清零,用来关闭PCA计数器。

*CCF1:

PCA模块1中断标志位。

当出现匹配或捕获的时该位由硬件置位。

该位必

*须由软件清零。

*CCF0:

PCA模块0中断标志位。

当出现匹配或捕获的时该位由硬件置位。

该位必

*须由软件清零。

*

*3.PCA比较/捕获寄存器CCAPM0和CCAPM1

*PCA模块0的比较/捕获寄存器的格式如下:

*CCAPM0:

PCA模块0的比较/捕获寄存器(不可位寻址)

*B7B6B5B4B3B2B1B0

*-ECOM0CAPP0CAPN0MAT0TOG0PWM0ECCF0

*ECOM0:

允许比较器控制位。

=1时允许比较;=0时禁止

*CAPP0:

正捕获控制位。

=1时允许上升沿捕获;=0时禁止

*CAPN0:

负捕获控制位。

=1时允许下降沿捕获;=0时禁止

*MAT0:

匹配控制位。

*=1时,PCA计数值与模块的比较/捕获寄存器的值匹配将置位CCON寄存器的中

*断标志位CCF0;=0时无论匹配与否都不置位。

*TOG0:

翻转控制位。

*=1时,工作在PCA高数输出模式,PCA计数器的值与模块的比较/捕获寄存器

*

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 总结汇报 > 学习总结

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1