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

📄 18motor.c

📁 一款汽车马达控制的产品软件,使用PIC18C452芯片开发,能对汽车马达实现检测控制,可有效提高马达功率及减低功耗
💻 C
📖 第 1 页 / 共 2 页
字号:
//	Setup() initializes program variables and peripheral registers
//---------------------------------------------------------------------

void Setup(void)
{
firstseg = 0;							// Initialize motion segment
lastseg = 0;							// variables
segnum = 0;
parameter = 0;							// Motion segment parameter#
i = 0;									// Receive buffer index
comcount = 0;							// Input command index
udata = 0;								// Holds USART received data

stat.phase = 0;						// Set flags to 0.
stat.saturated = 0;
stat.motion = 0;
stat.run = 0;
stat.loop = 0;
stat.neg_move = 0;
dtime = 0;
integral.l = 0;
vlim = 0;
mvelocity = 0;
DnCount = 0;
UpCount = 0;
temp.l = 0;
accel.l = 0;
error.l = 0;
ypid.l = 0;
velact.l = 0;
phase1dist.l = 0;
position = 0;
mposition = 0;
fposition = 0;
flatcount = 0;
udata = 0;
memset(inpbuf,0,8);		   // clear the input buffer

// Setup A/D converter
OpenADC(ADC_FOSC_32 & ADC_LEFT_JUST & ADC_1ANA_0REF,
			ADC_CH0 & ADC_INT_OFF);

OpenPWM1(0xff);				// Setup Timer2, CCP1 to provide
									//	19.53 Khz PWM @ 20MHz

OpenTimer2(T2_PS_1_1 & T2_POST_1_10 & TIMER_INT_ON);

SetDCPWM1(512);				// 50% initial duty cycle

EnablePullups();           // Enable PORTB pullups
PORTC = 0;						// Clear PORTC
PORTD = 0;						//	Clear PORTD
PORTE = 0x00;					//	Clear PORTD
TRISC = 0xdb;					// 
TRISD = 0;						// PORTD all outputs.
TRISE = 0;						// PORTE all outputs.

// Setup the USART for 19200 baud @ 20MHz

SPBRG = 15;						// 19200 baud @ 20MHz
TXSTA = 0x20;					// setup USART transmit
RCSTA = 0x90;					// setup USART receive

putrsUSART("\r\nPIC18C452 DC Servomotor");
putrsUSART(ready);

OpenI2C(MASTER,SLEW_OFF);	// Setup MSSP for master I2C
SSPADD = 49;       			// 100KHz @ 20MHz

kp = ExtEERead(122);			// Get PID gain constants
ki = 0;							// from data EEPROM
kd = ExtEERead(126);

TMR0L = 0;						// Clear timers.
TMR0H = 0;
TMR1L = 0;
TMR1H = 0;

OpenTimer0(TIMER_INT_OFF & T0_16BIT & TIMER_INT_OFF & T0_EDGE_RISE &
				T0_SOURCE_EXT & T0_PS_1_1);
OpenTimer1(TIMER_INT_OFF & T1_SOURCE_EXT & T1_16BIT_RW & TIMER_INT_OFF
				& T1_PS_1_1 & T1_SYNC_EXT_ON & T1_OSC1EN_OFF );

// Load motion profile data for segments 1 through 12 from
// data EEPROM

for(segnum=0;segnum < 12;segnum++)              
	{
	for(parameter=0;parameter < 4;parameter++)
		{
		eeadr = (segnum << 3) + (parameter << 1);
		segment1[segnum][parameter] = ExtEERead(eeadr);
		}
	}

segment2[0][DIST] = 29500;			// Motion profile data for segments
segment2[0][VEL] = 4096;			// 13 through 24 are loaded into RAM
segment2[0][ACCEL] = 2048;			// from program memory
segment2[0][TIME] = 1200;

segment2[1][DIST] = -29500;
segment2[1][VEL] = 1024;
segment2[1][ACCEL] = 512;
segment2[1][TIME] = 1200;

segment2[2][DIST] = 737;
segment2[2][VEL] = 4096;
segment2[2][ACCEL] = 2048;
segment2[2][TIME] = 1200;

segment2[3][DIST] = 737;
segment2[3][VEL] = 4096;
segment2[3][ACCEL] = 2048;
segment2[3][TIME] = 1200;

segment2[4][DIST] = 738;
segment2[4][VEL] = 4096;
segment2[4][ACCEL] = 2048;
segment2[4][TIME] = 1200;

segment2[5][DIST] = 738;
segment2[5][VEL] = 4096;
segment2[5][ACCEL] = 2048;
segment2[5][TIME] = 1200;

segment2[6][DIST] = -2950;
segment2[6][VEL] = 1024;
segment2[6][ACCEL] = 128;
segment2[6][TIME] = 1200;

segment2[7][DIST] = 2950;
segment2[7][VEL] = 256;
segment2[7][ACCEL] = 64;
segment2[7][TIME] = 1200;

segment2[8][DIST] = -2950;
segment2[8][VEL] = 4096;
segment2[8][ACCEL] = 512;
segment2[8][TIME] = 1200;

segment2[9][DIST] = 29500;
segment2[9][VEL] = 1024;
segment2[9][ACCEL] = 512;
segment2[9][TIME] = 1200;

segment2[10][DIST] = 29500;
segment2[10][VEL] = 2048;
segment2[10][ACCEL] = 512;
segment2[10][TIME] = 1200;

segment2[11][DIST] = 29500;
segment2[11][VEL] = 4096;
segment2[11][ACCEL] = 1024;
segment2[11][TIME] = 1200;

if(MODE1)								// Check DIP switches at powerup
   stat.loop = 1;						// If SW1 is on, set for loop mode
	    
if(MODE2)								// If SW2 is on, execute 
   {										// segments 12 and 13
   firstseg = 12;
   lastseg = 13;
   segnum = 12;
	stat.run = 1;
   }
else if(MODE3)							// If SW3 is on, execute
   {										// segments 14 through 18
	firstseg = 14;
   lastseg = 18;
   segnum = 14;
	stat.run = 1;
   }
else if(MODE4)							// If SW4 is on, execute
   {										// segments 18 and 19
	firstseg = 18;
   lastseg = 19;
   segnum = 18;
   stat.run = 1;
	}   
											
INTCONbits.PEIE = 1;					// Enable peripheral interrupts
INTCONbits.GIE = 1;					// Enable all interrupts
}

