⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 spwm16.c

📁 采样法生成三相SPWM波的开环调速控制程序载波频率为20KHz
💻 C
字号:
//---------------------
//PWM16.c
//---------------------

#include<C8051F040.H>
#include<math.h>
#include<stdio.h>
#define uchar unsigned char
#define uint unsigned int

//--------------------
//全局变量
//---------------------------

#define PWM_START 0x0B00      	//对应于PWM高电平时间的起始值
sbit SPWM_OUT1=P0^0;            //定义SPWM输出端口1引脚
sbit SPWM_OUT2=P0^1;			//定义SPWM输出端口2引脚


#define SYSCLK 24500000       	//单片机系统时钟频率(MHz)
float CARRIER_F;              	//载波频率
uchar CARRIER_N;				//载波比
float M_rate=0.8;				//幅值调制比
float freq;						//输出电压频率
uint tpw;						//高电平脉冲宽度(us)
uchar i_SPWM1=0,i_SPWM2=70,max=70;


uint xdata hhigh[325];			//计算SPWM波高电平脉冲宽度中间寄存器
uint xdata llow[325];			//计算SPWM波低电平脉冲宽度中间寄存器
uint xdata runhigh_SPWM1[325];	//SPWM波输出口1高电平脉冲宽度运行寄存器
uint xdata runhigh_SPWM2[325];	//SPWM波输出口2高电平脉冲宽度运行寄存器
uint xdata runlow_SPWM1[325];	//SPWM波输出口1低电平脉冲宽度运行寄存器
uint xdata runlow_SPWM2[325];	//SPWM波输出口2低电平脉冲宽度运行寄存器

uint xdata sin_tbl1[24]={1305,2588,3827,5000,6088,7071,		//载波比为51时的正弦表
						7934,8660,9239,9659,9914,10000,
						9914,9659,9239,8660,7934,7071,
						6088,5000,3827,2588,1305,2
						};
uint xdata sin_tbl2[42]={747,1490,2225,2948,3653,4339,		//载波比为85时的正弦表(*10^4)
						5000,5633,6235,6802,7331,7818,
						8262,8660,9010,9309,9556,9749,
						9888,9972,10000,9972,9888,9749,
						9556,9309,9010,8660,8262,7818,
						7331,6802,6234,5633,5000,4339,
						3653,2948,2225,1490,747,2
						};
uint xdata sin_tbl3[70]={31,62,93,124,155,185,215,244,273,302,
						329,356,383,409,433,457,480,502,523,562,
						580,597,612,626,639,651,661,670,678,684,
						689,692,694,695,694,692,689,684, 678,670,
						661,651,639,626,612,597,580,562,543,523,
						502,480,457,433,409,383,356,329,302,273,
						244,215,185,155,124,93,62,31,1
						};
uint xdata sin_tbl4[115]={2935,3193,3448,3701,3952,4199,4443,4684,4922,5156,	//载波比为233时的正弦表(*10^4)
						5386,5612,5834,6052,6265,6474,6678,6877,7071,7260,
						7443,7622,7794,7961,8122,8277,8426,8569,8705,8835,
						8959,9076,9186,9290,9387,9477,9560,9635,9704,9766,
						9821,9868,9908,9941,9967,9985,9996,10000,9996,9985,
						9967,9941,9908,9868,9821,9766,9704,9635,9560,9477,
						9387,9290,9186,9076,8959,8835,8705,8569,8426,8277,
						8122,7961,7794,7622,7444,7260,7071,6877,6678,6474,
						6265,6052,5834,5612,5386,5156,4922,4684,4443,4199,
						3952,3701,3448,3193,2935,2675,2413,2150,1884,1618,
						1350,1081,812,541,271,2
						};
uint xdata sin_tbl5[194]={162,324,486,647,809,970,1131,1292,1452,1612,			//载波比为389时的正弦表(*10^4)
						1772,1931,2090,2248,2405,2562,2718,2874,3029,3182,
						3336,3488,3639,3789,3939,4087,4234,4380,4525,4669,
						4812,4953,5093,5232,5369,5505,5640,5772,5904,6034,
						6162,6289,6414,6537,6659,6779,6897,7014,7128,7241,
						7351,7460,7567,7672,7775,7876,7974,8071,8166,8258,
						8348,8436,8522,8606,8687,8766,8843,8917,8990,9059,
						9127,9192,9254,9314,9372,9427,9480,9530,9578,9623,
						9666,9706,9744,9779,9812,9842,9869,9894,9916,9936,
						9953,9967,9979,9988,9995,9999,10000,9999,9995,9988,
						9979,9967,9953,9936,9916,9894,9869,9842,9812,9779,
						9744,9706,9666,9623,9578,9530,9480,9427,9372,9314,
						9254,9192,9127,9059,8990,8917,8843,8766,8687,8606,
						8522,8436,8348,8258,8166,8071,7974,7876,7775,7672,
						7567,7460,7351,7241,7128,7014,6897,6779,6659,6537,
						6414,6289,6162,6034,5904,5773,5640,5505,5369,5232,
						5093,4953,4812,4669,4525,4380,4234,4087,3939,3789,
						3639,3488,3336,3182,3029,2874,2718,2562,2405,2248,
						2090,1931,1772,1612,1452,1292,1131,970,808,647,
						486,324,162,2
						};
