www.pudn.com > stepper123.rar > stepper.c


/****************************************************************************/ 
/*                                                                          */ 
/* FILE NAME                                      VERSION                   */ 
/*                                                                          */ 
/* STEPPER.C                                            1.0                 */ 
/*                                                                          */ 
/* DESCRIPTION                                                              */ 
/*                                                                          */ 
/*     JX44B0(S3C44B0X)步进电机实验                                         */ 
/*                                                                          */ 
/*                                                                          */ 
/* DATA STRUCTURES                                                          */ 
/*                                                                          */ 
/* FUNCTIONS :                                                              */ 
/*     在JX44B0教学实验箱进行步进电机控制的实验                             */ 
/*                                                                          */ 
/* DEPENDENCIES                                                             */ 
/*     JX44B0-1                                                             */ 
/*     JX44B0-2                                                             */ 
/*     JX44B0-3                                                             */ 
/*                                                                          */ 
/*                                                                          */ 
/* NAME:                                                                    */ 
/* REMARKS:                                                                 */ 
/*                                                                          */ 
/*								Copyright (C) 2003 Wuhan CVTECH CO.,LTD     */ 
/****************************************************************************/ 
 
/****************************************************************************/ 
/* 学习JX44B0实验箱中的步进电机控制方法:                                   */ 
/****************************************************************************/ 
 
/* 包含文件 */ 
#include "44b.h" 
 
#define STEP_INTERVALE				0x40 
#define STEPER_VALUE_MIN 			0x40 
#define STEPER_VALUE_MAX 			0x1000 
 
#define STEPER_MOTOR_ENABLE         1 
#define STEPER_MOTOR_DISABLE        0 
#define STEPER_MOTOR_CLOCKWISE      0         
#define STEPER_MOTOR_ANTICLOCKWISE  1  
 
#define true						1 
#define false						0 
 
#define STEPER_ENABLE				0x01 
#define STEPER_SINGLE				0x02 
#define STEPER_REVERSE				0x04 
 
#define MIN_STEPER_PLUSE_FREQ		0x300 
#define MAX_STEPER_PLUSE_FREQ		0x100000 
 
#define SET_STEPER_ENABLE(X)						\ 
{ 													\ 
	if(X)											\ 
		steper_control_mask |= (1<<3); 				\ 
	else 											\ 
		steper_control_mask &= ~(1<<3);				\ 
	*(unsigned char *)0x0a000006 = steper_control_mask; \ 
} 
		 
#define SET_STEPER_REVERSE(X)						\ 
{ 													\ 
	if(X)steper_control_mask |= (1<<2); 			\ 
	else steper_control_mask &= ~(1<<2);			\ 
	*(unsigned char *)0x0a000006 = steper_control_mask; \ 
} 
 
#define GEN_PLUSE_HIGH()			{rPDATC |= (1<<11);} 
#define GEN_PLUSE_LOW()				{rPDATC &= (~(1<<11));} 
 
typedef (*ISR_ROUTINE_ENTRY)(void); 
 
char key_get_char(int row, int col); 
void init_interrupt_handler(unsigned int irq_handler); 
void install_isr_handler(int irq_no, void* irq_routine); 
 
void timer1_isr(void); 
void IsrIRQ() __attribute__ ((interrupt("IRQ"))); 
 
static int steper_control_mask = 0xf8; 
 
int  step_status;				/* 当前步进电机的工作状态 */ 
int  step_mode;					/* 模式:单步或循环,正反转 */ 
int  step_freq;					/* 步进频率 */ 
 
