/*****************************************************************************
该程序中假设有200个电压矢量Uout平均分布在电角度为360度的范围内
该程序用于简单的SVPWM演示,产生3相互差120度电角度的正弦交流电压,此程序实
时计算cmp1和cmp2的值,使用的是定时器3
PWM7、9、11高有效,
PWM8、10、12低有效
周期是1K
---------------------------------------------------------------------------*/
#include "f2407c.h"
#include "float.h"
#include "math.h"
float ualfa[200],ubeta[200]; // 存储电压矢量Uout的(α,β)轴分量ualfa、ubeta的数组
int sector[200]; // 定义存储扇区数的数组
#define PI2 2*3.1415926 // 定义2π的值
#define DETA PI2/200 // 定义相临两个Uout之间的电角度的差值
#define INIA 3.1415926/180 // 定义Uout的初始电角度
#define TP 1200 // t1的周期寄存器的值,其值等于SVPWM调制周期T的一半,
//1200=30000000/1k/2
// 因为在该程序中2π电角度内Uout的点数一定,故改变此值
// 可以改变输出的3相正弦交流电压的频率
#define KP 0.5 // 定义Uout的标幺值,KP的值在0和1之间,改变此值可以
// 改变逆变桥输出电压的幅值,范围是 -
//-----------------屏蔽中断子程序------------------------------
void inline disable()
{
asm(" setc INTM");
}
//---------------系统初始化子程序------------------------------
void initial()
{
*IFR=0xFFFF; // 清除所有的中断标志
*IMR=0X0; // 屏蔽所有中断
*SCSR1=0x81FE; // CLKIN=15M,4倍频CLKOUT=60M
*WDCR=0xE8; // 不使能看门狗
*T3PR=TP; // 通用定时器1的周期=PWM的周期/预定标数/指令周期/2
*T3CON=0X0802; // 设置通用定时器3为连续增减模式,以产生对称的PWM,
// 且为了便于调试,使仿真一挂起时时钟就停止运行
//预定标数是1
*ACTRB=0X666; // PWM7、9、11高有效,PWM8、10、12低有效
//正向逆时针
*COMCONB=0X9200; // 使能SPWM
//使能PWM输出和比较动作
*EVBIMRA=0X00; // 禁止EVB和时钟及比较有关的中断
*T3CNT=0X00; // T3的计数器清0
*EVBIFRA=0x0FFFF; // 清除EVB相应的中断标志
*MCRC=*MCRC|0X7E; // PWM7-PWM12输出使能,使能IOPE1-IOPE6第二功能
*WSGR=0x0000; // 不使能所有的等待状态
}
//-----------根据Uout的标幺值KP计算ualfa,ubeta子程序-----------------------
void calu()
{
int i;
for(i=0;i<200;i++)
{
ualfa[i]=KP*cos(INIA+i*DETA);
ubeta[i]=KP*sin(INIA+i*DETA);
}
}
//--------------------各点的扇区确定子程序-------------------------------------
void SECTOR()
{
int i,a,b,c;
float vref1,vref2,vref3;
for(i=0;i<200;i++)
{
vref1=ubeta[i];
vref2=(-ubeta[i]+ualfa[i]*1.732051)/2;
vref3=(-ubeta[i]-ualfa[i]*1.732051)/2; // 计算确定扇区数需要的3个参考量
// vref1、vref2、vref3
if(vref1>0) a=1;
else a=0;
if(vref2>0) b=1;
else b=0;
if(vref3>0) c=1;
else c=0;
a=4*c+2*b+a;
switch(a){
case 1:sector[i]=1;break;
case 2:sector[i]=5;break;
case 3:sector[i]=0;break;
case 4:sector[i]=3;break;
case 5:sector[i]=2;break;
case 6:sector[i]=4;break;
default:break;
} // 根据相应的关系确定各个Uout所在的扇区
}
}
//---------------------主程序-------------------------------------------------
main()
{
int anticlk[6]={0x1666,0x3666,0x2666,0x6666,0x4666,0x5666};
// 逆时针旋转的6个基本矢量
int i,k=0,cmp1,cmp2;
float x,y,z;
disable(); // 屏蔽所有中断
initial(); // 系统初始化
calu(); // 计算ualfa,ubeta的值
SECTOR(); // 确定各点的扇区,在实际应用时应该由即时
// 的ualfa和ubeta即时算出
while(1)
{
for(i=0;i<200;i++)
{
*ACTRB=anticlk[sector[i]]; // 重新装配ACTRA
x=ubeta[i];
y=(1.732051*ualfa[i]+ubeta[i])/2;
z=(-1.732051*ualfa[i]+ubeta[i])/2;// 以上3句计算3个相应的参考量
switch(sector[i])
{
case 0: cmp1=(int)(-z*TP),cmp2=(int)(x*TP);break;
case 1: cmp1=(int)(y*TP),cmp2=(int)(z*TP);break;
case 2: cmp1=(int)(x*TP),cmp2=(int)(-y*TP);break;
case 3: cmp1=(int)(z*TP),cmp2=(int)(-x*TP);break;
case 4: cmp1=(int)(-y*TP),cmp2=(int)(-z*TP);break;
case 5: cmp1=(int)(-x*TP),cmp2=(int)(y*TP);break;
default: break;
} // 以上根据uout所处的扇区计算相应的cmp1和cmp2的值
*CMPR4=cmp1; // 比较寄存器4赋值
*CMPR5=cmp1+cmp2; // 比较寄存器5赋值
if((i+k)==0) *T3CON=*T3CON|0X040; // 启动定时器,只启动一次
while(1)
{
k=*EVBIFRA&0X0200;
if(k==0x0200) break; // 如果T3的中断标志建立,则停止等待
}
}
}
}
//----------------如果由于干扰引起中断,则执行此直接返回程序-----------------
void interrupt nothing()
{
// asm("CLRC INTM");
return;
}
SVPWM.rar_svpwm_伺服 源码_伺服电机控制_伺服电机源码_伺服电路图
版权申诉
118 浏览量
2022-09-19
19:24:04
上传
评论 1
收藏 62KB RAR 举报
小波思基
- 粉丝: 74
- 资源: 1万+
最新资源
- 基于Java的网上订餐系统设计源码 - online ordering system
- 基于Javascript的超级美眉网络资源管理应用模块设计源码
- 基于Typescript和PHP的编程知识储备库设计源码 - study-php
- Screenshot_2024-05-28-11-40-58-177_com.tencent.mm.jpg
- 基于Dart的Flutter小提琴调音器APP设计源码 - violinhelper
- 基于JavaScript和CSS的随寻订购网页设计源码 - web-order
- 基于MATLAB的声纹识别系统设计源码 - VoiceprintRecognition
- 基于Java的微服务插件集合设计源码 - wsy-plugins
- 基于Vue和微信小程序的监理日志系统设计源码 - supervisionLog
- 基于Java和LCN分布式事务框架的设计源码 - tx-lcn
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
评论0