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

📄 main.c

📁 AVR_butterfly_BOOT是AVR单片机的BOOT程序
💻 C
📖 第 1 页 / 共 2 页
字号:
        {
          sendchar(read_program_memory(0x0000,0x09)); // 0x09 for (1<<BLBSET)|(1<<SPMEN)
        }

        else if(val=='r')                   // read lock bits
        { 
          sendchar(read_program_memory(0x0001,0x09));
        }        

        else if(val=='N')                   // read high fuse bits
        {
          // mt sendchar(read_program_memory(0x0003));
		  sendchar(read_program_memory(0x0003,0x09));
        }        

        else if(val=='Q')                   // read extended fuse bits
        {
          sendchar(read_program_memory(0x0002,0x09));
        }
#endif	
// end of ENABLEREADFUSELOCK section

        else if(val=='t')                   // Return programmer type 
        {
          sendchar(devtype);
          sendchar(0);
        }

        else if ((val=='x')||(val=='y'))	// mt: clear and set LED ignored
        {
          recchar();
          sendchar('\r');
        }
       
       else if (val=='T')	// mt:  set device/programmer type in bootloader (?)
       {
         device = recchar();
          sendchar('\r');
       }
        
        else if (val=='S')                  // Return software identifier 
        {
          sendchar('A');
          sendchar('V');
          sendchar('R');
          sendchar('B');
          sendchar('O');
          sendchar('O');
          sendchar('T');
        }                
        
        else if (val=='V')                  // Return Software Version
        {
          sendchar('0');	// mt: changed from 2;0 to 0;1 
          sendchar('2');
        }        

        else if (val=='s')                  // Return Signature Byte
        {
          sendchar(sig_byte1);
          sendchar(sig_byte2);
          sendchar(sig_byte3);
        }       

        else if(val!=0x1b)                  // if not esc
        {
          sendchar('?');
        }
      }

	  return 0;
}

/*
void USART_Init(unsigned int baudrate)
{
    // Set baud rate
    UBRR0H = (unsigned char)(baudrate>>8);
    UBRR0L = (unsigned char)baudrate;

    // Enable 2x speed
    UCSR0A = (1<<U2X0);

    // Enable receiver and transmitter
    UCSR0B = (1<<RXEN0)|(1<<TXEN0)|(0<<RXCIE0)|(0<<UDRIE0);

    // Async. mode, 8N1
    UCSR0C = (0<<UMSEL0)|(0<<UPM00)|(0<<USBS0)|(3<<UCSZ00)|(0<<UCPOL0);
}
*/

void sendchar(char data)
{
    int i = 0;
    
    UDR = data;
    
    if(SREG & 0x80)
    {
		while ( !(UCSRA&0x40) && (i<10000) )
		{
			i++;
		}
    }
    else 
        while( !(UCSRA&0x40) );
        
    UCSRA=UCSRA|0x40;                             //delete TXCflag
}


char recchar(void)
{
    int i = 0;
    
    if(SREG & 0x80)
    {
		while (!(UCSRA & (1<<RXC)) && (i<10000))
		{
			i++;
		}
    }
    else
        while(!(UCSRA & (1<<RXC)));
        
    return UDR;
}


// mtA
// #pragma vector = PCINT1_vect
// __interrupt void PCINT1_interrupt(void)
// mt TODO: find out if the handler is needed
// mtE
// SIGNAL(SIG_PIN_CHANGE1)
ISR(PCINT1_vect)
{
//    __no_operation();
}

unsigned char BufferLoad(unsigned int size, unsigned char mem)
{
	int data, tempaddress, cnt;
	
	// store values to be programmed in temporary buffer
	for (cnt=0; cnt<UART_RX_BUFFER_SIZE; cnt++) {
		if (cnt<size) gBuffer[cnt]=recchar();
		else gBuffer[cnt]=0xFF;
	}
	cnt=0;
	
	tempaddress = address;					// Store address in page
	
	if (device == devtype)
	{
		if (mem == 'F')
		{

			do {
				data = gBuffer[cnt++];
				data |= (gBuffer[cnt++]<<8);
				fill_temp_buffer(data,(address));
											//call asm routine. 
				address=address+2;  		// Select next word in memory
				size -= 2;					// Reduce number of bytes to write by two
	    
			} while(size);					// Loop until all bytes written

			tempaddress &= 0xFF80;			// Ensure the address points to the first byte in the page
			write_page((tempaddress),0x05);	// Program page contents

			write_page(tempaddress,(1<<RWWSRE) + (1<<SPMEN));
											//Re-enable the RWW section
			if (address != (address & 0xFF80))
			{								// Ensure that the address points to the beginning of the next page
				address &= 0xFF80;
				address += PAGESIZE;
			}
		}									// End FLASH
		
		if (mem == 'E')						// Start EEPROM
        {
			address>>=1;
			do {
	 	        EEARL = address;			// Setup EEPROM address
	            EEARH = (address >> 8);
	            address++;					// Select next byte
	            EEDR = gBuffer[cnt++];			// Load data to write
	            EECR |= (1<<EEMWE);			// Write data into EEPROM
	            EECR |= (1<<EEWE);
	            while (EECR & (1<<EEWE))	// Wait for EEPROM write to finish
	              ;
				size--;						// Decreas number of bytes to write
			} while(size);					// Loop until all bytes written
		}
      	return '\r';						// Report programming OK
	}
	return 0;								// Report programming failed
}

