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

📄 main._c

📁 一个正在应用的步进电机控制程序,包括电机的调速,正反,细分,通讯控制
💻 _C
📖 第 1 页 / 共 2 页
字号:
/*ICC-AVR application builder : 2004-3-11 12:02:11
// Target : M16
// Crystal: 8.0000Mhz
主程序
******************************************************************************/
#include <iom16v.h>
#include <macros.h>
#include <eeprom.h>
#include <stdlib.h>
#include <math.h>
#include "main.h"
#include "eeprom_l.h"
#include "delay.h"
#include "comm.h"
#include "key.h"

//eeprom 中的数据表
#pragma data:eeprom
/*
{0x0000(2),speed_romaddr(2),state_romaddr(1),pump_tab_romaddr(1),
state_other_romaddr(1)}
*/
unsigned int space_eeprom=0000;
unsigned int speed_eeprom=100;
unsigned char state_eeprom=0;
unsigned char pump_tab_eeprom=1;
unsigned char state_other_eeprom=0;
    							
#pragma data:code
const unsigned char tabsin[]={
0,6,13,19,25,31,37,44,50,56,62,68,74,80,86,92,
98,103,109,115,120,126,131,136,142,147,152,157,162,167,171,176,
180,185,189,193,197,201,205,208,212,215,219,222,225,228,231,233,
236,238,240,242,244,246,247,249,250,251,252,253,254,254,255,255,
255,255,255,254,254,253,252,251,250,249,247,246,244,242,240,238,
236,233,231,228,225,222,219,215,212,208,205,201,197,193,189,185,
180,176,171,167,162,157,152,147,142,136,131,126,120,115,109,103,
98,92,86,80,74,68,62,56,50,44,37,31,25,19,13,6,
};
const unsigned char tabcos[]={  
255,255,255,254,254,253,252,251,250,249,247,246,244,242,240,238,
236,233,231,228,225,222,219,215,212,208,205,201,197,193,189,185,
180,176,171,167,162,157,152,147,142,136,131,126,120,115,109,103,
98,92,86,80,74,68,62,56,50,44,37,31,25,19,13,6,
0,6,13,19,25,31,37,44,50,56,62,68,74,80,86,92,
98,103,109,115,120,126,131,136,142,147,152,157,162,167,171,176,
180,185,189,193,197,201,205,208,212,215,219,222,225,228,231,233,
236,238,240,242,244,246,247,249,250,251,252,253,254,254,255,255, 
};

#pragma data:data

//全局变量
unsigned int        speed;	  		  //16位速度寄存器
unsigned int   		out_ctr;		  //16位AD转换值寄存器
unsigned int        pull_number;       //闸门时间的脉冲数
unsigned int  	    time_da;		  //16位D/A时间寄存器
unsigned int        time_da0;
unsigned char       key;	 		  //按键值
unsigned char 		da_counter;		  //8位计数器:纪录正在读取的细分表位置
unsigned char 		micros_nu;		  //8位寄存器:纪录细分数如4,8,16,32,64,128,256
unsigned char  		micros_nu0;       //最终纪录细分数
unsigned char       key_state;        //1:禁止      0:允许
//key_state.0       run/stop
//key_state.1 		cw/ccw
//key_state.2 		max
//key_state.3 		enter
//key_state.4		
unsigned char       key_counter;      //键盘加减计数器
unsigned long       disp_time_counter0;
unsigned long       disp_time_counter1;
unsigned char 		add_dec_nu;
unsigned char       ac_bd_state;
unsigned char 		state;  		  //软件位状态寄存器
//state.0 正反转状态位					  			1正转    0反转 						  			
//state.1 全速标志   								1全速    0正常
//state.2 
//state.3 启停                                      1启      0停
//state.4 
//state.5 
//state.6 
//state.7 
unsigned char state_other;//软件位状态寄存器
//state.2 显示方式									1流量    0转速
//state.4 脚踏开关标志位  							1脉冲    0电平
//state.5 外控方式        							1关      0开
unsigned char       state0;		        //软件位状态寄存器0
//state0.0 校正体积改变标志							1改变    0无改变	  
//state0.1 电机abcd相工作状态位		   				1为ab相  0为cd相 
//state0.2 测试模式使能位  				  			1使能    0禁止
//state0.3 在旋转编码开关控制函数里是否为第一次旋转 1第一次,0连续
//state0.4 定时分配标志								1分配    0停止
//state0.5 接收消息有效标志
//state0.6 显示            							1转速    0流量
//state0.7 初始化启停                               1启      0停   
extern unsigned char state2;    
//state2.0 disable_data    1:输入数据无效  			0:有效;
//state2.1 remote		   1:遥控输入有效  			0:本地输入有效
//state2.2 				   1:外控关		            0:外控开
//state2.3    		 	   1:键盘+10       	 		0:键盘+1  
//state2.4				   1:允许输入数据			0:禁止输入数据 
//state2.5				   1:允许					0:停机
//state2.6 				   1:无外控模块             0:有外控模块
//state2.7 p99			   1:P99指令使能   	 		0:禁止
extern unsigned char state1;
//state1.7                 1:电流					0:电压
unsigned char in_out_state;
unsigned char in_out_number;
unsigned char wrong;
/*
0正常
1数值下溢出
2数值上溢出
3
*/
unsigned char counter;
unsigned int speed_pull;
extern unsigned char pump_tab;

//定义中断向量
#pragma interrupt_handler time1_int:iv_TIMER1_COMPA
#pragma interrupt_handler time2_int:iv_TIMER2_COMP
#pragma interrupt_handler pull_int:iv_INT0


