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

📄 diag.c

📁 example of communication between the Cerebellum 16f877 pic board and the CMUcam
💻 C
字号:
/* This is a diagnostic program that tests the i/o for the Cerebellum board.
   It is a menu-driven program with the following tests implemented:


	1 - Servo Motor Test
	2 - Analog Input Test
	3 - LED Test
	4 - Button Test
	5 - PWM Motor Test

The details about each test are described below.
*/

#include "cerebv41.h" // load declarations
#include "cerebv41.c" // load useful cerebellum functions
#define ENTER 13


/* 
	standardizeInput(int a, int b, int c) - 	This takes in a character array in the form of 3
 								integers, manipulates the integers to determine the desired 3 digit
 								number and returns this position as an interger.

*/

int standardizeInput(int a, int b, int c)
{
	int toReturn;

	// 128 is used as 'empty' value as it is a nonprinting character
	if(c == 128)		
 	{
		if(b == 128)
		{
			if(a == 128)
			{
				return 0;		// if no value was specified, do not move servo
			}
			else				// 1 digit number
				return (a - 48);
		}
		else		// 2 digit number
		{
			toReturn = 10 * (a - 48) + (b - 48);			
			return toReturn;
		}
	}
	else		// 3 digit number
	{	
			toReturn = 100 * (a - 48) + 10 * (b - 48) + (c - 48);			
			return toReturn;
	}


}

/* 	
	printInteger(int toPrint) -	Takes an integer value and displays it to terminal window by converting int to a
 						char 

*/

void printInteger(int toPrint)
{
	char a = toPrint;
	ser_writechar(a);
}

/*
	moveServo() - 	Prompts user for which port the servo to be tested is plugged into
				and then allows the user to move the specified servo by typing in
				a desired position.  To return to the main menu, the user can type 'q'.
*/

void moveServo()
{
	char c;
	char d;
	char e = ENTER;
	char arr[3];
	int i;

	int continueTesting = 1;	// signals when user wants to quit moveServo() 
	int continueReading = 1;	// signals when user has finished entering position

	int desiredPos = 0;
	int digits = 0;

	servo_init(); // start up servo control
	servo_state = 1;

	set_bit(INTCON, GIE); // start up interrupts- required for servo control
	servo_mask = 11111111b; // set up all D0-D7 pins for servo control

	ser_putstring("\n\rPort to be tested (0-7):");

	c = ser_rcv();
	d = c - 48;

	while(d > 7 || d < 0)
	{	
		c = ser_rcv();
		d = c - 48;
	}

	while(continueTesting)
	{	
		ser_putstring("\n\rEnter servo pos: ");
		continueReading = 1;
		digits = 0;		
		for(i = 0; i < 3; i++)		// clear contents of character array
			arr[i] = 128;		// use 128 as 'empty' value as it is a nonprinting character

		while(continueReading)
		{
			c = ser_rcv();		// wait for user input

			if(c == 'q')		// quit to main menu
			{
				continueTesting = 0;
				continueReading = 0;
				ser_putstring("\n\r");
				return;
			}
			else if(c == e)		// user has hit 'enter' and process input to determine desired position
			{
				continueReading = 0;
				digits = 0;
				desiredPos = standardizeInput(arr[0],arr[1],arr[2]);
				for(i = 0; i < 3; i++)		// clear contents of character array
					arr[i] = 128;		// use 128 as 'empty' value as it is a nonprinting character
			}		
			else
			{
				arr[digits] = c;			// place input in character array and increment current digit
				digits++;
			}

		}

		servo_pos[d] = desiredPos;			// actually move the servo and print current action
		ser_putstring("\n\rServo moved to: ");

		printInteger(desiredPos);
		ser_putstring("\n\r");
		
	}
}

/*
	readAnalog() - 	Prompts user for which analog port is to be read (0-7)
				and then allows the user to read the port by typing 'r'.
				To return to the main menu, the user can type 'q'.
*/

void readAnalog()
{
	char c, d, ar;
	int continueTesting = 1;

	ADCON1 = 0; // initialize analog-digital converter //

	ser_putstring("\n\rPort for analog input (0-7): ");

	c = ser_rcv();
	d = c - 48;
	while(d > 7 || d < 0)
	{	
		c = ser_rcv();
		d = c - 48;
	}
	ser_putstring("\n\rHit 'r' to take a reading: ");
	while(continueTesting)
	{
		c = ser_rcv();
		switch(c)
		{
     			case 'q' :
				continueTesting = 0;
				break;

		 	case 'r' :
				ar = adc_read(d);      // read analog input d 
				ser_putstring("\n\rAD read: ");
				ser_writechar(ar);
				ser_putstring("\n\r");	 
				break;
			default :	
	          		break;
		}
	}

}

/*
	changeLED() - 	Allows user to change state of GREEN LED by typing 1 or
				the YELLOW LED by typing 2.
				To return to the main menu, the user can type 'q'.

				***** The YELLOW AND GREEN constants have been switched to create the desired behavior, but should be
					switched back after the YELLOW & GREEN constants are switched in the API.
*/