void BlockRead(unsigned int size, unsigned char mem)
{
	unsigned int data;
	
	if (mem == 'E')							// Read EEPROM
	{
		do {
			EEARL = address;				// Setup EEPROM address
			EEARH = (address >> 8);
			address++;						// Select next EEPROM byte
			EECR |= (1<<EERE);				// Read EEPROM
			sendchar(EEDR);					// Transmit EEPROM data to PC
			size--;							// Decrease number of bytes to read
		} while (size);					// Repeat until all block has been read
	}
	else									// Read Flash
	{
		do {
			data = read_program_memory(address,0x00);
			sendchar((char)data);			//send LSB
			sendchar((char)(data >> 8));	//send MSB  
			address += 2;  					// Select next word in memory
			size -= 2;						// Subtract two bytes from number of bytes to read
		} while (size);					// Repeat until all block has been read
	}
}





/*****************************************************************************
*
*   Function name : OSCCAL_calibration
*
*   Returns :       None
*
*   Parameters :    None
*
*   Purpose :       Calibrate the internal OSCCAL byte, using the external 
*                   32,768 kHz crystal as reference
*
*****************************************************************************/
void OSCCAL_calibration(void)
{
    unsigned char calibrate = FALSE;
    int temp;
    unsigned char tempL;

    CLKPR = (1<<CLKPCE);        // set Clock Prescaler Change Enable
    // set prescaler = 8, Inter RC 8Mhz / 8 = 1Mhz
    CLKPR = (1<<CLKPS1) | (1<<CLKPS0);
    
    TIMSK2 = 0;             //disable OCIE2A and TOIE2

    ASSR = (1<<AS2);        //select asynchronous operation of timer2 (32,768kHz)
    
    OCR2A = 200;            // set timer2 compare value 

    TIMSK0 = 0;             // delete any interrupt sources
        
    TCCR1B = (1<<CS10);     // start timer1 with no prescaling
    TCCR2A = (1<<CS20);     // start timer2 with no prescaling

    while((ASSR & 0x01) | (ASSR & 0x04));       //wait for TCN2UB and TCR2UB to be cleared

    Delay(1000);    // wait for external crystal to stabilise
    
    while(!calibrate)
    {
        cli(); // mt __disable_interrupt();  // disable global interrupt
        
        TIFR1 = 0xFF;   // delete TIFR1 flags
        TIFR2 = 0xFF;   // delete TIFR2 flags
        
        TCNT1H = 0;     // clear timer1 counter
        TCNT1L = 0;
        TCNT2 = 0;      // clear timer2 counter
           
	while ( !(TIFR2 & (1<<OCF2A)) ); // while ( !(TIFR2 && (1<<OCF2A)) );   // wait for timer2 compareflag
    
        TCCR1B = 0; // stop timer1

        sei(); // __enable_interrupt();  // enable global interrupt
    
        if ( (TIFR1 & (1<<TOV1)) ) // if ( (TIFR1 && (1<<TOV1)) )
        {
            temp = 0xFFFF;      // if timer1 overflows, set the temp to 0xFFFF
        }
        else
        {   // read out the timer1 counter value
            tempL = TCNT1L;
            temp = TCNT1H;
            temp = (temp << 8);
            temp += tempL;
        }
    
        if (temp > 6250)
        {
            OSCCAL--;   // the internRC oscillator runs to fast, decrease the OSCCAL
        }
        else if (temp < 6120)
        {
            OSCCAL++;   // the internRC oscillator runs to slow, increase the OSCCAL
        }
        else
            calibrate = TRUE;   // the interRC is correct
    
        TCCR1B = (1<<CS10); // start timer1
    }
}


/*****************************************************************************
*
*   Function name : Delay
*
*   Returns :       None
*
*   Parameters :    unsigned int millisec
*
*   Purpose :       Delay-loop
*
*****************************************************************************/
void Delay(unsigned int millisec)
{
    unsigned char i; // mt int i;
    
    while (millisec--) {
        for (i=0; i<125; i++) {
			asm volatile (""::);
		}
	}
}

⌨️ 快捷键说明

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