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

📄 main.c

📁 This code is using for rpm measurement.
💻 C
字号:
/*********************************************
Project : RPM counter
Version : 1.0
Date    : 19-08-2004
Author  : Jan Thogersen                   
Email   : jan@future-design.dk
Company :                                 
Comments: The project here measures the time
          between two pulses and calculates
          the RPM from a average of several
          measurements.
          The project uses a 16 bit timer to
          measure the time between pulses,
          however, to extend the RPM range
          the 16 bit hardware timer is extended
          with an extra software layer. The end
          product is a 32 bit timer. Which makes
          the measurement very accurate and with
          a large range. To minimize the software
          footprint the timer is running in
          Indput Capture mode. So the essential
          of this project is done 100% in hardware.

Chip type           : AT90S2313
Clock frequency     : 8,000000 MHz
Memory model        : Tiny
Internal SRAM size  : 128
External SRAM size  : 0
Data Stack size     : 32
*********************************************/

#include <90s2313.h>


// Here is the definition of which port pin is used for which LED in the matrix.

// The following defines is the ROW in the matrix.
// These values can be changed to fit the PCB layout.
#define A	   4
#define B	 128  
#define C	  32 
#define D	   2
#define E	   1
#define F	  16 
#define G	  64 
#define Dod    8

// The following defines is the COL in the matrix.
// These values can be changed to fit the PCB layout.
#define COL_A   0x1C
#define COL_B   0x2C
#define COL_C   0x34
#define COL_D   0x38

// Definition of the 7 segment numbers
//         A
//      -----    
//   F | G  | B
//    |----|
// E |    | C
//   -----o
//     D   Dod

const unsigned char kucDigi[] = { 
    (A+B+C+D+E+F),   // 0
    (B+C),   // 1
    (A+B+G+E+D),   // 2
    (A+B+C+D+G),   // 3
    (B+C+F+G),   // 4
    (A+C+D+F+G),   // 5
    (A+C+D+E+F+G),   // 6
    (A+B+C),   // 7
    (A+B+C+D+E+F+G),   // 8
    (A+B+C+D+F+G),   // 9
    (0)    // blank
};

const unsigned char kucCOLUMS[] = {COL_A, COL_B, COL_C, COL_D};

#define  NumMeasures 	2  // The output is a average of the X readings  

unsigned char ucLEDS[4], ucLED_POS;
unsigned char ucCiffer[4];
unsigned int  uiTempDigi, uiOutput;
unsigned long ulMeasuredTime;
unsigned char ucOutputOutOfRange;
unsigned long ulMeasured[NumMeasures];
unsigned char ucMeasuredPos;

// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
// Place your code here
    // Here is the 7 segment matrix scanner.
    TCNT0=0xF0; // This value can be changes to scan faster or slower.
    PORTD = kucCOLUMS[ucLED_POS];
    PORTB = ucLEDS[ucLED_POS];
    ucLED_POS++;
    if (ucLED_POS == 4) ucLED_POS = 0;
}

// Timer 1 overflow interrupt service routine
interrupt [TIM1_OVF] void timer1_ovf_isr(void)
{
// Place your code here

    // When we receive a Timer overflood interrupt
    // then we add 1 to the high 16 bit of the
    // ulMeasuredTime. Why?
    // The timer is 16 bit. Thats not enough so we add
    // another 16 bit, however this time in software.
    // The end product is a 32 bit unsigned long ulMeasuredTime.
    // The low 16 bit is for the hardware value from the timer, the
    // high 16 bit is for the software timer part.
    // So a the overflood we simply add 1 to the software part.
    // Later when we have the Input Capture Interrupt we can complete
    // the process by adding the hardware value from the timer
    // to the low 16 bit of the ulMeasuredTime. 

    ulMeasuredTime += 0x10000;  

    // The ucOutputOutOfRange is a variable used to
    // verify that we have an input or not. It's a form
    // of timeout. When there is a overflood like now, then
    // we decrease the value by one.
    // If the value reaches zero, then we make the
    // assumption that there is no signal.
    if (ucOutputOutOfRange > 0) ucOutputOutOfRange--;
}

