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

📄 project.c

📁 Atme AVR digital voltmeter examples!
💻 C
📖 第 1 页 / 共 2 页
字号:
	 
	 PORTB &= ~DF_CHIP_SELECT;			   //Enable Flash
	 
	 if (active_buffer == 1) {			   //Transfer page to inactive buffer
	 	WRITE_SPI (MM_PAGE_TO_B2_XFER);
	 }
	 else {
	 	WRITE_SPI (MM_PAGE_TO_B1_XFER);
	 }
	 if (buffer_max == 528) {
	 	WRITE_SPI (page_counter >> 6); 	   //Write first part of page counter
	    WRITE_SPI (page_counter << 2); 	   //Write next part of page counter
	 }
	 else {
	 	WRITE_SPI (page_counter >> 7); 	   //Write first part of page counter
	    WRITE_SPI (page_counter << 1); 	   //Write next part of page counter
	 }
	 WRITE_SPI (0x00); 					   //Dont care bits	 
	 
	 PORTB |= DF_CHIP_SELECT;			   //Disable the DataFlash	 
}

//Retrieves the contents of the active buffer in the DataFlash and writes it
//to the PWM module in sync. with the sampling frequency.
void active_buffer_to_speaker (unsigned char active_buffer) {
	 unsigned int buffer_counter = 0;
	 unsigned char temp = 0x80;
	 
	 PORTB &= ~DF_CHIP_SELECT; 	   	 	   //Enable Flash	 
	 
	 if (active_buffer == 1) {			   //Transfer page to inactive buffer
	 	WRITE_SPI (BUFFER_1_READ);		   //Command to read buffer 1
	 }
	 else {
	 	WRITE_SPI (BUFFER_2_READ);		   //Command to read buffer 2
	 }
	 WRITE_SPI (0x00); 					   //Dont care bits	 
	 WRITE_SPI (0x00); 					   //Dont care bits	 
	 WRITE_SPI (0x00); 					   //Dont care bits	 
	 WRITE_SPI (0x00); 					   //Dont care bits	 

	 while (buffer_counter < buffer_max) { //As long as buffer is not done...
		   while (!sync);  				   //Wait for synchronization
		   sync = 0;					   //Clear the sync.
	 	   SPDR = 0xFF;	   	 	   		   //Send a Dummy value
		   while (!(SPSR & temp));		   //Wait for transfer
		   OCR1B = SPDR;				   //Write to PWM module
		   buffer_counter++;			   //increment buffer pos.
	 } 
	 PORTB |= DF_CHIP_SELECT;			   //Disable the DataFlash	 
}

//Retrieves digital audio from the DataFlash and plays it back on the speaker.							     
void playback (void) {
 	 unsigned int page_counter = 0;
 	 unsigned int buffer_counter = 0;
	 unsigned char active_buffer = 1;
	 unsigned char temp = 0x80;
	 
	 enable_PWM ();
	 enable_timer0 ();
	 SPCR = 0x5C;  	  	  	   	   	 	//Enable SPI, master mode, MSB first,
	 	  								//SPI mode 3, 2MHz clock
	 reset_rec = 1;										   										   
	 //Read first page to buffer									   										   										   
	 next_page_to_next_buffer (active_buffer, page_counter);
	 while (!(PINB & 0x02));  	 		   //Wait for Flash to be ready
	 										   
	 sync = 0;
	 while (!(PIND&0x01) || lock) {					//While play is pressed
	 	   if (page_counter < 4096) {
		   	  page_counter++; 		 		//Read from the next page   

			  //Copy the next page into the inactive buffer			  
			  next_page_to_next_buffer (active_buffer, page_counter);
			  //Play the active buffer
			  active_buffer_to_speaker (active_buffer);

			  //swap buffers			  
			  if (active_buffer == 1) active_buffer++;
			  else active_buffer--;
		   }
		   else {
		   		//TODO:
		   		//Indicate that the end is reached
			 	led_state |= 0x01;
		   }
		   if (lock) {						   			   		
		   	  if (!(PIND&0x08)) lock = 0;
			  led_state |= 0x08;						   			   		
		   }
		   else {
		      if (!(PIND&0x08)) lock = 1;
			  led_state &= ~0x08;						   			   		
		   }		   						   			   		
	 }
	 lock = 0;
	 TCCR0 = 0x00;	  	  //Disable Timer0
	 TCCR1B = 0x00;  	  //Disable Timer1PWM
	 SPCR = 0x00;		  //Disable SPI
	 PORTC = 0xFF;		  //Turn off LEDs
}

