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

📄 eventcounter.c

📁 Event counter for MSP430 - multi channel and real fast using latched interrupts.
💻 C
字号:
// ES449 Sample Program
// Copyright (c) 2002 Rowley Associates Limited

#include <msp430x44x.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "c:\projects\aq480lib\sblcd.h"

#define inbuflen 40
#include "c:\projects\aq480lib\rs232pr.h"

register unsigned int IntCnt0,IntCnt1,IntCnt2,IntCnt3,IntCnt4,IntCnt5;
unsigned int ticks;
static char msg[20];
static char txbuf[40],rxbuf[40];
static int rxbuflen;
static int dispch;
static unsigned int sampletime; // how many timer ticks to a sample time
static int scanauto;           // 1 to run scans constantly


interrupt[BASICTIMER_VECTOR] void timer_interrupt(void)
{
  ticks++;
}
 


interrupt[PORT1_VECTOR] void port1_interrupt(void) {
register int pending;
auto char keepbits;
  P2OUT |= 0x10;
  pending=P1IFG; keepbits=~pending;
/$
  RRA @pending
  ADC @IntCnt0
  RRA @pending
  ADC @IntCnt1
  RRA @pending
  ADC @IntCnt2
  RRA @pending
  ADC @IntCnt3
  RRA @pending
  ADC @IntCnt4
  RRA @pending
  ADC @IntCnt5
$/

  P1IFG &= keepbits;
  P2OUT &= ~0x10;
}

 

static void sblcd_display_cntr(int ctr)
{
   sblcd_display_7seg(1,LCD8a_A+LCD8a_F+LCD8a_E+LCD8a_D); // C
   sblcd_display_7seg(2,LCD8a_F+LCD8a_B+LCD8a_G+LCD8a_E+LCD8a_C); // H
   //sblcd_display_7seg(3,LCD8b_G+LCD8b_D); // =
   sblcd_show(LCD_CLOCKCOLON);

   sblcd_display_digit(4,ctr); 
   switch (ctr) {
   case 0 :  sprintf(msg,"%7u",IntCnt0); break;
   case 1 :  sprintf(msg,"%7u",IntCnt1); break;
   case 2 :  sprintf(msg,"%7u",IntCnt2); break;
   case 3 :  sprintf(msg,"%7u",IntCnt3); break;
   case 4 :  sprintf(msg,"%7u",IntCnt4); break;
   case 5 :  sprintf(msg,"%7u",IntCnt5); break;
   };
   sblcd_msg(1,msg);
}


  
static void UART0_putch(char c) {
  while ((IFG1 & UTXIFG0) == 0);        // Wait for UART0 buffer ready
  TXBUF0=c;                             // And send
}

static void initUART0_115200(void) {
// Baudrate=115200, actual=115322.004 (0.106%)
// BRCLK=7077888 Hz
  U0CTL  = SWRST;        // Set the reset bit to hold inactive
  U0BR0  = 0x3D;         // Prescale divisor = 0x003D
  U0BR1  = 0x00; 
  U0MCTL = 0x2A;         // Modulation 00101010
  U0CTL  = SWRST+CHAR;   // P=none, 8 bits, 1 stop
  U0TCTL = SSEL1;        // SMCLK
  U0RCTL = 0;            // wake on all correct rx
  ME1   |= URXE0 +UTXE0; // Enable the module
  P2SEL |= 0x30;         // P2.4,5 special function
  P2DIR |= 0x10;         // P2.4   output
  P2DIR &= ~0x20;        // P2.5 input
  U0CTL &= ~SWRST;       // Release the UART to operation 
  IE1   |= URXIE0;       //  RXINT enable
} // initUART0_115200()

static void send_result(void) {
// Sends result to UART, all 6 channels
int i,j,sl;  
   for (i=0;i<6;i++)  {
     switch(i) {
     case 0 :  sprintf(msg,"{M,%u,",IntCnt0); break;
     case 1 :  sprintf(msg,"%u,",IntCnt1); break;
     case 2 :  sprintf(msg,"%u,",IntCnt2); break;
     case 3 :  sprintf(msg,"%u,",IntCnt3); break;
     case 4 :  sprintf(msg,"%u,",IntCnt4); break;
     case 5 :  sprintf(msg,"%u}",IntCnt5); break;
     };
     sl=strlen(msg);
     for (j=0;j<sl;j++) UART0_putch(msg[j]); // send the string
   };  
}

static void doCount(void) {
    IntCnt0=0;IntCnt1=0;IntCnt2=0;IntCnt3=0;IntCnt4=0;IntCnt5=0; // Reset for next count
    P1IFG=0;                // Clear int bits set while resting   
    TACTL |= TACLR;         // Clear time
    P1IE  =0x3F;            // All 6 interrupts running crazy
    while (TAR<sampletime); // wait for the sampletime
    P1IE  =0x00;            // Stop the counters.
}
 
static unsigned int i, ADCresult; 
static unsigned long int DegC, DegF;
 