//---------------------------------------------------------------------
// main()
//---------------------------------------------------------------------

void main(void)
{
Setup();									// Setup peripherals and software
											// variables.

while(1)                    		// Loop forever
    {										
   ClrWdt();							// Clear the WDT

   ConvertADC();						// Start an A/D conversion				
   while(BusyADC());					// Wait for the conversion to complete
	PORTD = 0;							// Clear the LED bargraph display.
	PORTE	&= 0x04;						//						"
	
	if(ADRES > 225) 
		{
		PORTE |= 0x03;					// Turn on 10 LEDS
		PORTD = 0xff;
		}
	if(ADRES > 200) 
		{
		PORTE |= 0x01;					// Turn on 9 LEDS
		PORTD = 0xff;
		}
	else if(ADRES > 175) 	PORTD = 0xff;	// Turn on 8 LEDS
	else if(ADRES > 150) 	PORTD = 0x7f;	// 7 LEDS
	else if(ADRES > 125) 	PORTD = 0x3f;	// 6 LEDS
	else if(ADRES > 100) 	PORTD = 0x1f;	// 5 LEDS
	else if(ADRES > 75)		PORTD = 0x0f;	// 4 LEDS
	else if(ADRES > 50) 	PORTD = 0x07;	// 3 LEDS
	else if(ADRES > 25) 	PORTD = 0x03;	// 2 LEDS
	else if(ADRES > 0) 		PORTD = 0x01;	// 1 LED
	
	if(PIR1bits.RCIF)									// Check for USART interrupt
   	{
   	switch(udata = RCREG)
	      {
	      case ',':	DoCommand();				// process the string
	      				memset(inpbuf,0,8);		// clear the input buffer
	                  i = 0;						// clear the buffer index
	                  comcount++;					// increment comma count
	                  TXREG = udata;				// echo the character
	                  break;
	      				
	      				
	      case 0x0d:  DoCommand();				// process the string
	                  memset(inpbuf,0,8);		// clear the input buffer
	                  i = 0;						// clear the buffer index
	                  comcount = 0;				// clear comma count
							segnum = 0;					// clear segment number
							parameter = 0;				// clear paramater 
							putrsUSART(ready);		// put prompt to USART 
	                  break;
	                  
	      default:    inpbuf[i] = udata;		// get received char 
	                  i++;							// increment buffer index
	                  if(i > 7)					// If more than 8 chars
	                     {							// received before getting
	                     putrsUSART(ready); 	// a <CR>, clear input
	                     memset(inpbuf,0,8);	// buffer
	                     i = 0;					// the buffer index
	                     }
	                  else TXREG = udata; 		// echo character
	                  break;						//
         
         }     										//end switch(udata)
	   
	    }       										//end if(RCIF)
    }          										//end while(1)
}


//-------------------------------------------------------------------
// DoCommand()
// Processes incoming USART data.
//-------------------------------------------------------------------