// Timer 1 input capture interrupt service routine
interrupt [TIM1_CAPT] void timer1_capt_isr(void)
{
// Place your code here
    if (ucOutputOutOfRange < 16) ucOutputOutOfRange+=4;

    // Place the hardware timer value into the 32 bit accumulation.
    ulMeasuredTime += ICR1;
    TCNT1 = 0;

    // The output is based on an average, so we save the measurements.
    // This is not the best way to do it. I know that. But it was fast to code
    // And I had enough RAM to do it. But a waste I know.
    ulMeasured[ucMeasuredPos] = ulMeasuredTime;
    ucMeasuredPos++;
    if (ucMeasuredPos >= NumMeasures) ucMeasuredPos = 0;

    ulMeasuredTime = 0;
}

// Declare your global variables here
char cTempCnt;
unsigned long ulSum;

void main(void)
{
// Declare your local variables here

// Input/Output Ports initialization
// Port B initialization
// Func0=Out Func1=Out Func2=Out Func3=Out Func4=Out Func5=Out Func6=Out Func7=Out 
// State0=1 State1=1 State2=1 State3=1 State4=1 State5=1 State6=1 State7=1 
    PORTB=0xFF;
    DDRB=0xFF;

// Port D initialization
// Func0=Out Func1=Out Func2=Out Func3=Out Func4=In Func5=In Func6=In 
// State0=1 State1=1 State2=1 State3=1 State4=T State5=T State6=T 
    PORTD=0x3C;
    DDRD=0x3C;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 31,250 kHz
    TCCR0=0x04;
    TCNT0=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 125,000 kHz
// Mode: Normal top=FFFFh
// OC1 output: Discon.
// Noise Canceler: On
// Input Capture on Faling Edge
    TCCR1A=0x00;
    TCCR1B=0x83;
    TCNT1H=0x00;
    TCNT1L=0x00;
    OCR1H=0x00;
    OCR1L=0x00;

// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
    GIMSK=0x00;
    MCUCR=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization
    TIMSK=0x8A;

// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
// Analog Comparator Output: Off
    ACSR=0x80;

// Global enable interrupts
#asm("sei")

    uiOutput =  0;

    while (1) {

        ulSum = 0;

        // Calculate the average
        for (cTempCnt = 0; cTempCnt < NumMeasures; cTempCnt++) ulSum += ulMeasured[cTempCnt];
        uiOutput = (long)ulSum / NumMeasures; 

        // Calculate the RPM from the average time between pulses.
        uiTempDigi = (long)(125000*60*NumMeasures) / ulSum;

        // Place your code here
        if (ucOutputOutOfRange > 4) { // > 4 then Ok Else to many overfloads...

            // Check if the RPM is higner than we can show in the display else show "out of range" in the display.
            if (uiTempDigi < 10000) {

                // A simple binary to BCD converter.
                for (cTempCnt = 4;cTempCnt > 0;cTempCnt--) {
                    ucCiffer[4 - cTempCnt] = (uiTempDigi % 10);
                    uiTempDigi = uiTempDigi / 10;
                }

                // Swap a leading zero with "blank"
                for (cTempCnt = 3;(ucCiffer[cTempCnt] == 0) && (cTempCnt > 0);cTempCnt--) {
                    ucCiffer[cTempCnt] = 0x0A;
                }

                // convert the BCD calue to port values.
                for (cTempCnt = 0;cTempCnt < 4;cTempCnt++)
                    ucLEDS[cTempCnt] = ~kucDigi[ucCiffer[cTempCnt]];

                // Flash the comma in the last digi if there is a signal input
                if (PIND.6 == 0) ucLEDS[0] &= ~(Dod);

            } else {
                // Show out of range in display
                if (PIND.6 == 0) ucLEDS[0] = ~(A+D+E+F+Dod);
                else ucLEDS[0] = ~(A+D+E+F);
                ucLEDS[1] = 0xFF;
                ucLEDS[2] = 0xFF;
                ucLEDS[3] = ~(A+B+C+D);
            }
        } else {
            // If we had to many overfloods (No signal) then we show that in the display
            // so it is visible for the user that there is no signal.
            if (PIND.6 == 0) ucLEDS[0] = ~(G+Dod);
            else ucLEDS[0] = ~(G);
            ucLEDS[1] = ~G;
            ucLEDS[2] = ~G;
            ucLEDS[3] = ~G;
        }
    };
}

⌨️ 快捷键说明

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