void main(void)
{

 // Stop watchdog.
  WDTCTL = WDTHOLD | WDTPW;

  // Set FLL.
  FLL_CTL0 |= DCOPLUS + XCAP18PF;
  
  // On startup they are SCFI0=0x41 and SCFQCTL=0x1F
  // 7 MHz operation at 3.3V
  SCFQCTL = 26 ;           // (26+1) x 32768 x 8 = 7,077,888 Hz 
  SCFI0 = FLLD0+FLLD1+FN_8; // Divide by 8, 5-40MHz
   
  P5DIR |= 0xc0;
  P5OUT |= 0x80;
  P5OUT &= ~0x80;
  P5OUT |= 0x80;
  P5OUT &= ~0x80;

  // Set up basic timer for LCD
  BTCTL = BT_fLCD_DIV64 + BT_ADLY_250;

  // Turn on Basic Timer interrupts
  //IE2 |= BTIE;

  //P1SEL = 0x32;
  // Set port1 to interrupt function
  P1SEL =0x00; // All standard function
  P1DIR =0x00; // All are inputs
  P1IES =0x00; // Low to high transition
  P1IE  =0x00; // No interrupts enabled

  // Port 2.  
  P2SEL = 0x00; // All standard
  P2DIR = 0xF0; // P2.7 is AB
  P2OUT = 0x80; // Set P2.7

  P3SEL = 0x00;
  P3DIR = 0x8F;
  P3OUT = 0x00;
  
  
  ticks=0; IntCnt0=0;IntCnt1=0;IntCnt2=0;IntCnt3=0;IntCnt4=0;IntCnt5=0;
 
  P4SEL = 0xfc;
  P5SEL = 0xff;

  // Start things up  
  sblcd_init();
  initUART0_115200();
 
  sblcd_display_starburst(1,_M+_N+_D);
  sblcd_display_starburst(2,_G+_P+_E+_D);
  sblcd_msg(3,"NDI");


  // Setup ADC to read temperature
  ADC12CTL0 = ADC12ON+REFON+REF2_5V+SHT0_6; // Setup ADC12, ref., sampling time
  ADC12CTL1 = SHP;                      // Use sampling timer
  ADC12MCTL0 = INCH_10+SREF_1;          // Select channel A10, Vref+
  ADC12IE = 0x00;                       // Disable ADC12IFG.0

  for (i=0; i<0x3600; i++)              // Delay for reference start-up
  {
  }
  ADC12CTL0 |= ENC;  // Enable conversions

  
  _EINT();

  // Set up timer A for counting at ACLK/8. One second is 0x1000 
  TACTL=TASSEL0 + ID1 + ID0 + MC1 + TACLR; // Select ACLK/8 count up to 0xFFFF
 
  cmdDone();dispch=0;scanauto=1; sampletime=0x1000;
  sblcd_show(LCD_ArrowRight);
  
  for (;;) { // no power down stuff.. 
     
    if (scanauto) { // automatic mode  
      sblcd_show(LCD_Antenna);
      doCount();
      sblcd_hide(LCD_Antenna);
      sblcd_display_cntr(dispch); // Show counter
      send_result();              // Send the result on the UART
    };
    
    if (cmdReady) {
        switch(RS232Cmd) {
          case 'a' : scanauto=pick(1); sendOK(); 
                     if (scanauto) sblcd_show(LCD_ArrowRight); else sblcd_hide(LCD_ArrowRight);
                     break;
          case 'c' : sampletime=(0x1000*pick(1))/1000; sendOK(); break;
          case 's' : startTX(); tx_ch('S');
                     tx_int(dispch);
                     tx_int32((8000L*sampletime)/0x8000); // display in ms
                     tx_int(scanauto);
                     stopTX(); break;
          case 'd' : dispch=pick(1); 
                     if (dispch>5) { dispch=5; sendERR(); break; }
                     if (dispch<0) { dispch=0; sendERR(); break; }
                     sblcd_display_cntr(dispch); // Show counter
                     sendOK(); break;
          case 'm' : sblcd_show(LCD_Antenna);
                     doCount(); 
                     sblcd_hide(LCD_Antenna);
                     sblcd_display_cntr(dispch); // Show counter
                     send_result();              // Send the result on the UART
                     break;
          case 'v' : startTX(); tx_ch('V');tx_int(1); stopTX(); break;
          case 't' : startTX(); tx_ch('T');
                     ADC12MCTL0 = INCH_10+SREF_1;          // Select channel A10, Vref+
                     ADC12CTL0 |= ADC12SC;   // Start conversion
                     while (ADC12CTL1 & ADC12BUSY) { }; // Wait for conversion
                     ADCresult = ADC12MEM0;
                     //  DegC = (Vsensor - 986mV)/3.55mV
                     //  Vsensor = (Vref)(ADCresult)/4095)
                     //  DegC -> ((ADCresult - 1615)*704)/4095
                     DegC = ((((long)ADCresult-1615)*704)/4095);
                     DegF = ((DegC * 9/5)+32);           // Calculate DegF
                     tx_int(DegC); tx_int(DegF);
                     stopTX();
                     break;
          default  : sendERR(); break;
        }
        cmdDone(); // Clear command
     }
   
  }  

}
        

⌨️ 快捷键说明

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