void changeLED()
{
	int continueTesting = 1;
	int yellowIsOn = 0;
	int greenIsOn = 0;
	char c;
	ser_putstring("\n\r1 = Change status of GREEN LED.");
	ser_putstring("\n\r2 = Change status of YELLOW LED.\n\r");

	while(continueTesting)
	{
		c = ser_rcv();
		switch(c) 
		{
     			case 'q' :
				continueTesting = 0;
				clear_bit(PORTB, GREEN);  // turn off both led's before exiting tests
				clear_bit(PORTB, YELLOW);
				break;
     			case '1' :
				if(greenIsOn)
				{
					clear_bit(PORTB, GREEN); // turn off green led	
					greenIsOn = 0;
				}
				else
				{				
					set_bit(PORTB, GREEN); // turn on green led
					greenIsOn = 1;	
				}
				break;
			case '2' :
				if(yellowIsOn)
				{
					clear_bit(PORTB, YELLOW); // turn off both led's
					yellowIsOn = 0;
				}
				else
				{
					set_bit(PORTB, YELLOW); // turn on yellow led
					yellowIsOn = 1;
				}
			  	break;
		 	default :	
	          		break;
      	}
	}




}

/*
	checkButtons() - 	Allows user to read in when either button is pressed.
				To return to the main menu, the user can type 'q'.
*/

void checkButtons()
{
	int continueTesting = 1;
	char c;
	ser_putstring("\n\rPlease hit either button to test.\n\r");
	while(continueTesting)
	{
		c = ser_rcv_nb();
		switch(c) 
		{
     			case 'q' :
				continueTesting = 0;
				break;
     		   	default :
      	     		if (PORTB & BTN1) // if button1 is depressed
   				{
					ser_putstring("\n\rButton 1 pressed.");
					delay_ms( 250 );
				}
				else if (PORTB & BTN2)
				{
					ser_putstring("\n\rButton 2 pressed.");
					delay_ms( 250 );
				}		
	          		break;
      	}
	}
}

/*
	motorPWM() - 	Allows user to change state of PWM MOTOR1 by typing 1 or
				the PWM MOTOR2 by typing 2.  Then user selects a direction
				which is either off, forward, or reverse.  Finally a duty cycle
				is entered as an integer between 0 and 255.
				To return to the main menu, the user can type 'q'.
*/


void motorPWM()
{
	int continueTestingMotor = 1;
	char c;
	char d;
	char e = ENTER;
	char f;
	char arr[3];
	int i;
	int temp;

	int continueReading = 1;	// signals when user has finished entering position

	int desiredSpeed = 0;
	int digits = 0;

	pwm_init();

	
	ser_putstring("\n\r'1' = MOTORA or '2' = MOTORB\n\r");
	c = ser_rcv();
	while(c != '1' && c != '2' && c != 'q')
	{
		c = ser_rcv();	
	
	}
	continueTestingMotor = 1;
	if(c == 'q')
	{
		continueTestingMotor = 0;
	}
	
	// This assumes that Motor A => 0 and Motor B => 1
	// d = c - 48 - 1;
	
	// This assumes that Motor A => 1 and Motor B => 0
	d = 50 - c; 

	while(continueTestingMotor)
	{	
		ser_putstring("\n\rMotor: 1 = Off, 2 = Forward, 3 = Reverse.\n\r");	
		f = ser_rcv();
		if(f == 'q')		// quit to main menu
		{
			pwm_setvel8(0,0,0);  // turn off motor before exiting tests
			pwm_setvel8(1,0,0);  // turn off motor before exiting tests
			return;
		
		}
		if(f != '1')
		{
			ser_putstring("\n\r\Motor duty cycle (0-255):");
			continueReading = 1;
			digits = 0;		
			for(i = 0; i < 3; i++)		// clear contents of character array
				arr[i] = 128;		// use 128 as 'empty' value as it is a nonprinting character
			while(continueReading)
			{
				c = ser_rcv();		// wait for user input

				if(c == 'q')		// quit to main menu
				{
					pwm_setvel8(0,0,0);  // turn off motor before exiting tests
					pwm_setvel8(1,0,0);  // turn off motor before exiting tests
					return;
		
				}
				else if(c == e)		// user has hit 'enter' and process input to determine desired speed
				{
					continueReading = 0;
					desiredSpeed = standardizeInput(arr[0],arr[1],arr[2]);
				}		
				else
				{
					arr[digits] = c;			// place input in character array and increment current digit
					digits++;
				}
			}		
		}

		switch(f) 
		{
			case 'q' :
				continueTestingMotor = 0;
				pwm_setvel8(d,0,0);  // turn off motor before exiting tests
				return;
			case '1' :
				pwm_setvel8(d,0,0); // turn off motor	
				ser_putstring("\n\rOff\n\r");
				break;
			case '2' :
				pwm_setvel8(d,0,desiredSpeed); // turn on motor desiredSpeed speed forward	
				ser_putstring("\n\rForward - ");
				printInteger(desiredSpeed);
				ser_putstring("\n\r");
				break;
	     		case '3' :
				pwm_setvel8(d,1,desiredSpeed); // turn on motor desiredSpeed speed reverse
				ser_putstring("\n\rReverse - ");
				printInteger(desiredSpeed);
				ser_putstring("\n\r");
				break;
		 	default :	
	     	    		break;
		}
	}
}


void main(void)
{
      char c;
	init_cerebellum(); 			// configure cerebellum
	ser_init(SER_115200); 			// start up serial port handling
	while(1)
	{
			
		ser_putstring("\n\r1 = Move a servo to a new position.");
		ser_putstring("\n\r2 = Read an analog input.");
		ser_putstring("\n\r3 = Change the state of an LED.");
		ser_putstring("\n\r4 = Read a button.");
		ser_putstring("\n\r5 = Test PWM Motors.\n\r");

		c = ser_rcv();

		switch(c) {
        		case '1' :
                		moveServo();
				break;
        		case '2' :
				readAnalog();
                		break;
        		case '3' :
                		changeLED();
				break;
        		case '4' :
               		checkButtons();
				break;
        		case '5' :
                		motorPWM();
                		break;
        		default :
                		break;
        	}

	}

}

⌨️ 快捷键说明

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