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) 
  {}    //循环
}


  • 5
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
STC8A单片机是一款高性能、低功耗的8位单片机,具有多种功能和特性。它的ADC(模数转换器)模块可以用于采集模拟信号,并将其转换为数字信号进行处理。 STC8A单片机的ADC采集程序需要以下基本步骤: 1. 初始化ADC模块:配置ADC通道、参考电压以及采样时钟等参数。可以使用相应的寄存器设置来完成此任务。 2. 设置ADC输入通道:选择需要采集的模拟信号输入通道。单片机的ADC模块可以有多个输入通道,通过设置相应的寄存器来选择通道。 3. 启用ADC模块:将ADC模块打开,使其处于工作状态。可以通过设置相应的寄存器来完成此任务。 4. 设置ADC采样时钟:根据需求设置ADC的采样时钟频率。采样时钟频率的选择要结合被采样信号的变化速度和所需精度来确定。 5. 开始采样:启动ADC模块进行模数转换,将模拟信号转换为数字信号。可以通过设置相应的寄存器来启动ADC转换过程。 6. 等待转换完成:等待ADC转换完成,可以通过查询相应的标志位或使用中断来实现。一旦转换完成,可以读取转换结果。 7. 处理转换结果:获取ADC转换的结果值,并进行相应的处理。可以将结果值用于后续的计算、显示或其他处理。 8. 关闭ADC模块:在不需要进行ADC采集时,应关闭ADC模块,以节省功耗。 以上是STC8A单片机ADC采集程序的基本步骤。通过合理的配置和操作,可以实现对模拟信号的精确采集和处理,满足各种应用需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值