uint xdata sin_tbl6[326]={964,1927,2891,3854,4817,5779,6741,7702,8662,9622,10581,11538,			//载波比为653时的正弦表(*10^5)
					2495,13451,14405,15358,16309,17259,18208,19154,20099,21042,21984,22923,
					23860,24794,25727,26657,27584,28509,29432,30351,31268,32182,33093,34001,
					34905,35807,36705,37600,38491,39378,40262,41143,42019,42892,43760,44624,
					45485,46341,47193,48040,48883,49722,50555,51384,52209,53028,53843,54652,
					55457,56256,57050,57839,58622,59400,60173,60940,61701,62457,63206,63950,
					64688,65420,66146,66865,67579,68286,68987,69681,70369,71051,71725,72394,
					73055,73710,74357,74998,75632,76259,76879,77492,78097,78695,79286,79870,
					80446,81015,81576,82130,82676,83214,83744,84267,84782,85289,85788,86280,
					86763,87238,87705,88164,88614,89057,89491,89917,90334,90744,91144,91537,
					91920,92295,92662,93020,93370,93710,94042,94366,94680,94986,95283,95571,
					95850,96120,96382,96634,96877,97112,97337,97554,97761,97959,98148,98328,
					98499,98661,98814,98957,99091,99216,99332,99439,99536,99624,99703,99773,
					99833,99884,99926,99958,99981,99995,100000,99995,99981,99958,99926,99884,
					99833,99773,99703,99624,99536,99439,99332,99216,99091,98957,98814,98661,
					98499,98328,98148,97959,97761,97554,97337,97112,96877,96634,96382,96120,
					95850,95571,95283,94986,94680,94366,94042,93710,93370,93020,92662,92295,
					91920,91537,91144,90744,90334,89917,89491,89057,88614,88164,87705,87238,
					86763,86280,85788,85289,84782,84267,83744,83214,82676,82130,81576,81015,
					80446,79870,79286,78695,78097,77492,76879,76259,75632,74998,74357,73710,
					73055,72394,71725,71051,70369,69681,68987,68286,67579,66865,66146,65420,
					64688,63950,63206,62457,61701,60940,60173,59400,58622,57839,57050,56256,
					55457,54652,53843,53028,52209,51384,50555,49722,48883,48040,47193,46341,
					45485,44625,43760,42892,42019,41143,40262,39378,38491,37600,36705,35807,
					34905,34001,33093,32182,31268,30351,29432,28509,27584,26657,25727,24794,
					23860,22923,21984,21042,20099,19154,18208,17259,16309,15358,14405,13451,
					12495,11538,10581,9622,8662,7702,6741,5779,4817,3854,2891,1927,964,2
					};												

//------------------
//函数原型
//----------------------
void main(void);
void PCA_ISR(void);           		//PCA中断服务程序
void spwmboard(void);				//SPWM波脉宽计算程序
//void dlms(void);     				//延时程序

//-----------------------------------

//主程序
//-------------------------------------
void main(void)
	{	
	uint temp0,temp1;

	WDTCN=0xDE;						//禁止看门狗定时器		
	WDTCN=0xAD;
	
		
	/*SFRPAGE=CONFIG_PAGE;
	SFRPAGE=0x0F;
	CLKSEL=0x00;
	OSCICL=0x00;
	OSCICN=0x83;*/					//设置SYSCLK为24.5MHz内部振荡器
	SFRPAGE=CONFIG_PAGE; //设置SYSCLK为24MHz内部振荡器
    OSCICN=0xC3;
    OSCICL=0x3C;
    CLKSEL=0x00;    

    XBR0=0x10;						//使CEX0和CEX1输出到P0.0、P0.1
	XBR2=0x40;						//允许交叉开关和弱上拉
	
	
	//PCA0CPM0=0x4D;					//PCA输出方式选择
	//PCA0CPM1=0x4D;

	P0MDOUT=0x01;					//设置P0.0输出为推挽方式
	P0MDOUT=0x02;					//设置P0.1输出为推挽方式
	
	
	SFRPAGE=0x00;
	
	
   //配置PCA
	PCA0MD=0x08;					//禁止CF中断
   									//PCA时基=SYSCLK	
	freq=100;						//正弦波频率
	spwmboard();

	temp0=0x00;						//初始化PCA模块0的比较值
	temp0+=runhigh_SPWM1[i_SPWM1];
	PCA0CPL0=(0xFF&temp0);	
	PCA0CPH0=(0xFF&(temp0>>8));	
	PCA0CPM0=0x4d;					//PCA输出方式选择(CCM0为高速输出方式)
	temp1=0x00;
	temp1+=runhigh_SPWM2[i_SPWM2];
	PCA0CPL1=(0xFF&temp1);	
	PCA0CPH1=(0xFF&(temp1>>8));
	PCA0CPM1=0x4d;					//PCA输出方式选择(CCM0为高速输出方式)
	EIE1|=0x08;		//允许PCA中断
	EA=1;			//允许全局中断
	
	PCA0CN=0x40;		//允许PCA计数器

		

	while(1){
			PCON|=0x01;
			}
	}