//Records digital audio from the mike and stores it in the DataFlash
void record (void) {
 	 static unsigned int page_counter = 0;
 	 static unsigned int buffer_counter = 0;
	 static unsigned char active_buffer = 1;
	 static unsigned char temp = 0x80;
	 
	 if (ACSR&0x02) {	  	   //ACSR bit 1 is used to determine if data has
	 						   //been erased (ie, start from previous point
							   //or from start of memory)
	 	buffer_counter = 0;	   //If ACSR has been set, make the position vars.
		page_counter = 0;	   //point to the beginning of Flash
		ACSR &= 0xFD;  		   //Clear the flag
		active_buffer = 1;	   //Make Buffer 1 active.
	 }
	 
	 if (reset_rec) { 	  	   //If some other function is called after
	 						   //the previous record session, align the
							   //new data to a page boundary and reset the
							   //active buffer.
	 	active_buffer = 1;	   //Set active buffer to 1
		buffer_counter = 0;	   //Clear buffer pos.
		reset_rec = 0; 	 	   //Make sure this happens only once per session.
	 }

	 init_ADC ();
	 enable_timer0 ();
	 SPCR = 0x5D;  	  	  	   	   	 	   //Enable SPI, master mode, MSB first,
	 	  								   //SPI mode 3, 2MHz clock
	 while (!(PIND&0x02) || lock) {				   //As long as record is pressed...
	 	   if (page_counter < 4096) {
		   	  page_counter++; 		 		//Read from the next page   

			  prev_page_to_prev_buffer (active_buffer, page_counter);
			  //Play the active buffer
			  adc_to_active_buffer (active_buffer);

			  //swap buffers			  
			  if (active_buffer == 1) active_buffer++;
			  else active_buffer--;
		   }
		   else {
		   		//TODO:
		   		//Indicate that the end is reached
			 	led_state |= 0x02;
		   }
		   if (lock) {						   			   		
		   	  if (!(PIND&0x08)) lock = 0;
			  led_state |= 0x08;						   			   		
		   }
		   else {
		      if (!(PIND&0x08)) lock = 1;
			  led_state &= ~0x08;						   			   		
		   }		   						   			   		
	 }
	 TCCR0 = 0x00;	  	  //Disable Timer0
	 SPCR = 0x00;		  //Stop SPI 
	 PORTC = 0xFF;		  //Turn off all LEDs.
}

//Erases the DataFlash and resets the recording position to the start of the
//DataFlash memory.
void erase (void) {
	 int block_counter = 0;
	 unsigned char temp = 0x80;
	 
	 ACSR |= 0x02; 		 //Indicates that recording is to start from beginning
	 	  	 			 //of flash, and not from where it was left off last.	 
	 SPCR = 0x5C;		 //Enable SPI

	 min_val = 0x1FF;	 
	 while (block_counter < 512) {
	 	   PORTB &= ~DF_CHIP_SELECT; 	 	 	  //Select Flash
		   WRITE_SPI (BLOCK_ERASE);				  //Write command
		   if (buffer_max == 528) {
		   	  WRITE_SPI (block_counter >> 3);	  //Which block to erase
		   	  WRITE_SPI (block_counter << 5);
		   }
		   else {
		   	  WRITE_SPI (block_counter >> 4);
		   	  WRITE_SPI (block_counter << 4);
		   }
		   WRITE_SPI (0x00);		   	  	 	  //Dont care value
	 	   PORTB |= DF_CHIP_SELECT;				  //Deselect Flash
		   block_counter++;
		   while (!(PINB & 0x02));		   
	 }
	 SPCR = 0x00;		   		   	   //Disable SPI
	 led_state = 0x04;				   //Enable Blinking erase LED.	 	   
	 while (!(PIND&0x04));			   //Wait till user releases Erase key
	 //Short pause, for debouncing
	 for (block_counter = 0; block_counter < 10000; block_counter++); 
	 PORTC = 0xFF;		  	 		   //Turn off all LEDs.
}

