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)
{} //循环
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)