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

📄 msp430-fw-interrupts.c

📁 老外用DDSAD9854和MSP430做的一个收音机的源程序.
💻 C
📖 第 1 页 / 共 2 页
字号:
      inBit = P2IN & BIT1;
      if(inBit!=0 && wheel_counter<32000)
         { wheel_counter += 1; }
      else if(inBit==0 && wheel_counter>-32000)
         { wheel_counter -= 1; }
         
      // reset interrupt flag
      P2IFG &= ~BIT0;
   }

   if ((P2IFG&KBD_CLK)!=0) {

      // -- AT keyboard
      
      // keyboard serial stream:
      //  falling clock edge data in
      //  start bit 0, 8 bit LSB ... MSB, odd parity, stop bit 1
      // 
      //  from scope traces and 
      //  http://www.beyondlogic.org/keyboard/keybrd.htm
      //
      //    (A)      B      C      D      E
      // ----+       +------+      +------+
      // CLK | <int  |      |      |      |         5..25 kHz
      //     +-------+      +------+      +-----...
      //
      // -+ DATA    +----------+
      //  |  0      |       1  |           0
      //  +---------+          +---------------...
      
      // timeout loop: xtal 4MHz/16000=250 Hz (plenty for 5..25kHz AT kbd clock)

      #ifdef NEW_KBD_FUNCS
      if(risingedge==1) {
         // trigged on rising edge (data done), switch back to falling edge trig
         P2IES |= KBD_CLK;
         risingedge=0;
      } else {
         // trigged on falling edge (data in), change to rising edge trig
         P2IES &= ~KBD_CLK;
         risingedge=1;         
            
         // read the bit
         inBit = P2IN & KBD_DAT;
      
   intPort2_kbdRetry:
         // start of new sequence?
         if(kbdBitcount==0) {
         
            // start bit 0
            if(inBit==0) { 
               ++kbdBitcount; 
               kbdData=0; 
            } else { 
               // out of sync, wait for next bit 
               P6OUT |= LED_1;
            }
            
            // continue current sequence: databits, parity, stopbit
            } else {

            // if previous bit over 3 ticks ago, reset sequence
            if((sys_ticks-old_sys_ticks)>20) { 
               kbdBitcount=0;
               kbdData=0;
         //   P6OUT ^= LED_1; // toggle diagnostic LED            
               goto intPort2_kbdRetry; // reinterpret as start bit
            }
            
            // data bits
            if(kbdBitcount<=(1+8)) {
               // LSB comes first, so shift bits in from left side
               kbdData /= 2;
            if(inBit!=0) 
               { kbdData |= 0x80; }
            ++kbdBitcount;
            // parity - ignored
            } else if (kbdBitcount==(1+8+1)) {
               ++kbdBitcount;
            // stop bit 1
            } else {
               if(inBit==0) {
                  // out of sync
                   P6OUT ^= LED_1; // toggle diagnostic LED
                  FWConfig.KBD_failure = 1; 
               } else {
                  if(!(kbdUnreadCount>=(KBD_BUFSIZE-1)))
                     { kbdUnreadCount++; }
                  kbdBufPos=(kbdBufPos+1)%KBD_BUFSIZE;
                  kbdBuf[kbdBufPos] = kbdData;
                  P6OUT &= ~LED_1;
               }
               kbdBitcount = 0;
            }
         }
      }
      old_sys_ticks = sys_ticks;
      #else
      // check start bit 0, cont B (wait for rising edge)
      if((P2IN&KBD_DAT)!=0) fail=1;
      timeout=0; 
      while((P2IN&KBD_CLK)==0 && (timeout++)<KBD_DLY && fail==0) { _NOP(); }
      if(timeout>KBD_DLY-1) fail=1;
   
      // cont C, wait for falling edges, read in 8 bits
      for(i=0;i<8 && fail==0;++i) { // &&fail==0

         // falling edge
         timeout=0; 
         while((P2IN&KBD_CLK)!=0 && (timeout++)<KBD_DLY) { _NOP(); }
         if(timeout>KBD_DLY-1) fail=1;
         
         // data, LSB first MSB last
         kbdChar /= 2;
         if((P2IN&KBD_DAT)!=0) kbdChar+=0x80;
      
         // rising edge
         timeout=0; while((P2IN&KBD_CLK)==0 && (timeout++)<KBD_DLY && fail==0) _NOP(); if(timeout>KBD_DLY-1) fail=1;
      }
   
      // skip parity bit, falling + rising edge
      timeout=0; while((P2IN&KBD_CLK)!=0 && (timeout++)<KBD_DLY && fail==0) _NOP(); if(timeout>KBD_DLY-1) fail=1;
      timeout=0; while((P2IN&KBD_CLK)==0 && (timeout++)<KBD_DLY && fail==0) _NOP(); if(timeout>KBD_DLY-1) fail=1;
   
      // check stop bit 1, falling + rising edge
      timeout=0; while((P2IN&KBD_CLK)!=0 && (timeout++)<KBD_DLY && fail==0) _NOP(); if(timeout>KBD_DLY-1) fail=1;
      if((P2IN&KBD_DAT)==0) fail=1;
      timeout=0; while((P2IN&KBD_CLK)==0 && (timeout++)<KBD_DLY && fail==0) _NOP(); // last rising edge
      
      if(fail==0) {
         if(!(kbdUnreadCount>=(KBD_BUFSIZE-1)))
         { kbdUnreadCount++; }

         kbdBufPos=(kbdBufPos+1)%KBD_BUFSIZE;
         kbdBuf[kbdBufPos] = kbdChar;
      } else {
         // P6OUT |= LED_1; // kbd error led on
         FWConfig.KBD_failure = 1; 
      }
      #endif
      
      // reset interrupt flag
      P2IFG &= ~KBD_CLK;
   }

}


