基于STC12系列单片机的串联型开关电源设计与实现.docx
- 文档编号:9731927
- 上传时间:2023-02-06
- 格式:DOCX
- 页数:26
- 大小:198.16KB
基于STC12系列单片机的串联型开关电源设计与实现.docx
《基于STC12系列单片机的串联型开关电源设计与实现.docx》由会员分享,可在线阅读,更多相关《基于STC12系列单片机的串联型开关电源设计与实现.docx(26页珍藏版)》请在冰豆网上搜索。
基于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计数器的值与模块的比较/捕获寄存器 *
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 基于 STC12 系列 单片机 串联 开关电源 设计 实现
![提示](https://static.bdocx.com/images/bang_tan.gif)