void DoCommand(void)
{
if(comcount == 0)		// If this is the first parameter of the input
	{						// command...
	switch(inpbuf[0])
		{
		case 'X':	parameter = DIST;		// Segment distance change
						break;
					
		case 'V':	parameter = VEL;		// Segment velocity change
						break;
					
		case 'A':	parameter = ACCEL;	// Segment acceleration change
						break;
					
		case 'T':	parameter = TIME;		// Segment delay time change
						break;
					
		case 'P':	parameter = 'P';		// Change proportional gain
						break;
	
		case 'I':	parameter = 'I';		// Change integral gain
						break;
	
		case 'D':	parameter = 'D';		// Change differential gain
						break;
		
		case 'L':	parameter = 'L';		// Loop a range of segments
						break;
		
		case 'S':	stat.run = 0;			// Stop execution of segments
						break;

		case 'G':	parameter = 'G';		// Execute a range of segments
						break;
		
		case 'W':   if(PORTEbits.RE2)		// Enable or disable motor
							{						// driver IC
							putrsUSART("\r\nPWM On");
							PORTEbits.RE2 = 0;
							}
						else
							{
							putrsUSART("\r\nPWM Off");
							PORTEbits.RE2 = 1;
							}
						break;
      	      
	   default:    if(inpbuf[0] != '\0')
	                  {
	                  putrsUSART(badcmd);
	                  }
	               break;
	
		}
	}

else if(comcount == 1)		// If this is the second parameter of the
	{								// input command.
	if(parameter < 4) segnum = atob(inpbuf);
	else
	switch(parameter)									
		{
		case 'P':   kp = atoi(inpbuf);			// proportional gain change
		            ExtEEWrite(122, kp);			// Store value in EEPROM
		            break;

		case 'I':   ki = atoi(inpbuf);			// integral gain change
		            ExtEEWrite(124, ki);			// Store value in EEPROM
		            break;

		case 'D':   kd = atoi(inpbuf);			// differential gain change
		            ExtEEWrite(126, kd);			// Store value in EEPROM
		            break;
      
		case 'G':	firstseg = atob(inpbuf);
						break;							
															// Get the first segment in
      													// the range to be executed.

		case 'L':	firstseg = atob(inpbuf);
						break;
			     
		default:    break;
     	}
	}
	
else if(comcount == 2)
	{
	if(!stat.run)							// If no profile is executing
		{
		if(parameter < 4)					// If this was a segment parameter
			{									// change.
			if(segnum < 12)
				{
				// Write the segment paramater into data memory
				segment1[segnum][parameter] = atoi(inpbuf);
				// Compute EEPROM address and write data to EEPROM
				eeadr = (segnum << 3) + (parameter << 1);
				ExtEEWrite(eeadr, segment1[segnum][parameter]);
				}
			
			else if(segnum < 24)
				// Write segment parameter data into data memory
				segment2[segnum - 12][parameter] = atoi(inpbuf);
			}
		else switch(parameter)									
			{
			case 'G':	lastseg = atob(inpbuf);				// Get value for
			            segnum = firstseg;					// last segment.
							stat.loop = 0;
							stat.run = 1;							// Start profile.
							break;
      
			case 'L':	lastseg = atob(inpbuf);				// Get value for
			            segnum = firstseg;					// last segment.
							stat.loop = 1;							// Enable looping
							stat.run = 1;							// Start profile
							break;
			
			default:    break;
	     	}
	   }
	}
}

//---------------------------------------------------------------------
// ExtEEWrite()
// Writes an integer value to an EEPROM connected to the I2C bus at
// the specified location.
//---------------------------------------------------------------------

void ExtEEWrite(unsigned char address, int data)
{
union 
{
char b[2];
int i;
}
temp;

char error, retry;

temp.i = data;
error = 0;

retry = 10;								// Poll the EEPROM up to 10 times
do
	{
	error = EEAckPolling(0xA0);
	retry--;
	} while(error && retry > 0); 

retry = 10;								// Attempt to write low byte of data
do											// up to 10 times
	{
	error = EEByteWrite(0xA0, address, temp.b[0]);
	retry--;
	} while(error && retry > 0);

retry = 10;								// Poll the EEPROM up to 10 times
do
	{
	error = EEAckPolling(0xA0);
	retry--;
	} while(error && retry > 0);


retry = 10;								// Attempt to write high byte of data
do											// up to 10 times
	{
	error = EEByteWrite(0xA0, address + 1, temp.b[1]);
	retry--;
	} while(error && retry > 0);
	
}

//---------------------------------------------------------------------
// ExtEEWrite()
// Reads an integer value from an EEPROM connected to the I2C bus at
// the specified location.
//---------------------------------------------------------------------

int ExtEERead(unsigned char address)
{
union 
{
char b[2];
int i;
}
data;

union 
{
char b[2];
int i;
}
temp;

char retry;

retry = 10;								// Attempt to read low byte of data
do											// up to 10 times
	{
	temp.i = EERandomRead(0xA0, address);
	retry--;
	} while(temp.b[1] && retry > 0);

if(temp.b[1]) data.b[0] = 0;		// Make read result 0 if error
else data.b[0] = temp.b[0];		// Otherwise get the low byte of data

retry = 10;								// Attempt to read high byte of data
do											// up to 10 times
	{
	temp.i = EERandomRead(0xA0, address + 1);
	retry--;
	} while(temp.b[1] && retry > 0);

if(temp.b[1]) data.b[1] = 0;		// Make read result 0 if error
else data.b[1] = temp.b[0];		// Otherwise get the high byte of data

return data.i;
}

//---------------------------------------------------------------------
// putrsUSART()
// Writes a string of characters in program memory to the USART
//---------------------------------------------------------------------

void putrsUSART(const rom char *data)
{
	do
	{				
		while(!(TXSTA & 0x02));
		TXREG = *data;
	} while( *data++ );
}


⌨️ 快捷键说明

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