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

📄 sound_system2.c

📁 此程序是用于AVR单片机驱动FLASH的,对于用AVR单片机进行开发的朋友,提供了一个例程,还有对于对使用FLASH没有经验的朋友也有很好参考价值
💻 C
字号:
/*****************************************************************************
*
* Atmel Corporation
*
* File              : sound_system2.c
* Compiler          : IAR EWAAVR 3.20C
* Revision          : $Revision: 1.4 $
* Date              : $Date: Monday, November 15, 2004 12:53:58 UTC $
*
* Support mail      : avr@atmel.com
*
* Supported devices : ATmega8535
*
* AppNote           : AVR335 Digital Sound Recorder.
*
*
****************************************************************************/


#include <inavr.h>
#include <ioavr.h>
#include "dataflash.h"

// prototypes
void setup (void);
void erasing (void);
void recording (void);     
void write_to_flash (unsigned char ad_data);
void playback (void);
void next_page_to_next_buffer (unsigned char active_buffer, unsigned int page_counter); 
void active_buffer_to_speaker (unsigned char active_buffer);
void write_SPI(unsigned char data);

// global variables  
volatile unsigned char wait = 0;


void setup(void)
{
    DDRB = 0xBD;                            // SPI Port initialisation
                                            // SCK, MISO, MOSI,  CS, LED,  WP , RDYBSY, RST
                                            // PB7, PB6,  PB5,  PB4, PB3, PB2 ,  PB1,   PB0
                                            //  O    I     O     O    O    O      I      O
                                            //  1    0     1     1    1    1      0      1
                                            
    PORTB = 0xFF;                           // all outputs high, inputs have pullups (LED is off) 
    DDRA = 0x00;                            // define port A as an input    
    PORTA = 0x00;
    DDRD = 0x10;                            // define port D as an input (D4: output)

    __enable_interrupt();                   // enable interrupts
}

void write_SPI(unsigned char data)
{
       SPDR = data;
       while (!(SPSR & 0x80));             // wait for data transfer to be completed
}

void erasing(void)
{
    unsigned int block_counter = 0;
    
    ACSR |= CLEARED;                           // set signal flag that new data has to be recorded next

    // interrupt disabled, SPI port enabled, master mode, MSB first,  SPI mode 3, Fcl/4
    SPCR = 0x5C;

    while (block_counter < 512)
    {
        PORTB &= ~DF_CHIP_SELECT;           // enable DataFlash
        
        write_SPI(BLOCK_ERASE);
        write_SPI((char)(block_counter>>3));
        write_SPI((char)(block_counter<<5));
        write_SPI(0x00);

        PORTB |= DF_CHIP_SELECT;            // disable DataFlash

        block_counter++;
        while(!(PINB & 0x02));              // wait until block is erased
    }
    SPCR = 0x00;                            //disable SPI        
}

 
void recording(void)
{   
    unsigned char count;
    // interrupt disabled, SPI port enabled, master mode, MSB first, SPI mode 3, Fcl/4
    SPCR = 0x5C;           
    ADMUX = 0x00;                           // A/D converter input pin number = 0
    ADCSRA = 0xD5;                           // single A/D conversion, fCK/32, conversion now started 
    do
    {
        do
        {
        } while(!(ADCSRA&(1<<ADIF)));         // Wait for A/D conversion to finish
        count = 6;                          
        do                                   // Customize this loop to 66 cycles !!
        {
        } while(--count);                   // wait some cycles
        ADCSRA |= 0x40;                      // start new A/D conversion 
        write_to_flash(ADC-0x1D5);          // read data, convert to 8 bit and store in flash 
    } while (!(PIND & 2));                  // loop while button for recording (button 1) is pressed

    ADCSRA = 0x00;                           // disable AD converter
    SPCR = 0x00;                            // disable SPI        
}

void write_to_flash(unsigned char flash_data)
{
    static unsigned int buffer_counter;
    static unsigned int page_counter;
    
    if((ACSR&CLEARED))                       // if flag is set that new data has to be written
    {
        buffer_counter = 0;
        page_counter = 0;                   // reset the counter if new data has to be written
        ACSR &= (~CLEARED);                       // clear the signal flag
    }

    while(!(PINB & 0x02));                  // check if flash is busy

    PORTB &= ~DF_CHIP_SELECT;               // enable DataFlash
     
    write_SPI(BUFFER_1_WRITE);
    write_SPI(0x00);                         // don't cares
    write_SPI((char)(buffer_counter>>8));    // don't cares plus first two bits of buffer address
    write_SPI((char)buffer_counter);         // buffer address (max. 2^8 = 256 pages)
    write_SPI(flash_data);                   // write data into SPI Data Register
        
    PORTB |= DF_CHIP_SELECT;                // disable DataFlash 
    
    buffer_counter++; 
        
    if (buffer_counter > 528)               // if buffer full write buffer into memory page
    {
        buffer_counter = 0;
        if (page_counter < 4096)            // if memory is not full   
        { 
            PORTB &= ~DF_CHIP_SELECT;       // enable DataFlash

            write_SPI(B1_TO_MM_PAGE_PROG_WITHOUT_ERASE);// write data from buffer1 to page 
            write_SPI((char)(page_counter>>6));
            write_SPI((char)(page_counter<<2));
            write_SPI(0x00);                    // don't cares
        
            PORTB |= DF_CHIP_SELECT;        // disable DataFlash
            page_counter++;
        }
        else
        {
            PORTB |= 0x08;                  // turn LED off
            while (!(PIND & 2));            // wait until button for recording (button 1) is released
        }
    }
}


