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

📄 interrupts.c

📁 老外开发的机器人的底层单片机代码。比较有参考价值哦!
💻 C
字号:
//  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 <hcs12dp256.h>		    //for registers
#include <stdio.h>				//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<<8;				//read first byte of data
		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.
*/ 	

⌨️ 快捷键说明

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