/* 选用stc15w4k系列单片机,自带PCA模块 */ /*利用PCA模块实现SPWM调制*/ /*利用单片机自带晶振18.432MHZ,PCA模块计数时钟取1/2系统时钟*/ /*定时器T0取系统时钟*/ /*为了实现50HZ的交流电输出转化,取半周点数180点,也就是SPWM的频率为18K*/ /*直流高压母线预设计电压为360V,输出220VAC,50HZ,调制度M为220*根号2除以360=311/360=0.8639*/ /*单片机计算效率不够高,取调制度M为0.86*/ /*作者:*/ #include #include #define uchar unsigned char #define uint unsigned int uchar code pwm[54]={ 255,243,230,217,205,193,180,169,157,146, 135,125,115,105,96,88,80,72,66,60, 54,49,45,42,40,38,37,36,37,38, 40,42,45,49,54,60,66,72,80,88, 96,105,115,125,135,146,157,169,180,193, 205,217,230,243 }; // 反正弦变化 int index=0; bit flag=0; //前后半周期标志 void init_pca(void)//pca计数器初始化函数 { CMOD=0x02;//2分频 CCON=0x00; CCAPM0=0x42;//8位PWM输出,无中断 CCAPM1=0x42;//8位PWM输出,无中断 CL=0x00;//清零pca计数器 CH=0x00; CCAP0L=pwm[0]; //初始化spwm输出的占空比 CCAP0H=pwm[0]; CCAP1L=pwm[0]; //初始化spwm输出的占空比 CCAP1H=pwm[0]; CR=1;//运行pca计数器 } void init_timer(void)//计数器初始化函数 { TMOD= 0x00; //计数器0工作在方式模式1 TH0 = 0XF8;//T1的计数值为2048,若是11.0592M晶振,则中断频率为11.0592M/2048=5.4K TL0 = 0x01; //T1的计数值低位 AUXR=0xC0;//计数器均工作在1T模式。计数频率11.0592M ET0 = 1; //开中计数器0断 TR0 = 1; //开启计数器0 } void int_timer0(void) interrupt 1//计数器1中断函数 { //TH0=0xF8; //重装计数值 //TL0=0x01; index++; //查表索引 if(index==54) //半周期转换,每半周期分为60份 { CR=0; //关PCA计数 index=0; flag=~flag; //半周期标志,zf=0,前半周期,zf=1,后半周期 if(flag) //设置后半周期 { P11=0; CCAPM0=0X00; //关闭模块0 CCAPM1=0X42; //设置模块1工作方式 } else //设置前半周期 { P10=0; CCAPM1=0X00; //关闭模块1 CCAPM0=0X42; //设置模块0工作方式 } CR=1; //开PCA计数 } if(flag==0) //将下一小格的占空比赋给相应值 { 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 delay1ms() //用于初始化时延时 { unsigned char i,j; _nop_(); _nop_(); _nop_(); i=11; j=190; do { while(--j); }while(--i); } void main(void) { delay1ms(); gpio(); P10=0; P11=0; EA=1;//开总中断 init_pca(); init_timer(); while(1)//主循环 { } }