//===================================================================
//
//       KEYBOARD HELPER FUNCTIONS
//

//-------------------------------------------------------------------
// kdbSuspend ( )
// Tell the AT keyboard to momentarily pause sending of any data.
//
void kbdSuspend(void) 
{
  /*
   _DINT();
   P2IES &= ~KBD_CLK;   // int off
   P2DIR |= KBD_CLK;    // clock line as output
   P2OUT &= ~KBD_CLK;   // set line low = keyboard doesn't transmit
   P2IFG &= ~KBD_CLK;   // clear int flag
   _EINT();
  */
   return;
} 

//-------------------------------------------------------------------
// kbdResume ( )
// Allow the AT keyboard to send data. If the keyboard was previously
// suspended and new button press data accumulated in the keyboards
// own memory buffer, it will start sending that data soon.
//
void kbdResume(void) 
{
  /*
   _DINT();
   P2DIR &= ~KBD_CLK;   // clock line as input
   P2IES |= KBD_CLK;    // int on
   P2IFG &= ~KBD_CLK;   // clear int flag
   _EINT();
  */
   return;
}

//-------------------------------------------------------------------
// unsigned char kbdGetChar ( )
// Returns the next character from our keyboard buffer, or 0 if
// the buffer was empty.
//
unsigned char kbdGetChar(void) 
{
   unsigned char tmp;

   if(kbdUnreadCount<=0) return '\0';

   _DINT();

   if(kbdBufPos>KBD_BUFSIZE)
   { kbdBufPos = 0; kbdUnreadCount=1; }

   kbdUnreadCount--;
   tmp = (kbdBufPos-kbdUnreadCount)%KBD_BUFSIZE;
   tmp = kbdBuf[tmp]; 

   _EINT();

   return tmp;
}



//===================================================================
//
//       PC SERIAL COMM HELPER FUNCTIONS
//

//-------------------------------------------------------------------
// PC_writeChar ( unsigned char )
// Queue a new data byte to transmit to the PC.
//
void PC_writeChar(unsigned char out) 
{

   // currently not sending?
   if(pcTxDone==1) {
      // just place the new char into the hardware buffer
      TXBUF1 = out; pcTxUnsentCount=0;
      pcTxDone = 0;
      return;
   }

   // already sending, add to software buffer for sending later
   while(pcTxUnsentCount>=PC_TXBUF) // buffer overflow
      { _NOP(); } // wait for tx interrupt driver to 'free' 1 byte

   _DINT();
   ++pcTxBufPos;              // append byte to the buffer
   pcTxBufPos%=PC_TXBUF;    
   pcTxUnsentCount++;
   pcTxBuf[pcTxBufPos] = out;
   _EINT();

   return;
}

//-------------------------------------------------------------------
// PC_writeString ( char * )
// Write a null-terminated string to the serial port 
//
void PC_writeString(char *str) 
{
   int i;
   for(i=0;i<100 && *(str+i)!='\0';i++)
      { PC_writeChar(*(str+i)); }
   return;
}

//-------------------------------------------------------------------
// PC_writeLine ( char * )
// Write a null-terminated string to the serial port.
// Precedes the string with a # and adds a newline.
//
void PC_writeLine(char *str)
{
   PC_writeString("# ");
   PC_writeString(str);
   PC_writeString((char*)STR_CRLF);
}

//-------------------------------------------------------------------
// unsigned char PC_readChar ( )
// Returns the next character from our serial input buffer, or 0 if
// the buffer was empty.
//
unsigned char PC_readChar(void) 
{
   unsigned char tmp;

   if(pcRxUnreadCount<1) { return 0; }

   _DINT();
   if(pcRxBufPos>PC_RXBUF) { 
      pcRxBufPos = 0; 
      pcRxUnreadCount = 1; 
   }

   do {
      tmp = pcRxBuf[pcRxBufPos];
      --pcRxBufPos; 
      pcRxBufPos%=PC_RXBUF;
      pcRxUnreadCount--;
   } while((tmp==0) && (pcRxUnreadCount>0));
   _EINT();

   return tmp;
}

⌨️ 快捷键说明

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