void playback(void)
{      
    unsigned int page_counter = 0;
    unsigned char active_buffer = 1;        // active buffer = buffer1

    TCCR1A = 0x21;                          // 8 bit PWM, using COM1B
    TCNT1 = 0x00;                           // set counter1 to zero      
    TIFR = 0x04;                            // clear counter1 overflow flag 
    TIMSK = 0x04;                           // enable counter1 overflow interrupt
    TCCR1B = 0x01;                          // counter1 clock prescale = 1
    OCR1B = 0x00;                           // set output compare register B to zero
    
    // interrupt disabled, SPI port enabled, master mode, MSB first,  SPI mode 3, Fcl/4
    SPCR = 0x5C;
        
    next_page_to_next_buffer (active_buffer, page_counter);  // read page0 to buffer1 
        
    while (!(PINB & 0x02));                 // wait until page0 to buffer1 transaction is finished
    
    while ((page_counter < 4095)&(!(PIND & 4))) // while button for playback (button 2) is pressed
    {   
        page_counter++;                     // now take next page
         
        next_page_to_next_buffer (active_buffer, page_counter);         
        active_buffer_to_speaker (active_buffer);        
        
        if (active_buffer == 1)             // if buffer1 is the active buffer
        {
          active_buffer++;                    // set buffer2 as active buffer
        }
        else                                // else
        {
          active_buffer--;                    // set buffer1 as active buffer
        }      
    }
    TIMSK = 0x00;                           // disable all interrupts
    TCCR1B = 0x00;                          // stop counter1
    SPCR = 0x00;                            // disable SPI
}


void next_page_to_next_buffer (unsigned char active_buffer, unsigned int page_counter)
{
    while(!(PINB & 0x02));                  // wait until flash is not busy
    
    PORTB &= ~DF_CHIP_SELECT;               // enable DataFlash
                
    if (active_buffer == 1)                 // if buffer1 is the active buffer
    {
          write_SPI(MM_PAGE_TO_B2_XFER);      // transfer next page to buffer2
    }
    else                                    // else
    {
           write_SPI(MM_PAGE_TO_B2_XFER);          // transfer next page to buffer1
    }
    write_SPI((char)(page_counter >> 6));
    write_SPI((char)(page_counter << 2));
    write_SPI(0x00);

    PORTB |= DF_CHIP_SELECT;                // disable DataFlash and start transaction     
}
 

#pragma vector = TIMER1_OVF_vect
__interrupt void out_now(void)
{
   ACSR |= T1_OVF;                                // an interrupt has occured 
}                          


void active_buffer_to_speaker (unsigned char active_buffer)
{
    // until active buffer not empty read active buffer to speaker
    
    unsigned int buffer_counter = 528;
        
    PORTB &= ~DF_CHIP_SELECT;               // enable DataFlash     

    if (active_buffer == 1)                 // if buffer1 is the active buffer
    {
        write_SPI(BUFFER_1_READ);           // read from buffer1
    }
    else                                    // else
    {
        write_SPI(BUFFER_2_READ);               // read from buffer2
    }
    write_SPI(0x00);                          // write don't care byte
    write_SPI(0x00);                          // write don't care byte
    write_SPI(0x00);                          // start at buffer address 0
    write_SPI(0x00);                          // write don't care byte
         
    do
    {
        write_SPI(0xFF);                     // write dummy value to start register shift
        while(!(ACSR&T1_OVF));                        // wait for timer1 overflow interrupt            
        OCR1B = SPDR;                       // play data from shift register
        ACSR &= (~T1_OVF);                           // clear the signal flag               
     } while (--buffer_counter);                          
     PORTB |= DF_CHIP_SELECT;               // disable DataFlash
}


void main(void)
{   
    setup();
    
    for(;;)
    {       
        if (!(PIND & 2))                    // if button for recording (button 2) is pressed
        {
            PORTB &= 0xF7;                  // turn LED on
            recording();       
        }     
        if (!(PIND & 1))                    // if button for erasing (button 0) is pressed
        {            
            PORTB &= 0xF7;                  // turn LED on
            erasing();
            while (!(PIND & 1));            // wait until button for erasing (button 0) is released          
        }       
        if (!(PIND & 4))                    // if button for playback (button 3) is pressed
        {
            PORTB &= 0xF7;                  // turn LED on      
            playback();
            while (!(PIND & 4));            // wait until button for playback (button 3) is released             
        }
    PORTB |= 0x08;                          // turn LED off while running idle
    }
} 

⌨️ 快捷键说明

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