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

📄 demonstrator.c

📁 The collection of AVR source code in C.
💻 C
字号:
// Demonstrator.c Function Generator / Digital Oscilloscope version

#include "PC_Comm.h"
#include "Messages.h"
#include "WaveTables.h"

unsigned char count = 0;
unsigned char tenth = 0;
//unsigned long signal = 0; // used for test
	
void initializer()
{
	// Calibrate the oscillator:
    OSCCAL_calibration();   

	// Initialize the USART
	USARTinit();
	
	// set PORTD for output
	DDRD = 0xFF;
	
	// Display instructions on PC
	sendFString(TALKING_TO);
	sendFString(WHO_DEMO);
	
	sendFString(ENTER);
	sendFString(TEXT_CTC);
	
	sendFString(ENTER);
	sendFString(TEXT_SINE);
	sendFString(TO_START);	
	sendFString(TEXT_SINE);
	sendFString(WAVE);

	sendFString(ENTER);
	sendFString(TEXT_SQUARE);
	sendFString(TO_START);	
	sendFString(TEXT_SQUARE);
	sendFString(WAVE);
	
	sendFString(ENTER);
	sendFString(TEXT_SAWTOOTH);
	sendFString(TO_START);	
	sendFString(TEXT_SAWTOOTH);
	sendFString(WAVE);
	
	sendFString(ENTER);
	sendFString(TEXT_TRIANGLE);
	sendFString(TO_START);	
	sendFString(TEXT_TRIANGLE);
	sendFString(WAVE);	
	
	
	MilliSec_init(250); // default to 1000 Hz	
	
	DigitalOscilloscopeTimerInit();

	ADC_init();
	
	startSine();
}

void parseInput(char s[])
{

	// parse first character	
	switch (s[0])
	{
		case 's':
			if( (s[1] == 'i') && (s[2] == 'n')&& (s[3] == 'e'))
				startSine();
			else if( (s[1] == 'q') && (s[2] == 'u')&& (s[3] == 'a')&& (s[4] == 'r')&& (s[5] == 'e'))
				startSquare();
			else if( (s[1] == 'a') && (s[2] == 'w')&& (s[3] == 't')&& (s[4] == 'o')&& (s[5] == 'o')&& (s[6] == 't')&& (s[7] == 'h'))
				startSawtooth();
			break;
		case 't':
			if( (s[1] == 'r') && (s[2] == 'i')&& (s[3] == 'a')&& (s[4] == 'n')&& (s[5] == 'g')&& (s[6] == 'l')&& (s[7] == 'e'))
			startTriangle();
			break;		
		case 'c':
			if( (s[1] == 't') && (s[2] == 'c'))
			parse_ctc(s);
			break;
		case 'd':
			if( (s[1] == 'e') && (s[2] == 'm') && (s[3] == 'o') && (s[4] == '?') )
			sendFString(TALKING_TO);
			sendFString(WHO_DEMO);
			break;
		default:
			sendFString(BAD_COMMAND1);
			sendChar(s[0]);
			sendFString(BAD_COMMAND2);

			break;
		
	}
	s[0] = '\0';
}

int parse_ctc(char s[])
{
	char ctc[11];
	unsigned char i = 3, j = 0;

	while( (s[i] != '\0') && (j <= 11) ) 
	{
	
		if( (s[i] >= '0') && (s[i] <= '9') )
		{
			ctc[j++] = s[i++];
		}
		else
		{
			sendFString(ERROR_NONINT);
			sendChar(s[i]);
			sendChar('\r');
			return 0;
		}
	}
	
	ctc[j] = '\0';
	
	if(j>4)// must be < 256
	{
		sendFString(ERROR_NUMTOLARGE);
		return 0;
	}
	else
	{
		set_ctc(atoi(ctc));
	}
		
	return 1;
}

void set_ctc(int count)
{
	char ctc[11];

	sendString("Setting the Compare Timer Count to: ");
	itoa(count,ctc,10);	
	sendString(ctc);
	sendChar('\r');
	
	MilliSec_init(count);

}

void startWave(int wave)
{	
 	sendFString(TEXT_SETTING);
	sendFString(TEXT_WAVE_TBL[wave]);     // Send the song title to the PC
	sendChar('\r');
            
	pWave=(int*)pgm_read_word(&Waves[wave]); // looks too complicated..
}