/***************************************************************************** 
// Function name	: key_get_char 
// Description	    : 根据键盘行列键值查询键 
//     键盘定义 
//     1         2         3        UP(C) 
//     4         5         6        DOWN(D) 
//     7         8         9        Cancel(E) 
//     0         .(A)      Del(B)   Enter(F) 
// Return type		: char 
// Argument         : int row 
// Argument         : int col 
*****************************************************************************/ 
char key_get_char(int row, int col) 
{ 
	char key; 
	 
	switch( row ) 
	{ 
	case 0: 
		if((col & 0x01) == 0) key = '7';  
		else if((col & 0x02) == 0) key = '1';  
		else if((col & 0x04) == 0) key = '0';  
		else if((col & 0x08) == 0) key = '4';  
		break; 
	case 1: 
		if((col & 0x01) == 0) key = '8';  
		else if((col & 0x02) == 0) key = '2';  
		else if((col & 0x04) == 0) key = 'A'; 
		else if((col & 0x08) == 0) key = '5'; 
		break; 
	case 2: 
		if((col & 0x01) == 0) key = '9';  
		else if((col & 0x02) == 0) key = '3';  
		else if((col & 0x04) == 0) key = 'B';  
		else if((col & 0x08) == 0) key = '6';  
		break; 
	case 3: 
		if((col & 0x01) == 0) key = 'E';  
		else if((col & 0x02) == 0) key = 'C';  
		else if((col & 0x04) == 0) key = 'F';  
		else if((col & 0x08) == 0) key = 'D';  
		break; 
	default: 
		break; 
	} 
	return key; 
} 
 
/******************************************************************** 
// Function name	: stepper_control 
// Description	    : 步进电机使能控制 
// Return type		: void 
// Argument         : int benable 
//     STEPER_MOTOR_ENABLE   -- stepper enable 
//     STEPER_MOTOR_DISABLE  -- stepper disable 
*********************************************************************/ 
void stepper_control(int benable)  
{    
	if(benable == STEPER_MOTOR_ENABLE)  
	{                                 
		steper_control_mask |= (1<<3);  
		*(unsigned char *)0x0a000006 = steper_control_mask;  
	}                                 
	else                              
	{                                 
		steper_control_mask &= (~(1<<3));   
		*(unsigned char *)0x0a000006 = steper_control_mask;  
	}            
} 
 
/******************************************************************** 
// Function name	: stepper_set_direct 
// Description	    : 步进电机方向控制 
// Return type		: void 
// Argument         : int direct 
//     STEPER_MOTOR_CLOCKWISE      -- clockwise direction 
//     STEPER_MOTOR_ANTICLOCKWISE  -- anticlockwise direction 
*********************************************************************/ 
void stepper_set_direct(int direct) 
{ 
	if(direct == STEPER_MOTOR_CLOCKWISE) 
	{ 
		steper_control_mask |= (1<<2); 
		*(unsigned char *)0x0a000006 = steper_control_mask; 
	} 
	else 
	{ 
		steper_control_mask &= (~(1<<2)); 
		*(unsigned char *)0x0a000006 = steper_control_mask; 
	} 
} 
 
/***************************************************************************** 
// Function name	: delay 
// Description	    : 延时子程序 
// Return type		: void 
// Argument         : count,延时的数值 
*****************************************************************************/ 
#define delay(count) {int cnt; for(cnt = 0; cnt <= count; cnt ++);}; 
 