/******************************************************
D/A出细分波形中断函数(定时器1比较匹配中断)
******************************************************/
void time1_int(void)
{
unsigned char i;
unsigned char j;
if (micros_nu==micros_nu0)
   {time_da0=time_da;}
else 
   {if (da_counter==128)
       {
	   micros_nu0=micros_nu;
	   time_da0=time_da;
	   }
   }
OCR1A=time_da0;
if (da_counter>=128)
   {da_counter=0;} 
i=tabsin[da_counter];
j=tabcos[da_counter];
PORTD&=~(1<<DA_CS);
PORTD&=~(1<<DA_AB);
DATA_OUT=i;                     //送正弦值
asm("nop");
PORTA&=~(1<<DA_WR);
PORTA|=(1<<DA_WR);
PORTD|=(1<<DA_AB);
DATA_OUT=j;                     //送正弦值
asm("nop");
PORTA&=~(1<<DA_WR);
PORTA|=(1<<DA_WR);
PORTD|=(1<<DA_CS);
if ((state|0b11111110)==0b11111110)           //判断正反转
  {											  //正转
  if (ac_bd_state==0)         //ac相处理
    {
	if (da_counter==0)
	   {
	   PORTC&=~(1<<DA_SIN);
	   PORTC&=~(1<<DA_COS);
	   ac_bd_state=1;
	   }
	else 
	   {
	   if (da_counter==64)
	   	  {
		  PORTC&=~(1<<DA_SIN);
	      PORTC|=(1<<DA_COS);
		  }
	   }	
	}
  else 			   		  			 //bd相处理
    {
	if (da_counter==0)
	   {
	   PORTC|=(1<<DA_SIN);
	   PORTC|=(1<<DA_COS);
	   ac_bd_state=0;
	   }
	else 
	   {
	   if (da_counter==64)
	   	  {
		  PORTC|=(1<<DA_SIN);
	      PORTC&=~(1<<DA_COS);
		  }
	   }		 
    }
  }
else  		  	   		  			 //反转
  {
  if (ac_bd_state==0)         //ac相处理
    {
	if (da_counter==0)
	   {
	   PORTC&=~(1<<DA_SIN);
	   PORTC|=(1<<DA_COS);
	   ac_bd_state=1;
	   }
	else 
	   {
	   if (da_counter==64)
	   	  {
		  PORTC&=~(1<<DA_SIN);
	      PORTC&=~(1<<DA_COS);
		  }
	   }	
	}
  else 			   		  			 //bd相处理
    {
	if (da_counter==0)
	   {
	   PORTC|=(1<<DA_SIN);
	   PORTC&=~(1<<DA_COS);
	   ac_bd_state=0;
	   }
	else 
	   {
	   if (da_counter==64)
	   	  {
		  PORTC|=(1<<DA_SIN);
	      PORTC|=(1<<DA_COS);
		  }
	   }		 
    }
  }
if (micros_nu0==32)	 	  			 		   	//根据细分数对地址指针步进
   {da_counter++;}
else
   {
   if (micros_nu0==16)
      {da_counter=da_counter+2;}
   else 
   	  {
	  if (micros_nu0==8)
	     {da_counter=da_counter+4;}
	  else
	     {
		 if (micros_nu0==4)
		 	{da_counter=da_counter+8;}
	     else
		    {
			if (micros_nu0==2)
			   {da_counter=da_counter+16;}
			else
			   {
			   if (micros_nu0==1)
			      {da_counter=da_counter+32;}
			   }
			}
		 }
	  }
   }
}

/******************************************************
测量脉冲闸门时间波形中断函数(定时器2比较匹配中断)20-12KHZ  1-600RPM
******************************************************/
void time2_int(void)
{
//200MS闸门
counter++;
if (counter==6)
  {OCR2=32;}
if (counter==7)
  {
  speed_pull=pull_number;
  pull_number=0;
  counter=0;
  OCR2=0XFF;
  }
}
/******************************************************
测量脉冲数中断函数(外部INT0中断)
******************************************************/
void pull_int(void)
{
pull_number++;
if (pull_number>2400)
  {pull_number=2400;}
}
/****************************************************************
                             定时器1初始化函数
****************************************************************/
void timer1_init(void)
{
 TCCR1B = (1<<CS10)|(1<<WGM12); 	 		  //time1的控制寄存器B,CTC模式,clk=系统时钟
 TIMSK &=~(1<<OCIE1A);                        //定时中断屏蔽寄存器
}

/****************************************************************
                             定时器2初始化函数
****************************************************************/
void timer2_init(void)
{
TCCR2=(1<<CS20)|(1<<CS21)|(1<<CS22)|(1<<WGM21);
OCR2=0XFF;
}
/****************************************************************
                             INT0初始化函数
****************************************************************/
void int0_init(void)
{
DDRD&=~(1<PULL_IN);
MCUCR=(1<<ISC01)|(1<<ISC00);
}


/****************************************************************
端口初始化
****************************************************************/
void port_init(void)
{
 //PORTA = 0xff;
 //DDRA  = 0xdf;
 //PORTB = 0x00;
 //DDRB  = 0x00;
 //PORTC = 0b01111110;             
 //DDRC  = 0b10000001;
 //PORTD = 0xff;
 //DDRD  = 0x00;
PORTC&=~(1<<INT);
DDRC |=(1<<INT);
}

/******************************************************
脉冲输入开始函数
******************************************************/
void pull_start(void)
{
GICR|=(1<<INT0);
TIMSK|=(1<<OCIE2);
pull_number=0;
counter=0;
OCR2=0XFF;
}
/******************************************************
脉冲输入开始函数
******************************************************/
void pull_stop(void)
{
GICR&=~(1<<INT0);
TIMSK&=~(1<<OCIE2);
}
/******************************************************

⌨️ 快捷键说明

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