//--------------------------------------------
//PCA_ISR,该程序在PCA CCM0得到一次
//---------------------------------------------
	void PCA_ISR (void) interrupt 9
		{
		uint temppp0=0,temppp1=0;
				
		if(CCF0){
				CCF0=0;		        						//清除比较标志
				if(SPWM_OUT1){								//处理上升沿
							 if(i_SPWM1!=max-1) i_SPWM1++;
							 else i_SPWM1=0;
							 temppp0=(PCA0CPH0<<8)|PCA0CPL0;
							 if (i_SPWM1==0)
                             	temppp0+=(runhigh_SPWM1[i_SPWM1]+runhigh_SPWM1[max-1]);
                      		 else
                          	 	temppp0+=runhigh_SPWM1[i_SPWM1];
							 PCA0CPL0=(0xFF&temppp0);		//设置SPWM的下一个匹配值
							 PCA0CPH0=(0xFF&(temppp0>>8));
					 		 }
				else{
			     	temppp0=(PCA0CPH0<<8)|PCA0CPL0;			//设置下一个匹配值为0
                    temppp0+=runlow_SPWM1[i_SPWM1];
					PCA0CPL0=(0xff&temppp0);
                    PCA0CPH0=(0xff&temppp0>>8);
			     	}
		      	 }
		else if(CCF1){CCF1=0;
					  if(SPWM_OUT2)
					  			{
								if(i_SPWM2!=max-1) i_SPWM2++;
								else i_SPWM2=0;
								temppp1=(PCA0CPH1<<8)|PCA0CPL1;
							 	temppp1+=runhigh_SPWM2[i_SPWM2];
							 	PCA0CPL1=(0xFF&temppp1);		//设置SPWM的下一个匹配值
							 	PCA0CPH1=(0xFF&(temppp1>>8));
					 		 	}
					  else{
			     		temppp1=(PCA0CPH1<<8)|PCA0CPL1;			//设置下一个匹配值为0
                    	temppp1+=runlow_SPWM2[i_SPWM2];
						PCA0CPL1=(0xff&temppp1);
                    	PCA0CPH1=(0xff&temppp1>>8);
						   }
					  }			

		else if(CCF2){CCF2=0;}									//处理其它PCA中断
		else if(CCF3){CCF3=0;}
		else if(CCF4){CCF4=0;}
		else if(CF){CF=0;}
		
		}
//-----------------------------------------

//-----------------------------------------
void spwmboard()								//SPWM波脉宽计算程序
	{
	uchar i1;
	

	
	
	SFRPAGE=PCA0_PAGE;							//PCA计数器停止运行设置,计数器不停会出问题
	
	if(freq<=144&&freq>87)						//输出频率为87Hz~144Hz时SPWM脉宽的计算
		{
		/*CARRIER_N=141;
		CARRIER_F=CARRIER_N*freq;
		tempp1=SYSCLK/CARRIER_F;
		max=CARRIER_N/2-1;
		for(i1=0;i1<max;i1++)
			{
			tpw_high=(M_rate*sin_tbl3[i1]/10000)/(2*CARRIER_F);
			tempp0=(uint)(tpw_high*SYSCLK);
			tempp1=(uint)(tpw_low*SYSCLK);
			hhigh[i1]=tempp0;
			llow[i1]=tempp1;
			}*/
		for(i1=0;i1<max-1;i1++)
			{
			if(sin_tbl3[i1]>70)
				hhigh[i1]=sin_tbl3[i1];
			else hhigh[i1]=70;
			llow[i1]=1738-hhigh[i1];
			hhigh[max-1]=sin_tbl3[max-1];

			}
	
		}
	
	SFRPAGE=PCA0_PAGE;  							//PCA计数器停止运行设置
	PCA0CN=0x00;

	for (i1=0;i1<max;i1++)							//将SPWM中间寄存器的数据装入运行寄存器
		runhigh_SPWM1[i1]=hhigh[i1];
	for (i1=0;i1<max;i1++)
            runlow_SPWM1[i1]=llow[i1];
			//runhigh_SPWM2[0]=llow[0];
    for (i1=0;i1<max;i1++)
          runhigh_SPWM2[i1]=llow[i1];
		
    for (i1=0;i1<max;i1++)
   		runlow_SPWM2[i1]=hhigh[i1];
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -