⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 e3phase.c.bak

📁 该程序实现了三菱M16C/62单片机的三相马达控制用的定时功能
💻 BAK
字号:
/**************三相马达控制用定时功能测试程序***************/
//文件名:e3phase.c
//说明:  本程序联合利用定时器A1,A2,A4和B2,产生驱动三相马达的电压波形(SPWM),
//	  完成对三菱M16C/6N系列单片机的三相马达控制用的定时功能的测试。晶振频率为16MHz。
//程序员:文武松
//时间:  05-04-09

/***********************包含的头文件************************/
#include "sfr6n.h"		//NOTE:在三菱单片机的C语言中,头文件必须用引号

/*************************宏定义****************************/
#define uint unsigned int
#define uchar unsigned char
#define ulong unsigned long

#define CLK 16			//晶振频率16MHz
#define modul_rate 80		//调制比(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;			//连续两次指向正弦表的指针之差
uint sin_sum;			//指针记忆单元
uint pointer;			//正弦表指针

uint pwm_v;			//v相定时器寄存器值
uint pwm_w;			//w相定时器寄存器值
uint pwm_u;			//u相定时器寄存器值

/*uint A1_DATA;			//定时器寄存器A1缓冲器
uint A11_DATA;			//定时器寄存器A11缓冲器
uint A2_DATA;			//定时器寄存器A2缓冲器
uint A21_DATA;			//定时器寄存器A21缓冲器
uint A4_DATA;			//定时器寄存器A4缓冲器
uint A41_DATA;			//定时器寄存器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
};

/*************************函数声明**************************/
//void delay_s(uchar x);			//延时xms子程序
void main_init(void);			//初始化子程序
void angle(void);			//计算正弦表指针函数
void Ai_data(void);			//计算定时器寄存器值的函数
void judge_Ai(void);			//定时器寄存器值上下限判断子程序
void PWM_SET(void);			//定时器寄存器赋值子程序
void tb2int(void);			//中断子程序
void main(void);			//主函数

/***********************延时xms子程序***********************/
//说明:本函数实现了延时xms的功能
//输入:x
//输出:无
/*void delay_s(uchar x)
{
	uchar n;
	while(x!=0)
	{
		for(n=0;n<=125;n++)
		{
			x--;
		}
	}
}
*/
/***********************初始化子程序************************/
//说明:本函数实现了对与三相马达控制有关的一些寄存器的初始化
//输入:无
//输出:无
void main_init(void)
{
	prc2=1;
	pd8=0x03;			//将P80,P81设置成输出方式
	pd7=0x0ff;			//将P72,P73,P74,P75设置成输出方式
	prc2=0;
	
	invc0=0x0c;			//有效中断输出的规定位未规定,三相PWM输出模式,
					//三角波调制模式,输出使能
	invc1=0x06;			//三相模式1,定时器B2溢出信号触发定时器Ai,死区时间
					//定时器计数源选择f1/2
	ictb2=2;			//设置定时器B2中断请求发生的频率为2
	
	idb0=0x15;			//设置三相输出缓冲器0,第6,7位不使用
	idb1=0x2a;			//设置三相输出缓冲器1,第6,7位不使用
	
	ta1mr=0x12; 			//选取单次工作方式,计数源选取f1
	ta2mr=0x12; 			//选取单次工作方式,计数源选取f1
	ta4mr=0x12; 			//选取单次工作方式,计数源选取f1
	tb2mr=0x00; 			//选取定时方式,计数源选取f1
	
	trgsr=0x45; 			//定时器A1,A2,A4选取TB2的溢出触发
	tb2=c2_data; 			//设置定时器B2的初值
	dtt=24; 			//设置死区时间定时器DTT(3us)=16MHz(clk)/2*(3us)
}

/*********************计算正弦表的指针函数*******************/
//说明:本函数根据指针跳读参数sin_cut确定每次中断时指向正弦表sin_tb[]的指针,
//	64个周期为一个循环
//输入:无
//输出:无
void angle(void)
{
	sin_sum=sin_sum+sin_cut;
	if(sin_sum>=23040)
	{
		sin_sum=sin_sum-23040;
	}
	else
	{
	}
	pointer=sin_sum/64;
}

/*****************计算定时器寄存器的值的函数*****************/
//说明:本函数实现了对定时器寄存器Ai的值的计算,由于u,v,w相临两相之间相位差为120,
//	因此各指针之间相差也为120。
//输入:无
//输出:无
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);
}

/**************定时器寄存器值的上下限判断子函数**************/
//说明:本函数通过将计算得到的定时器寄存器的值与规定的上下限进行比较,最终
//	确定定时器寄存器Ai,Ai1的值。
//输入:无
//输出:无
//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;		//若计算出的定时器寄存器A1的值
						//大于给定的最大值,则取最大值	
		A11_DATA=c2_data-A1_DATA;
	}
	else 
	{
		if(pwm_u<PWM_min)
		{
			A1_DATA=PWM_min;	//若计算出的定时器寄存器A1的值
						//小于给定的最小值,则取最小值
			A11_DATA=c2_data-A1_DATA;
		}
		else
		{
			A1_DATA=pwm_u;		//否则取计算得到的定时器寄存器的值
			A11_DATA=c2_data-A1_DATA;
		}
	}
	
	if(pwm_v>PWM_max)
	{
		A2_DATA=PWM_max;		//若计算出的定时器寄存器A2的值
						//大于给定的最大值,则取最大值	
		A21_DATA=c2_data-A2_DATA;
	}
	else 
	{
		if(pwm_v<PWM_min)
		{
			A2_DATA=PWM_min;	//若计算出的定时器寄存器A2的值
						//小于给定的最小值,则取最小值
			A21_DATA=c2_data-A2_DATA;
		}
		else
		{
			A2_DATA=pwm_v;		//否则取计算得到的定时器寄存器的值
			A21_DATA=c2_data-A2_DATA;
		}
	}
	
	if(pwm_w>PWM_max)
	{
		A4_DATA=PWM_max;		//若计算出的定时器寄存器A4的值
						//大于给定的最大值,则取最大值	
		A41_DATA=c2_data-A4_DATA;
	}
	else 
	{
		if(pwm_w<PWM_min)
		{
			A4_DATA=PWM_min;	//若计算出的定时器寄存器A4的值
						//小于给定的最小值,则取最小值
			A41_DATA=c2_data-A4_DATA;
		}
		else
		{
			A4_DATA=pwm_w;		//否则取计算得到的定时器寄存器的值
			A41_DATA=c2_data-A4_DATA;
		}
	}
}
*/
/*********************定时器赋值子程序***********************/
//说明:本函数将计算,判断是否超过上下限后得到的定时器寄存器的值赋给定时器寄存器。
//输入:无
//输出:无
//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;
}
*/
/************************中断子程序**************************/
//说明:本函数完成对定时器寄存器Ai和Ai1值的计算及赋值。
//输入:无
//输出:无
#pragma INTERRUPT/B tb2int
void tb2int(void)
{
	angle();			//计算正弦表的指针函数
	Ai_data();			//计算定时器寄存器的值函数
//	judge_Ai();			//定时器寄存器值的上下限判断子函数
//	PWM_SET();			//定时器赋值子函数
}

/**************************主函数****************************/
//说明:主要实现指针跳读参数sin_cut及参数modul_data的计算,并启动定时器TB2。
//输入:无
//输出:无
void main(void)
{
	sin_sum=0;
	main_init();				//初始化子程序
	
	sin_cut=(360*64)/(carrier_F/output_F);
					//计算连续两次指向正弦表的指针之差
	modul_data=c4_data*modul_rate;
	
	asm("FCLR I");			//中断禁止
	tb2ic=0x07;			//设置定时器B2的中断优先级为7级
	asm("LDIPL #110B");		//中断使能级别为6级
	asm("FSET I");			//允许中断
	
	tb2s=1;				//启动定时器b2
	while(1);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -