STC8单片机三相SPWM程序

STC8H8K单片机高级PWM资源产生6路SPWM波形,每路相差120°,可以做三相逆变器。程序中是用3个相同的数组产生,代码比较多,如果用指针会更好。

/**********STC8带死区正弦波调制,三相SPWM互补波形输出**********
*********频率:50Hz;    SPWM调制频率:10KHz******************
******** QQ:2401553359   QQ群:560864628   ****************/
#include "stc8.h" 
#define PWM_DeadZone 12      /* 死区时钟数, 6 ~ 24之间  */
#define u8 unsigned char
#define u16 unsigned int
u8 PWM_index;        //SPWM查表索引
u16 code A_SinTable[]={   //A相数组
70, 71, 72, 75, 79, 84, 90, 98, 106, 116,
126, 138, 151, 165, 179, 195, 212, 230, 249, 269,
290, 311, 334, 357, 382, 407, 433, 459, 487, 515,
544, 574, 604, 635, 666, 698, 730, 763, 797, 830,
865, 899, 934, 969, 1005, 1040, 1076, 1112, 1148, 1184,	
1220, 1256, 1292, 1328, 1364, 1400, 1435, 1471, 1506, 1541,
1575, 1610, 1643, 1677, 1710, 1742, 1774, 1805, 1836, 1866,
1896, 1925, 1953, 1981, 2007, 2033, 2058, 2083, 2106, 2129,
2150, 2171, 2191, 2210, 2228, 2245, 2261, 2275, 2289, 2302,
2314, 2324, 2334, 2342, 2350, 2356, 2361, 2365, 2368, 2369,
2370, 2369, 2368, 2365, 2361, 2356, 2350, 2342, 2334, 2324,
2314, 2302, 2289, 2275, 2261, 2245, 2228, 2210, 2191, 2171,
2150, 2129, 2106, 2083, 2058, 2033, 2007, 1981, 1953, 1925,
1896, 1866, 1836, 1805, 1774, 1742, 1710, 1677, 1643, 1610,
1575, 1541, 1506, 1471, 1435, 1400, 1364, 1328, 1292, 1256,
1220, 1184, 1148, 1112, 1076, 1040, 1005, 969, 934, 899,
865, 830, 797, 763, 730, 698, 666, 635, 604, 574,
544, 515, 487, 459, 433, 407, 382, 357, 334, 311,
290, 269, 249, 230, 212, 195, 179, 165, 151, 138,
126, 116, 106, 98, 90, 84, 79, 75, 72, 71,
};         //200个数组,如果改变其个数,则(PWM_Index)函数和
          //周期计算也要改变,否则输出频率不是50Hz且波形不一样
u16 code B_SinTable[]={//B相数组,相位相对A相滞后60°,及数组往后移动1/3
1677, 1710, 1742, 1774, 1805, 1836, 1866,
1896, 1925, 1953, 1981, 2007, 2033, 2058, 2083, 2106, 2129,
2150, 2171, 2191, 2210, 2228, 2245, 2261, 2275, 2289, 2302,
2314, 2324, 2334, 2342, 2350, 2356, 2361, 2365, 2368, 2369,
2370, 2369, 2368, 2365, 2361, 2356, 2350, 2342, 2334, 2324,
2314, 2302, 2289, 2275, 2261, 2245, 2228, 2210, 2191, 2171,
2150, 2129, 2106, 2083, 2058, 2033, 2007, 1981, 1953, 1925,
1896, 1866, 1836, 1805, 1774, 1742, 1710, 1677, 1643, 1610,
1575, 1541, 1506, 1471, 1435, 1400, 1364, 1328, 1292, 1256,
1220, 1184, 1148, 1112, 1076, 1040, 1005, 969, 934, 899,
865, 830, 797, 763, 730, 698, 666, 635, 604, 574,
544, 515, 487, 459, 433, 407, 382, 357, 334, 311,
290, 269, 249, 230, 212, 195, 179, 165, 151, 138,
126, 116, 106, 98, 90, 84, 79, 75, 72, 71,70,71, 
72, 75, 79, 84, 90, 98, 106, 116,
126, 138, 151, 165, 179, 195, 212, 230, 249, 269,
290, 311, 334, 357, 382, 407, 433, 459, 487, 515,
544, 574, 604, 635, 666, 698, 730, 763, 797, 830,
865, 899, 934, 969, 1005, 1040, 1076, 1112, 1148, 1184,	
1220, 1256, 1292, 1328, 1364, 1400, 1435, 1471, 1506, 1541,
1575, 1610, 1643,
};        //200个数组,如果改变其个数,则(PWM_Index)函数和
          //周期计算也要改变,否则输出频率不是50Hz且波形不一样