/***************************************************************************** 
// Function name	: Main 
// Description	    : 步进电机驱动程序 
//     键盘定义 
//     1(正反转) 2(使能)   3        UP(加速) 
//     4         5         6        DOWN(减速) 
//     7         8         9        Cancel(退出) 
//     0         .         Del      Enter 
// Return type		: void 
// Argument         : void 
*****************************************************************************/ 
void Main(void) 
{ 
	int bout = 0; 
	int init_rTCNTB1 = STEPER_VALUE_MIN; 
	int port_con_c, port_up_c; 
	 
	int 			row; 
	int 			ascii_key, input_key0, input_key1,input_key2, key_mask = 0x0F; 
	unsigned char*	keyboard_port_scan = (unsigned char*)0x02000000; 
	unsigned char*	keyboard_port_value = (unsigned char*)0x02000002; 
	 
	*(unsigned char *)0x0a000006 = 0xf8; 
 
	// bakup the config of port c 
	port_con_c = rPCONC; 
	port_up_c  = rPUPC; 
	 
	// config the port c 
	rPCONC 	= port_con_c | (1 << 22); 
	rPUPC  	= port_up_c | (1 << 11); 
	 
	/* 设置步进电机初始工作状态 */ 
	step_mode = step_status = 0; 
	 
	/* 设置并启动定时器1 T = rTCNTB0*{prescaler value+1}*{divider value}/MCLK */ 
	rTCFG0  = 0xff;				 
	rTCFG1  = 0x10; 
	rTCNTB1	= 0x200;			/* T = 0x80*{255+1}*{4}/60M = 1/(60*2^3) S */ 
								/* 0x40 <= rTCNTB1 <= 0x1000 */ 
	rTCON	= 0x00000200; 
	rTCON	= 0x00000900; 
	 
    rINTCON	= 0x7;						/* Non-vect,IRQ disable,FIQ disable	*/ 
	 
	init_interrupt_handler((unsigned int)IsrIRQ); 
	install_isr_handler(HandleTIMER1, (void*)timer1_isr); 
 
    rINTMOD	= 0x0; 
    rINTMSK = 0x07ffffff & ~(BIT_GLOBAL|BIT_TIMER1); 
    rINTCON	= 0x5; 
     
	while(1) 
	{ 
		for( row = 0; row < 4; row++) 
		{ 
			*keyboard_port_scan = ~(0x00000001<=4)continue; 
		 
		row = 0; 
			 
		switch( ascii_key ) 
		{ 
			case 'C':  // 加速 
				if((init_rTCNTB1 - STEP_INTERVALE) >= STEPER_VALUE_MIN) 
				{ 
					init_rTCNTB1 -= STEP_INTERVALE; 
				} 
				else 
				{ 
					*((unsigned char*)0x02000006) 	= 0x00; 
					*((unsigned char*)0x02000004) 	= 0xc0; 
					delay(10000); 
					*((unsigned char*)0x02000006) 	= 0xff; 
 
					init_rTCNTB1 = STEPER_VALUE_MIN; 
				} 
			 
				rTCNTB1 = init_rTCNTB1; 
				 
				break; 
					 
			case 'D':  // 减速 
				if((init_rTCNTB1 + STEP_INTERVALE) < STEPER_VALUE_MAX) 
				{ 
					init_rTCNTB1 += STEP_INTERVALE; 
				} 
				else 
				{ 
					*((unsigned char*)0x02000006) 	= 0x00; 
					*((unsigned char*)0x02000004) 	= 0x80; 
					delay(10000); 
					*((unsigned char*)0x02000006) 	= 0xff; 
 
					init_rTCNTB1 = STEPER_VALUE_MAX; 
				} 
					 
				rTCNTB1 = init_rTCNTB1;					 
				break; 
			case '1': // 正反转控制 
				step_mode ^= STEPER_REVERSE; 
				break; 
			case '2': // 使能控制 
				step_mode ^= STEPER_MOTOR_ENABLE; 
				break; 
			case 'E':  // 退出 
			case 'e':  // 退出 
				bout = 1; 
				break; 
			default: 
				bout = bout; 
				break; 
		} 
		 
		if(bout)break; 
	} 
	 
	// 
	rTCON	= 0x00000000; 
	SET_STEPER_ENABLE(false); 
	 
	rPCONC = (1 << 22); 
	 
	while(1);			/* dead here */ 
	 
} 
 
/***************************************************************************** 
// Function name	: rtc_tick_isr 
// Description	    : TICK中断处理程序 
// Return type		: int 
// Argument         : void 
*****************************************************************************/ 
void timer1_isr(void) 
{ 
    rI_ISPC=BIT_TIMER1; 
     
    if((step_mode^step_status)&STEPER_ENABLE) 
    { 
		/* 使能控制 */ 
    	if(step_mode&STEPER_ENABLE) 
    	{ 
    		/* 启动电机*/ 
    		SET_STEPER_ENABLE(true); 
    		step_status |= STEPER_ENABLE; 
    	} 
    	else 
    	{ 
    		/* 关闭电机*/ 
    		SET_STEPER_ENABLE(false); 
    		step_status &= ~STEPER_ENABLE; 
    		 
    		return; 
    	} 
    } 
     
	if((step_mode^step_status)&STEPER_REVERSE) 
	{ 
		/* 翻转控制 */ 
    	if(step_mode&STEPER_REVERSE) 
    	{ 
			SET_STEPER_REVERSE(true); 
    		step_status |= STEPER_REVERSE; 
    	} 
    	else 
    	{ 
			SET_STEPER_REVERSE(false); 
    		step_status &= ~STEPER_REVERSE; 
    	} 
	} 
		 
	/* 电机转动一次 */	 
	GEN_PLUSE_LOW(); 
	GEN_PLUSE_HIGH(); 
 
	if(step_mode&STEPER_SINGLE) 
	{ 
		/* 设置关闭标志,在下一个周期关闭电机*/ 
		step_mode &= ~STEPER_ENABLE; 
	} 
} 
 
/***************************************************************************** 
// Function name	: IsrIRQ 
// Description	    : 非矢量方式下中断的查表处理 
//					  中断地址表位于0x0c7fff00开始的256字节 
// Return type		: void 
// Argument         : void 
*****************************************************************************/ 
void IsrIRQ() 
{ 
	int count = 0; 
	unsigned int isr_pending; 
	unsigned int isr_mask = 0x00000001; 
	 
	unsigned int isr_mask_set = rINTMSK; 
	 
	ISR_ROUTINE_ENTRY isr_routine_entry = (ISR_ROUTINE_ENTRY)0x0; 
	 
	__asm__	( 
		"STMFD  	SP!, {r1,r4-r8}	@ SAVE r1,r4-r10 \n" 
		"nop \n"); 
	 
	isr_pending = (rINTPND & ~isr_mask_set); 
	 
	while(isr_mask) 
	{ 
		if(isr_pending&isr_mask) 
		{ 
			isr_routine_entry = (ISR_ROUTINE_ENTRY)(*(int*)(HandleADC+count)); 
			break; 
		} 
		 
		count+=4; 
		isr_mask <<= 1; 
	} 
	 
	if(isr_routine_entry) (*isr_routine_entry)(); 
	 
	__asm__ ( 
		"LDMFD  	SP!, {r1,r4-r8}	@ RESTORE r1,r4-r10 \n" 
		"nop \n"); 
} 
 
/***************************************************************************** 
// Function name	: init_interrupt_handler 
// Description	    : 非矢量方式下中断向量表初始化处理 
// Return type		: void 
// Argument         : irq_handler 
//					  中断处理函数入口 
*****************************************************************************/ 
void init_interrupt_handler(unsigned int irq_handler)  
{ 
	int i; 
	 
	rINTPND = 0x00000000;							/* 清除所有未决的中断	*/ 
	rI_ISPC = 0x03FFFFFF;  
	 
	for( i = 0; i < 256; i+=4)						/* 清除中断表			*/ 
		*(unsigned int*)(_ISR_STARTADDRESS+i) = 0; 
 
	*(unsigned int*)(HandleIRQ) = irq_handler;		/* 设置IRQ模式处理函数	*/ 
} 
 
/***************************************************************************** 
// Function name	: install_isr_handler 
// Description	    : 非矢量方式下中断向量的安装 
// Return type		: void 
// Argument         : irq_no, 中断号 
//					  irq_routine, 中断处理函数地址 
*****************************************************************************/ 
void install_isr_handler(int irq_no, void* irq_routine) 
{ 
	*(unsigned int*)(irq_no) = (unsigned int)irq_routine; 
}