老外开发的机器人的底层单片机代码。比较有参考价值哦!

源代码在线查看: interrupts.c

软件大小: 75 K
上传用户: xujinliner
关键词: 机器人 底层 单片机代码 价值
下载地址: 免注册下载 普通下载 VIP

相关代码

				//  Interrupt handlers     Interrupts.c					// Rev 9/1/05
				
				//Copyright (C) 2005 Alex Brown	rbirac@cox.net
				//This program is free software; See license at the end of this file for details.
				
				
				#include 		    //for registers
				#include 				//for i/o prototypes
				
				//External variables
				  //Misc
					extern unsigned int time;
				  //Encoders	
					long int enc0, enc1, enc2;
				  // I2C compass
				    extern int I2Ccount;
					extern int compass;
					int I2Cbuff;	   		 	   //dummy buffer
				  //Accelerometers
				  	int AccStartX, AccStartY;
					int AccIntX, AccIntY;	
					int AccEndX,AccEndY;
						   
				//Function Prototypes
					void rtexec(void);		   
					
				//-------------------------------------------------------------------------
				// Real Time Clock Interrupt
				
				#pragma interrupt_handler  rti_handler()
				
				void rti_handler()
				  {CRGFLG = 0x80; 		   //Clear RTI flag
				   time += 1;			   //Increment time counter
				   INTR_ON();			   //Turn interrupts back on to handle encoders & accel
				   rtexec();			   //Run Real Time executive
				  }
				  
				//-------------------------------------------------------------------------
				// Encoder interrupts.  
				// encoder clicks are counted into a long int (32 bit).  The compiler would do
				// this with a slow function call.  Hence, the increments are performed using
				// assembly code.
				
				
				//  PORT P interrupt handler   for Encoders 0 & 1
				#pragma interrupt_handler  PORTP_handler()
				  
				void PORTP_handler() 
				  { 
				    if(PIFP & 0x20)   	   //if interrupt bit 5 set (encoder 0)
				     {if(PTP & 0x40)          //if encoder direction bit set
				      { asm(" ldd %enc0+2");   //done in assembly for speed.  Done in two words
					 	asm(" addd #1");	   //with carry.
						asm(" std %enc0+2");
						asm(" bcc ab");
						asm(" ldd %enc0");
						asm(" addd #1");
						asm(" std %enc0");
						asm(" ab:");
					  }	
				     else 
				      { asm(" ldd %enc0+2");
					 	asm(" subd #1");
						asm(" std %enc0+2");
						asm(" bcc ab1");
						asm(" ldd %enc0");
						asm(" subd #1");
						asm(" std %enc0");
						asm(" ab1:");
					  }	
					  PIFP |= 0x20;	  	   //reset interrupt flag
					 } 
					  	
				  }
				  
				//  PORT H interrupt handler   for Encoder 1
				#pragma interrupt_handler  PORTH_handler()
				  
				void PORTH_handler() 
				  { 
				    if(PIFH & 0x02)   	   //if interrupt bit 1 set (encoder 1)
				     {if(PTH & 0x01)         //if encoder direction bit set
				      { asm(" ldd %enc1+2");   //done in assembly for speed.  Done in two words
					 	asm(" addd #1");	   //with carry.
						asm(" std %enc1+2");
						asm(" bcc ab4");
						asm(" ldd %enc1");
						asm(" addd #1");
						asm(" std %enc1");
						asm(" ab4:");
					  }	
				     else 
				      { asm(" ldd %enc1+2");
					 	asm(" subd #1");
						asm(" std %enc1+2");
						asm(" bcc ab5");
						asm(" ldd %enc1");
						asm(" subd #1");
						asm(" std %enc1");
						asm(" ab5:");
					  }	
					  PIFH |= 0x02;	  	   //reset interrupt flag
					 } 
				  }
				//  IRQ interrupt handler   for Encoder 2
				#pragma interrupt_handler  IRQ_handler()
				  
				void IRQ_handler() 
				{
				 	 if(PTP & 0x10)         //if encoder direction bit set
				      { asm(" ldd %enc2+2");   //done in assembly for speed.  Done in two words
					 	asm(" addd #1");	   //with carry.
						asm(" std %enc2+2");
						asm(" bcc ab2");
						asm(" ldd %enc2");
						asm(" addd #1");
						asm(" std %enc2");
						asm(" ab2:");
					  }	
				     else 
				      { asm(" ldd %enc2+2");
					 	asm(" subd #1");
						asm(" std %enc2+2");
						asm(" bcc ab3");
						asm(" ldd %enc2");
						asm(" subd #1");
						asm(" std %enc2");
						asm(" ab3:");
					  }	
					  PIFP |= 0x08;	  	   //reset interrupt flag
				}
				
				   
				//-------------------------------------------------------------------------
				// Accelerometer interrupts.  
				// These read a start time for the accel duty cycle leading edge and calculate
				// the interval on the falling edge.  The times are read from the timer 
				// register which counts up to 50000 in 1 usec intervals.
				// The resulting calculated interval may be negative if the timer rolls over
				// before the second value is taken.  This can be corrected in the using 
				// software by adding 50000.
				
				
				//  PORT J interrupt handler   for dual axis accelerometer
				#pragma interrupt_handler  PORTJ_handler()
				  
				void PORTJ_handler() 
				  { 
				    if(PIFJ & 0x01)   	   //if interrupt bit 0 set (accel ? axis)
				     {if(PPSJ & 0x01)         //if input bit set (rising edge)
					    {   AccStartX = TCNT;
							PPSJ &= ~0x01;	//set for next interrupt to trip on falling edge 
				//printf("Int %d  ",AccStartX);
						}  
					  else 
					    {   AccEndX = TCNT;   
						    AccIntX = AccEndX - AccStartX;
							PPSJ |= 0x01;   //set for next interrupt to trip on rising edge
				//printf("%d  %d\n",AccEndX,AccIntX);
						};
					  PIFJ |= 0x01;	  	   //reset interrupt flag for bit 0
					 } 
				
				    if(PIFJ & 0x02)   	   //if interrupt bit 1 set (accel ? axis)
				     {if(PPSJ & 0x02)         //if input bit set (rising edge)
					    {   AccStartY = TCNT;
							PPSJ &= ~0x02;	//set for next interrupt to trip on falling edge 
						}  
					  else 
					    {   AccEndY = TCNT;
							AccIntY = AccEndY - AccStartY;
							PPSJ |= 0x02;   //set for next interrupt to trip on rising edge
						};
					  PIFJ |= 0x02;	  	   //reset interrupt flag for bit 0
					 } 
				  }
				   
				//-------------------------------------------------------------------------
				// I2C Interrupt
				
				#pragma interrupt_handler  I2C_handler()
				
				void I2C_handler()
				  {	  IBSR = 0x02;		   						  //clear IBIF
				  	  if(IBSR & 0x10)
					  { printf("Int # %x \n",IBCR); //if arbitration lost error
					    //occasionally, get arb error. next line resets IBAL in IBSR to see if heals
						IBSR = 0x10;
					  }
					  if(IBSR & 0x40) printf("Int @");			  //if addressed as slave error
					  
				  	  switch (I2Ccount)		//cycle through each byte of the message
					  {
					   case 0:
					    IICDR = 0x02;					//send 16 bit heading subaddress
						break;
				
					  case 1:
				        IBCR |= 0x04;						//repeated start 
						IICDR = 0xC1;						//Compass address in receive mode
						break;
					
				       case 2:
					    IBCR &= ~0x10;					//change to receive mode
						I2Cbuff = IICDR;				//dummy read to start receive
						break;
						
				       case 3:
						IBCR |=  0x08;					//terminate data xfr (see note 1 below)
						compass = IICDR						break;
						
					  case 4:
				  	    IBCR &= ~0x30;					//stop
					    compass += IICDR;				//read in 2nd byte of data 
				   		break;
					  }
					  I2Ccount++; 		
				 }
				 
				//  OPEN SOURCE SOFTWARE LICENSE
				/* Permission is hereby granted, free of charge, to any person obtaining a copy 
				of this software and associated documentation files (the "Software"), to deal in
				the Software without restriction, including without limitation the rights to use, 
				copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the 
				Software, and to permit persons to whom the Software is furnished to do so, 
				subject to the following conditions:
				
				The above copyright notice and this permission notice shall be included in all 
				copies or substantial portions of the Software.
				
				THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
				IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 
				FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 
				COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 
				IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 
				CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
				*/ 	
							

相关资源