void startSine()
{
	startWave(0);
}
void startSquare()
{
	startWave(1);
}
void startSawtooth()
{
	startWave(2);
}
void startTriangle()
{
	startWave(3);
}


/*
The USART init set the system oscillator to 2 mHz. We set the Timer0 prescaler
to clk/8 which gives a 250 kHz input to the timer/counter. A compare of 250 throws
an interrupt every millisecond.
*/
void MilliSec_init(unsigned char count)
{
	// Initialize Timer0.

    // Enable timer0 compare interrupt
	TIMSK0 = (1<<OCIE0A);

	// Sets the compare value
	set_OCR0A(count);
	
	// Set Clear on Timer Compare (CTC) mode, 
	TCCR0A = (1<<WGM01)|(0<<WGM00)|(1<<CS02)|(0<<CS01)|(0<<CS00);

}

// Initialize for 1 millisecond interrupt
void DigitalOscilloscopeTimerInit()
{
	// Initialize Timer2.

    // Enable timer2 compare interrupt
	TIMSK2 = (1<<OCIE2A);

	// Sets the compare value
	OCR2A = 1;
	
	// Set Clear on Timer Compare (CTC) mode, 
	TCCR2A = (1<<WGM21)|(0<<WGM20)|(1<<CS22)|(0<<CS21)|(0<<CS20);

}


void set_OCR0A(unsigned char count)
{    
	// Sets the compare value
	OCR0A = count;
}


// Interrupt occurs once per millisecond
SIGNAL(SIG_OUTPUT_COMPARE0)
{
//	signal += pgm_read_word(pWave + count);  // used for test
	PORTD = pgm_read_word(pWave + count++);      // read table
	tenth++;	
}


// Interrupt occurs once per millisecond
SIGNAL(SIG_OUTPUT_COMPARE2)
{
	int sig = 0;
	
	sig = ADC_read();
	
	if (tenth >= 10) 
	{
		tenth = 0;
		
		for(int i = 0; i < (sig/4); i++)
		{
			sendChar(' ');
		}
		sendChar('*');
		sendChar('\r');
	}	

/*	// Test code to output wave from table to Hyperterminal
	if (tenth >= 10) 
	{
		tenth = 0;
		signal /= 50;
		
		for(int i = 0; i < signal; i++)
		{
			sendChar(' ');
		}
		sendChar('*');
		sendChar('\r');
		signal = 0;
	}	
*/	

}

/**********************************************************************************
	ADC common functions
***********************************************************************************/

void ADC_init()
{
	int dummy = 0;
	
    ADMUX = 1;   

    // set ADC prescaler to , 1MHz / 8 = 125kHz    
    ADCSRA = (1<<ADEN) | (1<<ADPS1) | (1<<ADPS0);    

    //  Take a dummy reading , which basically allows the ADC 
    // to hack up any hairballs before we take any real readings
    dummy = ADC_read();       
}

int ADC_read(void)
{
    char i;
    int ADC_temp;
	// mt int ADC = 0 ;
	int ADCr = 0;
    
    // To save power, the voltage over the LDR and the NTC is turned off when not used
    // This is done by controlling the voltage from a I/O-pin (PORTF3)
    sbi(PORTF, PF3); // mt sbi(PORTF, PORTF3);     // Enable the VCP (VC-peripheral)
    sbi(DDRF, DDF3); // sbi(DDRF, PORTF3);        

    sbi(ADCSRA, ADEN);     // Enable the ADC

    //do a dummy readout first
    ADCSRA |= (1<<ADSC);        // do single conversion
    while(!(ADCSRA & 0x10));    // wait for conversion done, ADIF flag active
        
    for(i=0;i<8;i++)            // do the ADC conversion 8 times for better accuracy 
    {
        ADCSRA |= (1<<ADSC);        // do single conversion
        while(!(ADCSRA & 0x10));    // wait for conversion done, ADIF flag active
        
        ADC_temp = ADCL;            // read out ADCL register
        ADC_temp += (ADCH << 8);    // read out ADCH register        

        ADCr += ADC_temp;      // accumulate result (8 samples) for later averaging
    }

    ADCr = ADCr >> 3;     // average the 8 samples
        
    cbi(PORTF,PF3); // mt cbi(PORTF, PORTF3);     // disable the VCP
    cbi(DDRF,DDF3); // mt cbi(DDRF, PORTF3);  
    
    cbi(ADCSRA, ADEN);      // disable the ADC

    return ADCr;
}

⌨️ 快捷键说明

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