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

📄 cam_control_fw.c

📁 This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY without ev
💻 C
📖 第 1 页 / 共 2 页
字号:
						CLEAR_HSNAK();					} else {						EP0_STALL();					}					break;				case SET_CONFIG_REQUEST:					/* only one configuration is supported */					if (sdata->bmRequestType == 0 && sdata->wValueL == 0x01) {						CLEAR_HSNAK();					} else {						EP0_STALL();					}					break;				case GET_INTERFACE_REQUEST:					/* only one interface */					if(sdata->bmRequestType == 0x81 &&						sdata->wIndexL == 0x00 &&						sdata->wLengthL == 0x01) { 						in0buf[0] = 0;						IN0BC = 0x01;						CLEAR_HSNAK();					} else {						EP0_STALL();					}					break;				case SET_INTERFACE_REQUEST:					set_interface();					break;				default:					EP0_STALL();					break;			}		} else {			EP0_STALL();		}	} else if (IN07IRQ & 0x01) {		/* IN 0 interrupt */		IN07IRQ = 0x01;	} else if (OUT07IRQ & 0x01) {		/* OUT 0 interrupt */		OUT0BC = 0;		OUT07IRQ = 0x01;  	} else if (OUT07IRQ & 0x02) {		/* OUT 1 interrupt */		endpoint1_out();		OUT1BC = 0;		OUT07IRQ = 0x02;	} else if (IN07IRQ & 0x02) {		/* IN 1 interrupt */		IN07IRQ = 0x02;		if (ep1in_pending) {			ep1in_pending = 0;			send_cc_info();		}	} 	/* reset - don't reset, servers may go crazy */	if (USBIRQ & 0x10){	 USBIRQ = 0x10;	}}/**************************************************** * reset_ezusb ****************************************************/static void reset_ezusb(void){	EA = 0;          /* disable global interrupts */	USBCS &= 0xF3;   /* Clear DISCON, DISCOE */	wait_msec(200);  /* give host plenty of time to respond to disconnect */	USBBAV = 0;      /* clear autovectoring and break reporting         */	USBIRQ = 0xFF;   /* clear SUDAV interrupt and all other interrupts  */	USBIEN = 0x11;   /* enable SUDAV interrupt and RESET interrupt      */	IN07IRQ = 0xFF;  /* clear all IN interrupts       */	IN07IEN = 0x03;  /* enable IN0 & IN1 interrupts   */	IN07VAL = 0x03;  /* make endpoint IN0 & IN1 valid */	OUT07IRQ = 0xFF; /* clear all OUT interrupts         */	OUT07IEN = 0x03; /* enable OUT0 & OUT1 interrupts    */	OUT07VAL = 0x03; /* make endpoint OUT0 & OUT1  valid */  	USBCS |= 0x06;   /* Set DISCOE to enable pullup resistor 							* Set RENUM so that 8051 handles USB requests							*/	PORTACFG &= ~0x80;   /* port A7 has LED attached for blinking */	OEA |= 0x80;	OUTA &= ~0x80;       /* initial state of LED is off */	PORTCCFG &= ~0x08;   /* on DeVaSys board blink port C3 */	OEC |= 0x08;	OUTC |= ~0xF7;       /* initial state of LED is off (led is tied to +v) */	                     /* so bring port high to turn it off               */	OUTC &= 0xF7;       /* ON */	PORTBCFG &= ~0x0C;   /* port B2 is horizontal servo & B3 is vertical */	OEB |= 0x0C;	EUSB = 1;        /* enable USB interrupt     */	EA = 1;          /* enable global interrupts */}/**************************************************** * set up the timers to control the servos ****************************************************/static void init_timers(void) critical{	unsigned short usecs;	timer1_action = STOP_BOTH_PULSES;	timer1_usecs_remaining = 0;	/* configure initial pulse widths for each timer */	usecs = SERVO_INTERRUPT_TIME(pulse_frequency);	TH0 = HI_BYTE(usecs);	TL0 = LOW_BYTE(usecs);	usecs = SERVO_INTERRUPT_TIME(center_usecs);	TH1 = HI_BYTE(usecs);	TL1 = LOW_BYTE(usecs);	/* configure timer0 and timer1 */	TMOD = 0x11;	TCON |= 0x50;	/* allow interrupts from timers */	ET0 = 1;	ET1 = 1;	/* start servo pulses */	HORIZONTAL_SERVO_ON();	VERTICAL_SERVO_ON();}/**************************************************** * interrupt runs every 20 milli-seconds, starts * a new pulse on each servo, and re-starts pulse  * duration timers ****************************************************/static void timer0_isr(void) interrupt 1 using 2 critical{	/* stop the timers */	TCON &= ~0x50;	if (pwm_message.new_command) {		/* new horizontal or vertical postion has been given */		final_horizontal_pos = pwm_message.horizontal_pos;		final_vertical_pos = pwm_message.vertical_pos;		pwm_message.new_command = 0;	}#if DELAY_PER_PERIOD   if (servo_delay_count++ >= DELAY_PER_PERIOD)#endif /* DELAY_PER_PERIOD */	{		if (current_horizontal_pos < final_horizontal_pos) {			current_horizontal_pos += 1;		} else if (current_horizontal_pos > final_horizontal_pos) {			current_horizontal_pos -= 1;		}		if (current_vertical_pos < final_vertical_pos) {			current_vertical_pos += 1;		} else if (current_vertical_pos > final_vertical_pos) {			current_vertical_pos -= 1;		}#if DELAY_PER_PERIOD		servo_delay_count = 0;#endif /* DELAY_PER_PERIOD */	} 	/* set timer0 to pulse interval */	usecs = SERVO_INTERRUPT_TIME(pulse_frequency);	TH0 = HI_BYTE(usecs);	TL0 = LOW_BYTE(usecs);	/* determine which pulse ends first and set the timer to expire	 * at that time, the timer will be started again for the remaining	 * portion of the longer timer period	 */	if (current_vertical_pos < current_horizontal_pos)	{		POSITION_TO_USEC(current_vertical_pos, usecs);		POSITION_TO_USEC(current_horizontal_pos, timer1_usecs_remaining);		timer1_action = HORIZONTAL_TIME_REMAINING;	}	else if (current_horizontal_pos < current_vertical_pos)	{		POSITION_TO_USEC(current_horizontal_pos, usecs);		POSITION_TO_USEC(current_vertical_pos, timer1_usecs_remaining);		timer1_action = VERTICAL_TIME_REMAINING;	}	else /* (current_vertical_pos == current_horizontal_pos) */	{		/* NOTE: we invoke POSITION_TO_USEC twice below to keep the code paths		 * the same length of time... otherwise the servos jitter when		 * the vertical and horizontal degrees equal		 */		POSITION_TO_USEC(current_horizontal_pos, usecs);		POSITION_TO_USEC(current_horizontal_pos, usecs);		timer1_action = STOP_BOTH_PULSES;	}	/* the code below is not really needed if the vertical and horizontal	 * degrees are the same... it is here to keep code paths the same,	 * see NOTE above.	 */	timer1_usecs_remaining -= usecs;	timer1_usecs_remaining = SERVO_INTERRUPT_TIME(timer1_usecs_remaining);	th1_remaining = HI_BYTE(timer1_usecs_remaining);	tl1_remaining = LOW_BYTE(timer1_usecs_remaining);	/* timer1 time to stop shortest pulse */	usecs = SERVO_INTERRUPT_TIME(usecs);	TH1 = HI_BYTE(usecs);	TL1 = LOW_BYTE(usecs);	/* start pulse on both servo ports */	HORIZONTAL_SERVO_ON();	VERTICAL_SERVO_ON();	/* start both timers */	TCON |= 0x50;#if HEART_BEAT_A7	/* blink port A7, we should be running this ISR at 20msec	 * intervals so below code should cause A7 to blink every second 	 */	{#define ON_PERIOD 50    /* 50*20usec == 1sec */		idata static int i = 0;		if (i<ON_PERIOD) {			if (i==0) {				OUTA &= 0x7F; /* off */			}			i++;		} else if (i<(2*ON_PERIOD)) {			if (i==ON_PERIOD) {				OUTA |= 0x80; /* on  */			}			i++;			if (i==(2*ON_PERIOD)) {				i=0;			}		} 	}#endif /* HEART_BEAT */#if HEART_BEAT_C3	/* blink port C3, we should be running this ISR at 20msec	 * intervals so below code should cause C3 to blink every second 	 */	{#define ON_PERIOD 50    /* 50*20usec == 1sec */		idata static int i = 0;		if (i<ON_PERIOD) {			if (i==0) {				OUTC |= 0x08; /* off (high) */			}			i++;		} else if (i<(2*ON_PERIOD)) {			if (i==ON_PERIOD) {				OUTC &= 0xF7; /* on (low) */			}			i++;			if (i==(2*ON_PERIOD)) {				i=0;			}		} 	}#endif /* HEART_BEAT */#if DATA_BEAT_A7	if (OUTA & ~0x7F) /* A7 is on */ {		idata static int i = 0;		if (i++>=3) /* 60+ usec */ {			OUTA &= 0x7F; /* turn port A7 off */			i = 0;		}	}#endif /* DATA_BEAT_A7 */#if DATA_BEAT_C3	if (!(OUTC & 0x08)) /* C3 is on (low) */ {		idata static int i = 0;		if (i++>=3) /* 60+ usec */ {			OUTC |= 0x08; /* turn port C3 off (high) */			i = 0;		}	}#endif /* DATA_BEAT_A7 */}/**************************************************** * horizontal servo timer ****************************************************/static void timer1_isr(void) interrupt 3 using 2 critical{	/* stop timer1 */	TCON &= ~0x40;	/* NOTE: this is not efficient as it could be - the code is	 * organized to keep the duration the same between actions.	 * we still get a bit of jitter when the servo horizontal	 * and vertical degrees cross...	 */	TH1 = th1_remaining;	TL1 = tl1_remaining;	if (timer1_action == HORIZONTAL_TIME_REMAINING) {		TCON |= 0x40;		VERTICAL_SERVO_OFF();	} else if (timer1_action == VERTICAL_TIME_REMAINING) {		TCON |= 0x40;		HORIZONTAL_SERVO_OFF();	} else /* STOP_BOTH_PULSES */ {		HORIZONTAL_SERVO_OFF();		VERTICAL_SERVO_OFF();	}	timer1_action = STOP_BOTH_PULSES;}/**************************************************** * _sdcc_external_startup() ****************************************************/byte _sdcc_external_startup(){	ISOCTL |= 0x01;  /* Disable ISO, see trm v1.9 page 3-3 (56)          */						  /* this gives us the memory at 0x2000 to 0x27FF     */	/*	{_asm		mov   sp,#0x2200;	_endasm;	}	*/	return (0);}/**************************************************** * main () * Basic initialization, re-enumeration and the reset ****************************************************/int main(void){	/* init variables */	center_usecs    = SERVO_PULSE_TIME(CENTER_USECS);	pulse_frequency = SERVO_PULSE_TIME(PULSE_FREQUENCY);	current_horizontal_pos = 0;	current_vertical_pos = 0;	ep1in_pending = 0;	pwm_message.new_command = 1;	pwm_message.horizontal_pos = 0;	pwm_message.vertical_pos = 0;#if DELAY_PER_PERIOD   servo_delay_count = 0;#endif /* DELAY_PER_PERIOD */	init_timers();	reset_ezusb();	/* blink_portA7(2, 1); */	while (1) { };}

⌨️ 快捷键说明

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