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

📄 stepper.c

📁 在JX44B0教学实验箱进行步进电机控制的实验 个人觉得很实用
💻 C
📖 第 1 页 / 共 2 页
字号:
//     0         .         Del      Enter
// Return type		: void
// Argument         : void
*****************************************************************************/
void Main(void)
{
    lcd_init();
    lcd_clear_screen(WHITE);			/* 清除整个LCD屏幕					*/
 	lcd_disp_hzk16(100,32,"功能导航",RED);
 	lcd_disp_hzk16(100,64,"一正反转",BLUE);
 	lcd_disp_hzk16(100,96,"二使能",BLUE);
    lcd_disp_hzk16(100,128,"向上为加速",BLUE);
    lcd_disp_hzk16(100,160,"向下为减速",BLUE);
     lcd_disp_hzk16(100,192,"取消为退出!",BLUE);
 	
	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<<row);     	/*将row列置低电平 */
			delay(5000);									/*延时*/
			input_key0 = (*keyboard_port_value) & key_mask;	/*并获取第一次扫描值*/
			if(input_key0 == key_mask)	continue;			/* 没有按键*/
			
			delay(5000);									/*延时*/
			input_key1 = (*keyboard_port_value) & key_mask;	/*第一次获取扫描值*/
			if(input_key1 == key_mask)	continue;			/*抖动*/

			while(1)
			{
				delay(5000);
				input_key2 = (*keyboard_port_value) & key_mask;	/*第三次获取扫描值*/
				if(input_key2 == key_mask)	break;				
			}
			
			ascii_key = key_get_char(row, input_key0);	/* 查表*/
			
			break;
		}
		
		if(row>=4)continue;
		
		row = 0;
			*((unsigned char*) 0x02000006) = 0x00;		
		switch( ascii_key )
		{
			  case 'F':  // 加速
			  	*((unsigned char*)0x02000004) = seg7table[(ascii_key-'0')+0X0A];// 加速
				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 'E':  
		*((unsigned char*)0x02000004) = seg7table[(ascii_key-'0')+0X0A];// 减速
				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': // 正反转控制
			 *((unsigned char*)0x02000004) = seg7table[ascii_key-'0'];
				step_mode ^= STEPER_REVERSE;
				break;
			case '2': // 使能控制
        	*((unsigned char*)0x02000004) = seg7table[ascii_key-'0'];		
				step_mode ^= STEPER_MOTOR_ENABLE;
				break;
			case 'D': *((unsigned char*)0x02000004) = seg7table[(ascii_key-'0')+0X0A]; // 退出
			case 'd': *((unsigned char*)0x02000004) = seg7table[(ascii_key-'0')+0X0A]; // 退出
				bout = 1;
				break;
			default:
			*((unsigned char*)0x02000004) = seg7table[ascii_key-'0'];
				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;
}

⌨️ 快捷键说明

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