?? e3phase.c
字號(hào):
/**************三相馬達(dá)控制用定時(shí)功能測(cè)試程序***************/
//文件名:e3phase.c
//說(shuō)明: 本程序聯(lián)合利用定時(shí)器A1,A2,A4和B2,產(chǎn)生驅(qū)動(dòng)三相馬達(dá)的電壓波形(SPWM),
// 完成對(duì)三菱M16C/6N系列單片機(jī)的三相馬達(dá)控制用的定時(shí)功能的測(cè)試。晶振頻率為16MHz。
//程序員:文武松
//時(shí)間: 05-04-09
/***********************包含的頭文件************************/
#include "sfr6n.h" //NOTE:在三菱單片機(jī)的C語(yǔ)言中,頭文件必須用引號(hào)
/*************************宏定義****************************/
#define uint unsigned int
#define uchar unsigned char
#define ulong unsigned long
#define CLK 16 //晶振頻率16MHz
#define modul_rate 80 //調(diào)制比(0.8)*100
#define carrier_F 3600 //載波頻率20KHz
#define output_F 10 //輸出正弦波的頻率
#define c2_data 399 //carrier period/2=(MCU clk frequency/carrier frequency)/2
#define c4_data 199 //carrier period/4
#define PWM_max 397 //TAi的最大值
#define PWM_min 2 //TAi的最小值
/**********************全局變量的定義***********************/
uint modul_data; //modul_data=modul_rate*carrier period/4/100
uint sin_cut; //連續(xù)兩次指向正弦表的指針之差
uint pointer; //正弦表指針
uint pwm_v; //v相定時(shí)器寄存器值
uint pwm_w; //w相定時(shí)器寄存器值
uint pwm_u; //u相定時(shí)器寄存器值
uint sin_sum; //指針記憶單元
/*uint A1_DATA; //定時(shí)器寄存器A1緩沖器
uint A11_DATA; //定時(shí)器寄存器A11緩沖器
uint A2_DATA; //定時(shí)器寄存器A2緩沖器
uint A21_DATA; //定時(shí)器寄存器A21緩沖器
uint A4_DATA; //定時(shí)器寄存器A4緩沖器
uint A41_DATA; //定時(shí)器寄存器A41緩沖器
*/
const uint sin_tb[600]={
174,348,523,697,871,1045,1218,1391,1564,1736,
1908,2079,2249,2419,2588,2756,2923,3090,3255,3420,
3583,3746,3907,4067,4226,4383,4539,4694,4848,5000,
5150,5299,5446,5591,5735,5877,6018,6156,6293,6427,
6560,6691,6819,6946,7071,7193,7313,7431,7547,7660,
7771,7880,7986,8090,8190,8290,8386,8480,8571,8660,
8746,8829,8910,8987,9063,9135,9205,9271,9335,9396,
9455,9510,9563,9612,9659,9702,9743,9781,9816,9848,
9875,9902,9925,9945,9961,9975,9986,9993,9998,10000,
9998,9993,9986,9975,9961,9945,9925,9902,9876,9848,
9816,9781,9743,9702,9659,9612,9563,9510,9455,9396,
9335,9271,9205,9135,9063,8987,8910,8829,8746,8660,
8571,8480,8386,8290,8191,8090,7986,7880,7771,7660,
7547,7431,7313,7193,7071,6946,6819,6691,6560,6427,
6293,6156,6018,5877,5735,5591,5446,5299,5150,5000,
4848,4694,4539,4383,4226,4067,3907,3746,3583,3420,
3555,3090,2923,2756,2588,2419,2249,2079,1908,1736,
1564,1391,1218,1045,871,697,523,348,174,50,
174,348,523,697,871,1045,1218,1391,1564,1736,
1908,2079,2249,2419,2588,2756,2923,3090,3255,3420,
3583,3746,3907,4067,4226,4383,4539,4694,4848,5000,
5150,5299,5446,5591,5735,5877,6018,6156,6293,6427,
6560,6691,6819,6946,7071,7193,7313,7431,7547,7660,
7771,7880,7986,8090,8190,8290,8386,8480,8571,8660,
8746,8829,8910,8987,9063,9135,9205,9271,9335,9396,
9455,9510,9563,9612,9659,9702,9743,9781,9816,9848,
9875,9902,9925,9945,9961,9975,9986,9993,9998,10000,
9998,9993,9986,9975,9961,9945,9925,9902,9876,9848,
9816,9781,9743,9702,9659,9612,9563,9510,9455,9396,
9335,9271,9205,9135,9063,8987,8910,8829,8746,8660,
8571,8480,8386,8290,8191,8090,7986,7880,7771,7660,
7547,7431,7313,7193,7071,6946,6819,6691,6560,6427,
6293,6156,6018,5877,5735,5591,5446,5299,5150,5000,
4848,4694,4539,4383,4226,4067,3907,3746,3583,3420,
3555,3090,2923,2756,2588,2419,2249,2079,1908,1736,
1564,1391,1218,1045,871,697,523,348,174,50,
174,348,523,697,871,1045,1218,1391,1564,1736,
1908,2079,2249,2419,2588,2756,2923,3090,3255,3420,
3583,3746,3907,4067,4226,4383,4539,4694,4848,5000,
5150,5299,5446,5591,5735,5877,6018,6156,6293,6427,
6560,6691,6819,6946,7071,7193,7313,7431,7547,7660,
7771,7880,7986,8090,8190,8290,8386,8480,8571,8660,
8746,8829,8910,8987,9063,9135,9205,9271,9335,9396,
9455,9510,9563,9612,9659,9702,9743,9781,9816,9848,
9875,9902,9925,9945,9961,9975,9986,9993,9998,10000,
9998,9993,9986,9975,9961,9945,9925,9902,9876,9848,
9816,9781,9743,9702,9659,9612,9563,9510,9455,9396,
9335,9271,9205,9135,9063,8987,8910,8829,8746,8660,
8571,8480,8386,8290,8191,8090,7986,7880,7771,7660,
7547,7431,7313,7193,7071,6946,6819,6691,6560,6427,
6293,6156,6018,5877,5735,5591,5446,5299,5150,5000,
4848,4694,4539,4383,4226,4067,3907,3746,3583,3420,
3555,3090,2923,2756,2588,2419,2249,2079,1908,1736,
1564,1391,1218,1045,871,697,523,348,174,50,
174,348,523,697,871,1045,1218,1391,1564,1736,
1908,2079,2249,2419,2588,2756,2923,3090,3255,3420,
3583,3746,3907,4067,4226,4383,4539,4694,4848,5000,
5150,5299,5446,5591,5735,5877,6018,6156,6293,6427,
6560,6691,6819,6946,7071,7193,7313,7431,7547,7660,
7771,7880,7986,8090,8190,8290,8386,8480,8571,8660
};
/*************************函數(shù)聲明**************************/
//void delay_s(uchar x); //延時(shí)xms子程序
void main_init(void); //初始化子程序
void angle(void); //計(jì)算正弦表指針函數(shù)
void Ai_data(void); //計(jì)算定時(shí)器寄存器值的函數(shù)
void judge_Ai(void); //定時(shí)器寄存器值上下限判斷子程序
void PWM_SET(void); //定時(shí)器寄存器賦值子程序
void tb2int(void); //中斷子程序
void main(void); //主函數(shù)
/***********************延時(shí)xms子程序***********************/
//說(shuō)明:本函數(shù)實(shí)現(xiàn)了延時(shí)xms的功能
//輸入:x
//輸出:無(wú)
/*void delay_s(uchar x)
{
uchar n;
while(x!=0)
{
for(n=0;n<=125;n++)
{
x--;
}
}
}
*/
/***********************初始化子程序************************/
//說(shuō)明:本函數(shù)實(shí)現(xiàn)了對(duì)與三相馬達(dá)控制有關(guān)的一些寄存器的初始化
//輸入:無(wú)
//輸出:無(wú)
void main_init(void)
{
prc2=1;
pd8=0x03; //將P80,P81設(shè)置成輸出方式
pd7=0x0ff; //將P72,P73,P74,P75設(shè)置成輸出方式
prc2=0;
invc0=0x0c; //有效中斷輸出的規(guī)定位未規(guī)定,三相PWM輸出模式,
//三角波調(diào)制模式,輸出使能
invc1=0x06; //三相模式1,定時(shí)器B2溢出信號(hào)觸發(fā)定時(shí)器Ai,死區(qū)時(shí)間
//定時(shí)器計(jì)數(shù)源選擇f1/2
ictb2=2; //設(shè)置定時(shí)器B2中斷請(qǐng)求發(fā)生的頻率為2
idb0=0x15; //設(shè)置三相輸出緩沖器0,第6,7位不使用
idb1=0x2a; //設(shè)置三相輸出緩沖器1,第6,7位不使用
ta1mr=0x12; //選取單次工作方式,計(jì)數(shù)源選取f1
ta2mr=0x12; //選取單次工作方式,計(jì)數(shù)源選取f1
ta4mr=0x12; //選取單次工作方式,計(jì)數(shù)源選取f1
tb2mr=0x00; //選取定時(shí)方式,計(jì)數(shù)源選取f1
trgsr=0x45; //定時(shí)器A1,A2,A4選取TB2的溢出觸發(fā)
tb2=c2_data; //設(shè)置定時(shí)器B2的初值
dtt=24; //設(shè)置死區(qū)時(shí)間定時(shí)器DTT(3us)=16MHz(clk)/2*(3us)
}
/*********************計(jì)算正弦表的指針函數(shù)*******************/
//說(shuō)明:本函數(shù)根據(jù)指針跳讀參數(shù)sin_cut確定每次中斷時(shí)指向正弦表sin_tb[]的指針,
// 64個(gè)周期為一個(gè)循環(huán)
//輸入:無(wú)
//輸出:無(wú)
void angle(void)
{
sin_sum=sin_sum+sin_cut;
if(sin_sum>=23040)
{
sin_sum=sin_sum-23040;
}
else
{
}
pointer=sin_sum/64;
}
/*****************計(jì)算定時(shí)器寄存器的值的函數(shù)*****************/
//說(shuō)明:本函數(shù)實(shí)現(xiàn)了對(duì)定時(shí)器寄存器Ai的值的計(jì)算,由于u,v,w相臨兩相之間相位差為120,
// 因此各指針之間相差也為120。
//輸入:無(wú)
//輸出:無(wú)
void Ai_data(void)
{
// uint pwm_u;
pwm_u=c4_data-(uint)((ulong)(modul_data*sin_tb[pointer])/1000000);
pwm_v=c4_data-(uint)((ulong)(modul_data*sin_tb[pointer+120])/1000000);
pwm_w=c4_data-(uint)((ulong)(modul_data*sin_tb[pointer+240])/1000000);
}
/**************定時(shí)器寄存器值的上下限判斷子函數(shù)**************/
//說(shuō)明:本函數(shù)通過(guò)將計(jì)算得到的定時(shí)器寄存器的值與規(guī)定的上下限進(jìn)行比較,最終
// 確定定時(shí)器寄存器Ai,Ai1的值。
//輸入:無(wú)
//輸出:無(wú)
//void judge_Ai(void)
//{
/* uint A1_DATA;
uint A11_DATA;
uint A2_DATA;
uint A21_DATA;
uint A4_DATA;
uint A41_DATA;
*/
// uint pwm_u;
/* if(pwm_u>PWM_max)
{
A1_DATA=PWM_max; //若計(jì)算出的定時(shí)器寄存器A1的值
//大于給定的最大值,則取最大值
A11_DATA=c2_data-A1_DATA;
}
else
{
if(pwm_u<PWM_min)
{
A1_DATA=PWM_min; //若計(jì)算出的定時(shí)器寄存器A1的值
//小于給定的最小值,則取最小值
A11_DATA=c2_data-A1_DATA;
}
else
{
A1_DATA=pwm_u; //否則取計(jì)算得到的定時(shí)器寄存器的值
A11_DATA=c2_data-A1_DATA;
}
}
if(pwm_v>PWM_max)
{
A2_DATA=PWM_max; //若計(jì)算出的定時(shí)器寄存器A2的值
//大于給定的最大值,則取最大值
A21_DATA=c2_data-A2_DATA;
}
else
{
if(pwm_v<PWM_min)
{
A2_DATA=PWM_min; //若計(jì)算出的定時(shí)器寄存器A2的值
//小于給定的最小值,則取最小值
A21_DATA=c2_data-A2_DATA;
}
else
{
A2_DATA=pwm_v; //否則取計(jì)算得到的定時(shí)器寄存器的值
A21_DATA=c2_data-A2_DATA;
}
}
if(pwm_w>PWM_max)
{
A4_DATA=PWM_max; //若計(jì)算出的定時(shí)器寄存器A4的值
//大于給定的最大值,則取最大值
A41_DATA=c2_data-A4_DATA;
}
else
{
if(pwm_w<PWM_min)
{
A4_DATA=PWM_min; //若計(jì)算出的定時(shí)器寄存器A4的值
//小于給定的最小值,則取最小值
A41_DATA=c2_data-A4_DATA;
}
else
{
A4_DATA=pwm_w; //否則取計(jì)算得到的定時(shí)器寄存器的值
A41_DATA=c2_data-A4_DATA;
}
}
}
*/
/*********************定時(shí)器賦值子程序***********************/
//說(shuō)明:本函數(shù)將計(jì)算,判斷是否超過(guò)上下限后得到的定時(shí)器寄存器的值賦給定時(shí)器寄存器。
//輸入:無(wú)
//輸出:無(wú)
//void PWM_SET(void)
//{
/* uint A1_DATA;
uint A11_DATA;
uint A2_DATA;
uint A21_DATA;
uint A4_DATA;
uint A41_DATA;
*/
/* ta1=A1_DATA;
ta11=A11_DATA;
ta2=A2_DATA;
ta21=A21_DATA;
ta4=A4_DATA;
ta41=A41_DATA;
}
*/
/************************中斷子程序**************************/
//說(shuō)明:本函數(shù)完成對(duì)定時(shí)器寄存器Ai和Ai1值的計(jì)算及賦值。
//輸入:無(wú)
//輸出:無(wú)
#pragma INTERRUPT/B tb2int
void tb2int(void)
{
angle(); //計(jì)算正弦表的指針函數(shù)
Ai_data(); //計(jì)算定時(shí)器寄存器的值函數(shù)
// judge_Ai(); //定時(shí)器寄存器值的上下限判斷子函數(shù)
// PWM_SET(); //定時(shí)器賦值子函數(shù)
}
/**************************主函數(shù)****************************/
//說(shuō)明:主要實(shí)現(xiàn)指針跳讀參數(shù)sin_cut及參數(shù)modul_data的計(jì)算,并啟動(dòng)定時(shí)器TB2。
//輸入:無(wú)
//輸出:無(wú)
void main(void)
{
sin_sum=0;
main_init(); //初始化子程序
sin_cut=(360*64)/(carrier_F/output_F);
//計(jì)算連續(xù)兩次指向正弦表的指針之差
modul_data=c4_data*modul_rate;
asm("FCLR I"); //中斷禁止
tb2ic=0x07; //設(shè)置定時(shí)器B2的中斷優(yōu)先級(jí)為7級(jí)
asm("LDIPL #110B"); //中斷使能級(jí)別為6級(jí)
asm("FSET I"); //允許中斷
tb2s=1; //啟動(dòng)定時(shí)器b2
while(1);
}
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -