基于STC12系列单片机的串联型开关电源设计与实现.docx
《基于STC12系列单片机的串联型开关电源设计与实现.docx》由会员分享,可在线阅读,更多相关《基于STC12系列单片机的串联型开关电源设计与实现.docx(26页珍藏版)》请在冰豆网上搜索。
基于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;//ClearpreviousresultADC_CONTR=ADC_POWER|ADC_SPEEDLL|ADC_START|ChNo;//for(Delay=0x00;Delay<500;Delay++);//ADCpower-onanddelayIE=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计数器的值与模块的比较/捕获寄存器*
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;//ClearpreviousresultADC_CONTR=ADC_POWER|ADC_SPEEDLL|ADC_START|ChNo;//for(Delay=0x00;Delay<500;Delay++);//ADCpower-onanddelayIE=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计数器的值与模块的比较/捕获寄存器*
{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();
elseif(b==setkey)
头文件如下:
#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);
a=a+0.1;
while(!
k1);
if(k2==0)
a=a-0.1;
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();
(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;//ClearpreviousresultADC_CONTR=ADC_POWER|ADC_SPEEDLL|ADC_START|ChNo;//for(Delay=0x00;Delay<500;Delay++);//ADCpower-onanddelayIE=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计数器的值与模块的比较/捕获寄存器*
{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个位上的数
SMG_g=1;
SMG_s=0;
P0=0x7f;
show2
前2位数的数码显示器显示获取电压(只用于ADC_Drv_Demo函数)
j
voidshow2(unsignedintj)//前两位数码管显示数字j即获取的电压值
{SMG_q=0;//P1.0引脚输出低电平,数码管千位接通
P0=Tab[j/10];//显示j十位上的数
SMG_q=1;
SMG_b=0;//P1.1引脚输出低电平,数码管百位接通
P0=Tab[j%10];//显示j个位上的数
SMG_b=1;//关闭所有显示器
SMG_q=0;
数码管头文件如下:
#ifndef__SMG_H__
#define__SMG_H__
externunsignedchari;
externunsignedintx;
externvoiddelay(unsignedintn);
externvoidshow1(unsignedintk);
externvoidshow2(unsignedintj);
(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赋值语句,不要用‘与’和‘或’语句
*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:
*4.中断寄存器:
IE——EA,EADC(1允许ADC中断,0禁止)
*5.中断优先级寄存器IP、IP2和IPH、IP2H
*IP、IP2中的中断优先控制位分别对应IE各中断允许位
*IPH、IPH2中的中断优先控制位分别对应IE2各中断允许位
*IPH:
中断优先级控制寄存器高(不可位寻址)
*PPCAHPLVDHPADCHPSHPT1HPX1HPT0HPX0H
*IP:
中断优先级控制寄存器低(可位寻址)
*PPCAPLVDPADCPSPT1PX1PT0PX0
*IP2H:
中断优先级控制寄存器2高(不可位寻址)
*------PSPIHPS2H
*IP2:
中断优先级控制寄存器2低(不可位寻址)
*------PSPIPS2
*PADCHPADC优先级
*00最低优先级(优先级0)
*01较低优先级(优先级1)
*10较高优先级(优先级2)
*11最高优先级(优先级3)
A/D实验程序:
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;//ClearpreviousresultADC_CONTR=ADC_POWER|ADC_SPEEDLL|ADC_START|ChNo;//for(Delay=0x00;Delay<500;Delay++);//ADCpower-onanddelayIE=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计数器的值与模块的比较/捕获寄存器*
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结果
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
显示获取的电压值
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);
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);
(5)PWM部分
*1.PCA工作模式寄存器:
CMOD
*CMOD:
(不可位寻址)
*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:
(可位寻址)
*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的比较/捕获寄存器(不可位寻址)
*-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