/* 选用stc15w4k系列单片机,自带PCA模块 */ /*利用PCA模块实现SPWM调制*/ /*利用单片机自带晶振18.432MHZ,PCA模块计数时钟取1/4系统时钟*/ /*定时器T0取系统时钟*/ /*为了实现50HZ的交流电输出转化,取半周点数180点,也就是SPWM的频率为18K*/ /*直流高压母线预设计电压为360V,输出220VAC,50HZ,调制度M为220*根号2除以360=311/360=0.8639*/ /*单片机计算效率不够高,取调制度M为0.86*/ /*作者:张康平*/ #include //#include //端口输出初始化,PWM端口输出需要初始化,默认上电时为高阻态(可能不涉及cpp端口,待调试检验) #define uchar unsigned char #define uint unsigned int uchar code pwm[180]={ 255,252,248,244,240,236,233,229,225,221,217,214,210,206,202,199,195,191,188,184, 180,177,173,170,166,163,159,156,153,149,146,143,139,136,133,130,127,124,120,117, 115,112,109,106,103,100,98,95,93,90,88,85,83,80,78,76,74,72,70,68, 66,64,62,60,58,57,55,54,52,51,49,48,47,46,45,44,43,42,41,40, 40,39,38,38,37,37,37,37,36,36,36,36,36,37,37,37,37,38,38,39, 40,40,41,42,43,44,45,46,47,48,49,51,52,54,55,57,58,60,62,64, 66,68,70,72,74,76,78,80,83,85,88,90,93,95,98,100,103,106,109,112, 115,117,120,124,127,130,133,136,139,143,146,149,153,156,159,163,166,170,173,177, 180,184,188,191,195,199,202,206,210,214,217,221,225,229,233,236,240,244,248,252, }; //反正弦表 int index=0; //标记反正弦表下表 bit flag=0; //前后半周期标志位 void init_PCA(void) //PCA初始化 { CMOD=0X0A;//PCA计数器时钟为系统时钟/4,系统晶振18.432M CCON=0X00;//计数器计数、中断位清零,停止计数 CCAPM0=0X42;//PWM输出,无中断 CCAPM1=0X42;//PWM输出,无中断 CL=0X00;//计数器清零 CH=0X00; PCA_PWM0=0X00;//PCA模块工作于8位PWM模式 PCA_PWM1=0X00;//PCA模块工作于8位PWM模式 CCAP0L=pwm[0];//设定PWM0的脉冲初始宽度 CCAP0H=pwm[0]; CCAP1L=pwm[0];//设定PWM1的脉冲初始宽度 CCAP1H=pwm[0]; CR=1;//启动PCA计数器 } void init_timer0(void) //定时器T0初始化 { TMOD=0X00;//定时器T0工作在工作方式0,16位自动重装定时器 AUXR=0XC0;//T0工作于1T模式,不进行分频(8-12倍速于C51单片机) TL0=0XFF;//T0的计数值为1024,如果晶振取18.432MHZ,中断频率为18.432M/1024=18K TH0=0XFB; TF0=0;//清除TF0中断标志 ET0=1;//允许定时器T0总中断 TR0=1;//开启定时器T0 } void T0_ISR(void) interrupt 1 //T0中断服务函数 { index++;//查表索引 if(index==180) { CR=0;//暂停PCA计数 index=0;//索引表回到开头 flag=~flag; if(flag) { P1^1=0;//模块0输出置零 CCAPM0=0X00;//关闭PCA模块0 CCAPM1=0X42;//开启PCA模块1 } else { P1^0=0;//模块1输出置零 CCAPM1=0X00;//关闭PCA模块1 CCAPM0=0X42;//开启PCA模块0 CR=1;//再次开启PCA计数器 } } if(flag==0) //将下一段的占空比系数置入CCAP0H或CCAP1H { CCAP0H=pwm[index]; } else { CCAP1H=pwm[index]; } } void gpio(void) //初始化I/O口,P0-P5全部设置为准双向口 { P0M1=0;P0M0=0; // P1M1=0;P1M0=0; P2M1=0;P2M0=0; P3M1=0;P3M0=0; P4M1=0;P4M0=0; P5M1=0;P5M0=0; } void main(void) //主函数 { gpio();//初始化I/O口 P1^1=0; P1^0=0;//SPWM输出端口上电时关闭 EA=1; //开总中断 init_PCA();//PCA模块初始化 init_timer0(); //定时器T0初始化 }