//Loops the audio from the mike to the speaker.
void loopback (void) {
	 unsigned char t;
	 enable_PWM ();
	 init_ADC ();
	 enable_timer0 ();
	 
	 min_val = 0xFF;

	 while (!(PIND&0x08)){ //Wait till the user lets go of the key
	 	 OCR1BL = (adc_value - min_val) >> 1;
		 /*
		 t = mu_table [abs(adc_value - 533)];
		 if (adc_value < 533) OCR1BL = 128 - t;
		 else OCR1BL = t + 128;
		 */ 
	 	 ADCSR = 0xC9;
		 while (!sync);
		 sync = 0;
		 if ((PIND&0x03)!=0x03) break;
	 }

	 TCCR0 = 0x00;	  	  //Disable Timer0
	 TCCR1B=0x00;  	  	  //Disable Timer1 (PWM)
	 PORTC = 0xFF;		  //Turn off all LEDs.
}

//This function generates a short beep at ~2000Hz.
void beep (void) {
	 int i;
	 unsigned char c = 64;		  //initial value of C

	 enable_PWM ();
	 enable_timer0 ();	 
	 for (i = 0; i < 400; i++) {
	 	 OCR1B = c;	 	  	   	  //write value to PWM
		 while (!sync);			  //Wait for sync 4 times (2000Hz)
		 sync = 0;
		 while (!sync);
		 sync = 0;
		 while (!sync);
		 sync = 0;
		 while (!sync);
		 sync = 0;
		 
		 c = 192 - c;  			  //invert the value of c		 		 
	 }
	 TCCR1B = 0x00;				  //Stop PWM
	 TCCR0 = 0x00;				  //Stop timer0
}

//Retrieves the chip ID of the attached DataFlash and sets the maximum buffer
//size. In case an SPI error occurs (missing/damaged DataFlash), a long beep
//is sounded and the Voice Recorder functions are disabled.
void get_chip_id (void) {
	 unsigned char temp = 0x80;

	 PORTB &= ~DF_CHIP_SELECT; 		//Enable Flash
	 SPCR = 0x5C;					//Enable SPI
	 WRITE_SPI (STATUS_REGISTER);	//Write command to retrieve status register
	 WRITE_SPI (0xFF);				//Write dummy value
	 PORTC = ~(SPDR >> 3);			//Show the device code on LEDs at startup
	 if ((SPDR & 0x38)==0x20) {
	 	buffer_max = 264;	   		//Set buffer length for AT45DB081A
	 }
	 else if ((SPDR & 0x38)==0x28) {
	 	buffer_max = 528;			//Set buffer length for AT45DB081A
	 }
	 else {		   	 				//An error has occured... missing Flash?
	 	  beep ();					//Long beep
		  beep ();
		  led_state = 0x0F;			//Make LEDs flash
		  for (;;);	  	   			//Prevent further use till reset.
	 }
	 SPCR = 0x00;  	 				//Disable SPI
	 PORTB |= DF_CHIP_SELECT;		//Deselect Flash
}

//Main function
void main () {
	 setup ();
	 //Set up Timer 2 (used to flash LEDs)
	 ASSR = 0x00;		  //set async mode
	 TCCR2 = 0x07;		  //Enable Timer2 with prescaler set to /8	 
	 TIMSK |= 0x40;		  //Enable Timer2 interrupt in mask register

	 get_chip_id ();	  //Get the ident. of memory attached.
	 beep ();	 		  //Signal to the user that device is ready
	 	 	 
	 for (;;) {
		 led_state = 0x00;		//Stop all LEDs from flashing.
	 	 if(!(PIND&0x01)) {		//If play key is pressed,
		 	  if (!(PIND&0x08)) lock = 1;
			  PORTC = 0xFE; 	//Light up the play LED...
			  playback ();		//...and start playback.
		 }			  		
	 	 if(!(PIND&0x02)) {		//If record key is pressed,
		 	  if (!(PIND&0x08)) lock = 1;
			  PORTC = 0xFD; 	//Light up record LED...
			  record ();		//...and start recording.
		 }			  		
	 	 if(!(PIND&0x04)) {		//If erase key is pressed,
			  PORTC =  0xFB;	//Light up erase LED...	 
			  erase();			//...and start erasing.
		 }
	 	 if(!(PIND&0x08)) {		//Do loopback if loopback key is pressed.
			  PORTC = 0xF7;
			  loopback();
		 }
	 }
}

⌨️ 快捷键说明

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