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

📄 sclk.c

📁 一个两碟控制的VCD的代码,两碟之间的转动及连续播放,已大量生产的CODE.
💻 C
📖 第 1 页 / 共 2 页
字号:
 * in the disk_position variable. * * When the carousel rotates from disk1 to disk5, the CAROUSEL_SENSOR * would have the following pattern. * _   _     _      _   _      _   _       _   _     _   _   _      _   _ *| |_| |___| |____| |_| |____| |_| |_____| |_| |___| |_| |_| |____| |_| |__ ... * stop    disk_1   stop       disk_2      stop       Disk_3         stop *        _   _   _   _      _   _       _   _   _   _   _      _   _ * ...___| |_| |_| |_| |____| |_| |_____| |_| |_| |_| |_| |____| |_| |_...... *          disk_4            stop           disk_5             stop * * Every disk position is represented by the number of spike between every * two STOP (or disk break) pattern and the time between that last spike * of a disk position and the beginning of the STOP pattern.  This time * is the longest between disk1 and its STOP pattern, and shortest * between disk5 and its STOP pattern.  TVM data sheet says this time * should be 300ms for disk1 and 200ms for disk5, and others disks have * timing in between 200ms and 300ms.  The HIGH timing for every spike * of the disk number should be for about 15ms.  The code counts the number  * of 15ms spikes for determining the disk position.   * * This routine is divided into two sections: Powerup and Normal Rotation. * * For powering, the disk rotating in disk1,2,3,4,5 direction.  It will  * stop on the first disk it finds after the powering up position.  If  * there are no disk, it will stop at the last empty position.  If there * is only one disk in the powering up position, the carousel will rotate * all the way around and stop at the powering up position. *  * The second section handles the disk rotation when rotating after the * powerup sequece.  It can rotate in either direction for the number * of disk positions specified in the global variable "home_many_disk". * * The stop sequence is done by toggling one of the two carousel direction * control signals.   * * To Start Rotation: * Setting changer_control_register to 0x8001 would cause the power up * carousel roation sequece. * Setting changer_control_register to 0x8000 would initiate the nomal * disk rotation operation.  Setting changer_control_register to  * 0x8000 | ROTATE_CCW will result in 0x8040 written to the register, * ant causing the carousel to rotate in disk5,4,3,2,1 direction. * The global variable, disk_position, that contains the current disk * position is automatically update in the ISR.  It should be read * only outside of this routine.  * * Notes: The TVM carousel can be rotated in disk1,2,3,4,5 direction or * in the disk5,4,3,2,1 direction.  When rotated in disk1,2,3,4,5 direction, * the number of spike is the actual disk position plus 1. I.e. 1 spike is * disk2, 2 spikes is disk3...5 spickes is disk1. * * Bugs: I have found out that the variable disk_position can not be * update in the main code.  So make sure that disk_position is read * only.  Never found out why it's this way; it's probably the compiler. */int powerup_state; /* state name for powerup rotation Finite State Machine */int rotate_state;  /* state name for post powerup rotation FSM */int half_rotate_state; /* state name for half rotation of OPEN when 			  disk is playing */int spike_counter; /* counting the number of disk position spikes */int first_disk_present;  /* FLAG, 1: power up carousel position has disk; 			    0: no disk */int disk_counter;  /* counts how many disk positions we have gone 		      through powerup rotating FSM */ void rotate_carousel_and_find_position(void){     PI = get_PI();    if (PI & 0x02) { /* can we rotate or not?*/	changer_control_register = 0;	return;    }	    if (changer_control_register & 0x0001) /* do power up */    { 	switch (powerup_state)	{	  case 0:   /* start rotation */	    /* init first_disk_present, spike_counter, and disk_counter */	    first_disk_present = (DISK_PRESENT) ? 0 : 1;	    if (!(first_disk_present)) {		/* double check, abate chances of glitches on EAUX9 */		first_disk_present = (DISK_PRESENT) ? 0 : 1;	    }	    spike_counter = 0;	    disk_counter = 0;                   	    	    /* enable rotation */	    CLEAR_CAROUSEL_CW; 	    SET_CAROUSEL_CCW;      	    powerup_state = 10; /* 1 */	    six_msec_counter = 0;	    break;	    	  case 10:	    if (!(CAROUSEL_SENSOR_HIGH)) {		powerup_state = 1;		six_msec_counter = 0;	    }	    break;	    	  case 1: /* look for the 200msec+ low */	    if (CAROUSEL_SENSOR_HIGH) {		if (six_msec_counter > 25 ) {		    /* found the 200msec+ low */		    powerup_state = 2;		    six_msec_counter = 0;		} else {		    powerup_state = 10; 		    six_msec_counter = 0;		}	    }	    break;	    	  case 2: /* is this a 15msec spike?? */	    if (!(CAROUSEL_SENSOR_HIGH)) {		if (six_msec_counter < 4) {		    /* this is a 15msec spike*/		    powerup_state = 3;		    spike_counter++;		    six_msec_counter = 0;		} else { 		    /* oops, this is not a 15msec spike.  start all over */		    six_msec_counter = 0;		    powerup_state = 10; /* 1; */		}	    }	    break;	    	  case 3: /* is this a 35msec LOW?? or a post position spike 200 msec+ LOW???*/	    if (CAROUSEL_SENSOR_HIGH) {		if ((six_msec_counter > 1)&&(six_msec_counter < 8)) {		    /* found the 35msec low */		    powerup_state = 2;		    six_msec_counter = 0;		} else if (six_msec_counter > 7) {		    /* post spike 200msec+ Low */		    powerup_state = 4;		    disk_position = spike_counter + 1; /* carousel bug, disk_position is spike count+1 */		    if (disk_position == 6) { disk_position = 1; } 		    spike_counter = 0; /* clear spike_counter for next disk position */		    disk_counter++;		    six_msec_counter = 0;		} else if (six_msec_counter < 2) {		    /* glitch !!! start all over */    		    six_msec_counter = 0;		    powerup_state = 1;		}	    }	    break;	    	    /* Wait for 18msec and detect if disk is present.  Start carousel STOP sequence if 	     * 1) disk presents, or 2) looked through all positions and found no disk. */	  case 4:	    if (six_msec_counter > 4) {		have_disk = (DISK_PRESENT) ? 0 : 1; 		if (!(have_disk)) {		    /* double check for disk presence, in case of glitches */		    have_disk = (DISK_PRESENT) ? 0 : 1; 		}		if (((changer_control_register &0x0002)&& (!have_disk))||		    (!(changer_control_register &0x0002))&&		    ( have_disk || ((disk_counter==4)&&(first_disk_present==0)) || 		     ((disk_counter==5)&&(first_disk_present == 1)))){		    /* start carousel STOP sequence */		    SET_CAROUSEL_CW;		    powerup_state = 5; /* continue sending out STOP waveform */		} else {		    /* no disk in current position, look at the next position*/		    six_msec_counter = 0;		    powerup_state = 1;		}	    }	    break; 	    	  case 5: /* sending out STOP waveform,   LOW */	    if (CAROUSEL_SENSOR_HIGH) {		/* CLEAR_CAROUSEL_CW;*/ 		powerup_state = 6;	    } else {		powerup_state = 9;	    }	    break;	    	  case 6: /* continueing STOP waveform,  HIGH */	    if (CAROUSEL_SENSOR_HIGH) {		SET_CAROUSEL_CW;		six_msec_counter = 0;		powerup_state = 7;	    } else {		powerup_state = 9;	    }	    break;	    	  case 7: /* continureing STOP waveform, LOW after 18msec */	    if (CAROUSEL_SENSOR_HIGH){		if (six_msec_counter > 2) {		    CLEAR_CAROUSEL_CW;		    powerup_state = 8;		} else {		    powerup_state = 9;		}	    }	    break;	    	  case 8: /* continueing STOP waveform, HIGH */	    if (CAROUSEL_SENSOR_HIGH) {		SET_CAROUSEL_CW;		powerup_state = 5; /* continueing STOP waveform in state 5 */	    } else {		powerup_state = 9;	    }	    break;	    	  case 9:	    SET_CAROUSEL_CW;	    changer_control_register &= 0x7FFF;	    powerup_state = 0;  /* reset the FSM */	    break;	    	 default:	    break; 	} /* end switch(powerup_state) */	    } else if ((changer_control_register & 0xFF00)==0x8800) {	/* do half rotation for OPEN while disk is playing */	switch (half_rotate_state)	{	  case 0:	    if(changer_control_register & 0x0040)                CLEAR_CAROUSEL_CCW;	    else                CLEAR_CAROUSEL_CW;	    six_msec_counter = 0;	    half_rotate_state = 1;	    break;	    	  case 1:	    if (six_msec_counter > 59) {		SET_CAROUSEL_CW;		SET_CAROUSEL_CCW;		half_rotate_state = 2;	    }	    break;	    	  case 2:	    if(changer_control_register & 0x0040)                CLEAR_CAROUSEL_CCW;	    else                CLEAR_CAROUSEL_CW;	    half_rotate_state = 3;	    break;	    	  case 3:	    SET_CAROUSEL_CW;	    SET_CAROUSEL_CCW;	    six_msec_counter = 0;	    half_rotate_state = 4;	    break;	    	  case 4:	    if (six_msec_counter > 2) {		if(changer_control_register & 0x0040)		    CLEAR_CAROUSEL_CCW;		else		    CLEAR_CAROUSEL_CW;		half_rotate_state = 5;	    }	    break;	    	  case 5:	    SET_CAROUSEL_CW;	    SET_CAROUSEL_CCW;	    half_rotate_state = 0;	    if (loader_state == 5) {		loader_state = 7;	    }	    changer_control_register = 0x0000;	    break;	    	  default:	    break;	}	/* finished half rotation */    } else {  	/* rotate to a position, direction and how much to turn must be given */	switch (rotate_state) 	{	  case 0:	    if (how_many_disk == 0) how_many_disk = 1;	    disk_counter = 0;	    if (changer_control_register & CAROUSEL_CCW) 		CLEAR_CAROUSEL_CCW;      	    else 	       CLEAR_CAROUSEL_CW;	    rotate_state = 1;	    break;	    	 case 1: /* in search for a LOW, any LOW */	    if (!(CAROUSEL_SENSOR_HIGH)) {		rotate_state = 2;		six_msec_counter = 0;	    }	    break;	    	  case 2: /* is this a 200msec+ LOW???? */	    if (CAROUSEL_SENSOR_HIGH) {		if (six_msec_counter > 28) {  		    /* found the 200msec+ LOW, look for 30msec+ HIGH next*/		    rotate_state = 3;		    six_msec_counter = 0;		} else {  		    /* start over, looking for a 200msec+ LOW */		    rotate_state = 1;		}	    }	    break;	    	  case 3:  /* looking for the 18msec+ HIGH */	    if (CAROUSEL_SENSOR_HIGH) {		if (six_msec_counter > 4) {		    disk_counter++;		    /* updating disk_position */		    if (changer_control_register & 0x0300)			;		    else{			if (changer_control_register & CAROUSEL_CCW) {			    disk_position--;			    if (disk_position == 0) { disk_position = 5; }			} else {			    disk_position++;			    if (disk_position == 6) { disk_position = 1; }			}		    }		    if (disk_counter == how_many_disk) {			if(changer_control_register & 0x0200)			{			    changer_control_register &= 0x00ff;			    changer_control_register |= 0x8800;			    rotate_state = 0;			    /* continue on the half rotate */			} else {			    /* finished rotating the number of disks that's asked */			    /* sending out stop sequence */			    have_disk = (DISK_PRESENT) ? 0 : 1;			    if (have_disk == 0) {				/* double check if disk is present */				have_disk = (DISK_PRESENT) ? 0 : 1;			    }			    SET_CAROUSEL_CCW;			    SET_CAROUSEL_CW;			    rotate_state = 4;			}		    } else {			/* more disk rotations required */			rotate_state = 1;		    }		}	    } else {   		/* OOPS! GLITCH? */		rotate_state = 1;	    }	    break;	    	  case 4: /* STOP sequence continues, clearing */	    if (CAROUSEL_SENSOR_HIGH) {		if (changer_control_register & CAROUSEL_CCW) 		    /*CLEAR_CAROUSEL_CCW;      */ SET_CAROUSEL_CCW;		else 		    /* CLEAR_CAROUSEL_CW; */ SET_CAROUSEL_CCW;		rotate_state = 5;	    } else {		rotate_state = 8;	    }	    break;	    	  case 5: /* setting to HIGH */	    if (CAROUSEL_SENSOR_HIGH ) {		if (changer_control_register & CAROUSEL_CCW) 		    SET_CAROUSEL_CCW;      		else 		    SET_CAROUSEL_CW;		rotate_state = 6;		six_msec_counter = 0;	    } else {		rotate_state = 8;	    }	    break;	    	  case 6:  /* setting to LOW after 18 ms */	    if (CAROUSEL_SENSOR_HIGH) {		if (six_msec_counter > 3) {		    if (changer_control_register & CAROUSEL_CCW) 			CLEAR_CAROUSEL_CCW;      		    else 			CLEAR_CAROUSEL_CW;		    rotate_state = 7;		}	    } else {		rotate_state = 8;	    }	    break;	    	  case 7:  /* setting to HIGH */	    if (CAROUSEL_SENSOR_HIGH) { 		if (changer_control_register & CAROUSEL_CCW) 		    SET_CAROUSEL_CCW;      		else 		    SET_CAROUSEL_CW;		rotate_state = 4;		six_msec_counter = 0;	    } else {		rotate_state = 8;	    }	    break;	    	  case 8:	    SET_CAROUSEL_CCW;	    SET_CAROUSEL_CW;                	    rotate_state = 0;	    if(changer_control_register & 0x0100) /* finished half rotate*/	    {		motor_control_register = 0xD000; /* now close the								drawer */		changer_control_register = 0;	    }	    else		changer_control_register &= 0x7FFF;	    break;	} /* end of switch(rotate_state) */    } /* end of if statment */} /* end rotate_carousel_and_find_position() *//* void rotate_drawer_motor() * Controls the In/Out the drawer and the Up/Down of the pickup. * This process is controlled through the motor_control_register. * [1xxx xxxx xxxx xxxx] start motor, it is set by main program * [x?xx xxxx xxxx xxxx] 1: counter clock wise    0: clock wise * [xx?? xxxx xxxx xxxx] 00: rotate by one state, *                       01: rotate by two states, *                       10: rotate by three states, *                       11: rotate by four states. * [xxxx 1xxx xxxx xxxx] motor rotation has started.     * [0xxx xxxx xxxx xxxx] motor stopped, this status is set to 0 by ISR. * */void rotate_drawer_motor(){        static int old_PI, state_counter, target_state;        if (!(motor_control_register & 0x8000)) {	return;    }         if (!(motor_control_register & 0x0800)) {	motor_timer = 0;                      	state_counter = 0;	old_PI = PI;	if (motor_control_register & 0x4000) {	    rotate_motor_CCW;         	} else {	    rotate_motor_CW;	}	target_state = ((motor_control_register >> 12) & 3) + 1;	/* target_state has the number of states that we want to move by */	motor_control_register |= 0x0800;    } else if ((motor_control_register & 0x8800)==0x8800)  {	PI = get_PI();	while (PI != get_PI()) {	    /* double check on PI value */	    PI = get_PI();	}      	while (PI != get_PI()) {	    /* tripple check on PI value */	    PI = get_PI();	}      	while (PI != get_PI()) {	    /* quadruple check on PI value */	    PI = get_PI();	}      	while (PI != get_PI()) {	    /* "sinco" (5th time) check on PI value */	    PI = get_PI();	}      	if (old_PI != PI) { 	    state_counter++;	    if (target_state == state_counter) { 		stop_motor;		motor_control_register &= 0x7FFF;  		if ((loader_state==5)&&(target_state==2) &&		    (!(motor_control_register & 0x4000))) {		    /* finished try OPEN while disk playing, start 1/2 rotate */		    changer_control_register = 0x8800;		    half_rotate_state = 0;		} else if ((loader_state==7) && (target_state==2) &&			   (motor_control_register &0x4000)) {		    loader_state = 5;		}		/*---------------------------*/		else if ((loader_state==3) && (target_state==2) &&			 ((motor_control_register & 0x4000))) {		    /* finished tray OPEN while pickup is down, 		       start 2 position rotate */		    		    how_many_disk = 2; 		    changer_control_register = 0x8000;		    /* 2 position rotate , in state: OPEN, pickup down */		    loader_state = 1;  		    		}  else if ((loader_state==1) && (target_state==2) &&			    (!(motor_control_register &0x4000))) {		    /* finished tray CLOSE while pickup is down, 		       start 3 position rotate */		    		    how_many_disk = 3; 		    changer_control_register = 0x8000;		    /* 3 position rotate , in state: CLOSE, pickup down */		    		    loader_state = 3;  		}				/*--------------------------*/	    } else {     		old_PI = PI;		motor_timer = 0;      	    }	} else {	    if (motor_timer > 400) {		/* 2.4 second timeout, not finalized */		motor_fault_error = 1;            		stop_motor;		motor_control_register &= 0x7FFF;	    }	}    }    return;}int get_PI(void){      int new_PI=0;   /* return value */    if (PI_1_HIGH) /* PI_1 */	new_PI = 0x0001;    if (PI_2_HIGH) /* PI_2 */	new_PI = new_PI | 0x0002;    return new_PI;}#endif /* CUST8_5DISK */#endif /* TVM_MODULE */

⌨️ 快捷键说明

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