u16 code C_SinTable[]={//C相数组,相位相对A相滞后120°,及数组往后移动2/3
1805, 1774, 1742, 1710, 1677, 1643, 1610,1575, 1541, 
1506, 1471, 1435, 1400, 1364, 1328, 1292, 1256,
1220, 1184, 1148, 1112, 1076, 1040, 1005, 969, 934, 899,
865, 830, 797, 763, 730, 698, 666, 635, 604, 574,
544, 515, 487, 459, 433, 407, 382, 357, 334, 311,
290, 269, 249, 230, 212, 195, 179, 165, 151, 138,
126, 116, 106, 98, 90, 84, 79, 75, 72, 71,70, 71, 
72, 75, 79, 84, 90, 98, 106, 116,
126, 138, 151, 165, 179, 195, 212, 230, 249, 269,
290, 311, 334, 357, 382, 407, 433, 459, 487, 515,
544, 574, 604, 635, 666, 698, 730, 763, 797, 830,
865, 899, 934, 969, 1005, 1040, 1076, 1112, 1148, 1184,	
1220, 1256, 1292, 1328, 1364, 1400, 1435, 1471, 1506, 1541,
1575, 1610, 1643, 1677, 1710, 1742, 1774, 1805, 1836, 1866,
1896, 1925, 1953, 1981, 2007, 2033, 2058, 2083, 2106, 2129,
2150, 2171, 2191, 2210, 2228, 2245, 2261, 2275, 2289, 2302,
2314, 2324, 2334, 2342, 2350, 2356, 2361, 2365, 2368, 2369,
2370, 2369, 2368, 2365, 2361, 2356, 2350, 2342, 2334, 2324,
2314, 2302, 2289, 2275, 2261, 2245, 2228, 2210, 2191, 2171,
2150, 2129, 2106, 2083, 2058, 2033, 2007, 1981, 1953, 1925,
1896, 1866, 1836, 
};        //200个数组,如果改变其个数,则(PWM_Index)函数和
          //周期计算也要改变,否则输出频率不是50Hz且波形不一样

void PWM_init(void)
{  
  P_SW2=0x80;
	
	PWM1T1=65;        // 第一个翻转计数
  PWM1T2=1220;      // 第二个翻转计数
  PWM1CR=0x80;     // 相应PWM通道的端口为PWM输出口,受PWM波形发生器控制 ENC10
  PWM2T1=65-PWM_DeadZone;  // 第一个翻转计数低字节       
  PWM2T2=(1220+PWM_DeadZone); // 第二个翻转计数高字节        
  PWM2CR|=0x80;      // 相应PWM通道的端口为PWM输出口,受PWM波形发生器控制 ENC20
 
  PWM3T1=65;        // 第一个翻转计数
  PWM3T2=1220;       // 第二个翻转计数
  PWM3CR=0x80;     // 相应PWM通道的端口为PWM输出口,受PWM波形发生器控制 ENC30
  PWM4T2=65+PWM_DeadZone;  // 第一个翻转计数低字节       
  PWM4T1=(1220-PWM_DeadZone); // 第二个翻转计数高字节        
  PWM4CR=0xC0;        // 相应PWM通道的端口为PWM输出口,受PWM波形发生器控制 ENC40
 
	PWM5T1=65;        // 第一个翻转计数
  PWM5T2=1220;      // 第二个翻转计数
  PWM5CR|=0x80;     // 相应PWM通道的端口为PWM输出口,受PWM波形发生器控制 ENC50
  PWM6T2=65+PWM_DeadZone;  // 第一个翻转计数低字节       
  PWM6T1=(1220-PWM_DeadZone); // 第二个翻转计数高字节        
  PWM6CR|=0x80; // 相应PWM通道的端口为PWM输出口,受PWM波形发生器控制 ENC60
 
  PWMC=2400;        // PWM计数器的高字节
  PWMCKS=0x00;      // 时钟源                 
  P_SW2=0x00;       // 恢复访问XRAM
  PWMCR=0x80;      // 使能PWM波形发生器,PWM计数器开始计数
  PWMCR|=ECBI;      // 允许PWM计数器归零中断
  EA=1;              //允许全局中断
}

void PWM_Isr(void) interrupt 22 //PWM中断
{
  u16 i,j,k;
  u8 SW2_tmp;
  if(PWMCFG&CBIF)        //PWM计数器归零中断标志 PWMCFG
  {
    PWMCFG&=~CBIF;        //清除中断标志
    SW2_tmp=P_SW2;        //保存SW2设置                  
    P_SW2=0x80;      //访问XFR

    i=A_SinTable[PWM_index];
		PWM1T2H=(u8)(i>>8);        //第二个翻转计数高字节
    PWM1T2L=(u8)i;          //第二个翻转计数低字节

		j=B_SinTable[PWM_index];
		PWM3T2H=(u8)(j>>8);     //第二个翻转计数高字节   
    PWM3T2L=(u8)j;  

		k=C_SinTable[PWM_index];
		PWM5T2H=(u8)(k>>8);     //第二个翻转计数高字节   
    PWM5T2L=(u8)k;  
		
    PWM2T2H=(u8)(i>>8);        //第二个翻转计数高字节
    PWM2T2L=(u8)i;          //第二个翻转计数低字节
    i+=PWM_DeadZone;         //死区  
	  
    PWM4T2H=(u8)(j>>8);     //第二个翻转计数高字节   
    PWM4T2L=(u8)j;         //第二个翻转计数低字节
		j+=PWM_DeadZone;         //死区  
		
		PWM6T2H=(u8)(k>>8);     //第二个翻转计数高字节   
    PWM6T2L=(u8)k;         //第二个翻转计数低字节
		k+=PWM_DeadZone;         //死区  
		
    P_SW2=SW2_tmp;        //恢复SW2设置
    if(++PWM_index>=200)     
		PWM_index=0;
  }
}

void main(void)
{
  
  PWM_init();        //初始化PWM
  while (1) 
  {}    //循环
}


评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值