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

📄 uart-spi-730.c

📁 通过io模拟spi对avr进行编程、 通过io模拟spi对avr进行编程 通过io模拟spi对avr进行编程
💻 C
📖 第 1 页 / 共 5 页
字号:
// IAR-AVR application builder : 2007-2-2 9:53:34
// Target : M32
// Crystal: 16.0000Mhz

//#include <iom32v.h>
//#include <macros.h>
#include <ioavr.h>
#include <iom32.h>
#include <inavr.h> 
#include <ina90.h>
#include <stdlib.h>
#include <string.h>
#include "def.h"
char temp;
char datacache[128]; 

void port_init(void)
{
 PORTA = 0x00;
 DDRA  = 0xD0;
 PORTB = 0x10;
 DDRB  = 0xB1;
 PORTC = 0x00; 
 DDRC  = 0x00;
 PORTD = 0x00;
 DDRD  = 0xBE;
}

//UART0 initialize
// desired baud rate: 9600
// actual: baud rate:9615 (0.2%)
// char size: 8 bit
// parity: Disabled
void uart0_init(void)
{
 _CLI();
 UCSRB = 0x00; //disable while setting baud rate
 UCSRA = 0x00;
 UCSRC = BIT(7) | 0x06;
 UBRRL = 0x67; //set baud rate lo
 UBRRH = 0x00; //set baud rate hi
 UCSRB = 0x18;
 _SEI();
}

// ~~~~~~~~~~~~~~~~~~~~~~~ SPI初始化函数 ~~~~~~~~~~~~~~~~~~~~~~//
//SPI initialize  SPI模式0
// clock rate: 4,000,000hz
//传一个字节需要0.25*8=2us
void SPI_init(void)
    {
     SPCR = 0x5D; //setup SPI   Fosc/4
     SPSR = 0x00; //setup SPI
    }

//  ~~~~~~~~~~~~~~~~~~~~~~ 读SPI函数~~~~~~~~~~~~~~~~~~~~~~~~~~~~//

uchar read_SPI(void)
    {    
	 SPDR = 0x00;
 	 while (!(SPSR&0x80));  //检查SPI中断标志
   	 return SPDR;           //返回SPI数据寄存器值
    }


//  ~~~~~~~~~~~~~~~~~~~~~~ 写SPI函数~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
void write_SPI(uchar data)
    {
     SPDR=data;             //将数据写入SPI数据寄存器
     while(!(SPSR&0x80));   //检查SPI中断标志
    }
	

//~~~~~~~~~~~~~~~~~~~~~~~~~片解除保护~~~~~~~~~~~~~~~~~~~~~~~~~~~//
void chip_unlock(void)
    {
      write_SPI(0x3d); 
      write_SPI(0x2a);
      write_SPI(0x7f); 
      write_SPI(0x9a);
    }


// ~~~~~~~~~~~~~~~~~~~~~~~~~~片擦除~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
void chip_erase(void)
    {
      write_SPI(0xc7); 
      write_SPI(0x94);
      write_SPI(0x80); 
      write_SPI(0x9a);
    }
	
//~~~~~~~~~~~~~~~~~~~~~~~~~UART读取函数~~~~~~~~~~~~~~~~~~~~~~//
uchar read_UART(void)
     {
	  while(!(UCSRA&BIT(7))); //检测是否完成接收
	  return UDR;             //返回UART数据寄存器值
     }

// ~~~~~~~~~~~~~~~~~~~~ADC1初始化函数~~~~~~~~~~~~~~~~~~~~~//
//选择AVCC做参考电压,转换左对齐 选中通道1即键盘通道 adc使能 
//ADC initialize
// Conversion time: 104uS
void ADC1_init(void)
    {
     ADCSRA = 0x00;  //disable adc
     ADMUX  = 0xE1;  //2.56V片内基准电压源, 左对齐, ADC1
     ACSR   = 0x80;
     ADCSRA = 0xE7;  //128分频
    }

// ~~~~~~~~~~~~~~~ 定时器0初始化~~~~~~~~~~~~~~~~~~~~~~~//
// 10ms定时中断
//TIMER0 initialize - prescale:1024
// desired value: 10mSec
// actual value:  9.984mSec (0.2%)

void timer0_init(void)
    {
     TCCR0 = 0x00;   //stop
     TCNT0 = 0x64;   //set count
     OCR0  = 0x9C;   //set compare
     TCCR0 = 0x05;   //start timer, 1024预分频 
    }
	
	
//~~~~~~~~~~~~~~~~定时器0中断采样键盘函数~~~~~~~~~~~~~~~~//

#pragma vector = TIMER0_OVF_vect
__interrupt void timer0_ovf_isr(void)

    {
     TCNT0 = 0x64; //reload counter value
     temp1 = ADCH;
    }


//~~~~~~~~~~~~~~~~~~~~~~~~~延时ms(不精确)~~~~~~~~~~~~~~~~~~~~~~~~//
void delay1(int time1)
	 {   
		 for (i=time1;i>0;i--)
	 	 	 {	  
			  j= 16000;
			  for (j=16000;j>0;j--)
			      {;}
			 }
	 }

//~~~~~~~~~~~~~~~~~~~~~~~~~延时 (time) us~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
//TIMER2 initialize - prescale:1
// desired value: 1000000Hz
// actual value: 1000000.000Hz (0.0%)
void timer2_init(void)
    {
     TCCR2 = 0x00; //stop
     ASSR  = 0x00; //set async mode
     TCNT2 = 0xF0; //setup
     OCR2  = 0x10;
    }

//~~~~~~~~~~~~~~~~~~~~~定时/计数器2中断函数(延时)~~~~~~~~~~~~~~~~~~~//

#pragma vector = TIMER2_OVF_vect
__interrupt void timer2_ovf_isr(void)

    {
     TCNT2 = 0xF0; //reload counter value
     m++;
    }



//~~~~~~~~~~~~~~~~~~~~~~~~~延时函数us(精确)~~~~~~~~~~~~~~~~~~~~~~~~~~//
void delay(uint time)
    {
	 m=0;
	 TCCR2 = 0x01; //start
	 while(m<time);
	 TCCR2 = 0x00; //stop
    }

//~~~~~~~~~~~~~~~~~~~~~~~~~I/O模拟SPI~~~~~~~~~~~~~~~~~~~~~~~~~~//

void IO_SPI(void)
{
  for(bs=8;bs!=0;bs--)
      {
	if(as&0x80){STA_SDI_HIG;}
        else       {STA_SDI_LOW;}
        STA_SCL_LOW;
	STA_SCL_HIG;
	as<<=1;
       }
  as=0;
}

void IO_SPI_RESP(void)
{
  for(bs=8;bs!=0;bs--)
      {
	if(as&0x80){STA_SDI_HIG;}
        else       {STA_SDI_LOW;}
        STA_SCL_LOW;
	STA_SCL_HIG;
	as<<=1;
        if(PINA&BIT(5)){cs |= BIT(bs-1);}
       }
  as=0;
}

void IO_SPI_READSP(void)
{
  for(bs=8;bs!=0;bs--)
      {
	if(as&0x80){STA_SDI_HIG;}
        else       {STA_SDI_LOW;}        
        STA_SCL_LOW;    
        STA_SCL_HIG;
        //_NOP();
        //STA_SCL_HIG;
        //STA_SCL_LOW;
        as<<=1;
        if(PINA&BIT(5)){rs |= BIT(bs-1);}
        //STA_SCL_LOW;
	//STA_SCL_HIG;        
	//STA_SCL_LOW;                
       }
  as=0;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~ASCII~~~~~~~~~~~~~~~~~~~~~~~~~~//

void ascii(void)
{
  if ( ((ds>=0x41)&&(ds<=0x46)) )
     {
       ds=ds-0x07;
     }
}

//~~~~~~~~~~~~~~~~~~~~~~~~~往主芯片EEPROM中写入状态信息~~~~~~~~~~~~~~~~~~~~~~~~~~//

void EEPROM_write(uint uiAddress, uchar ucData)
{
/* 等待上一次写操作结束 
while(EECR & (1<<EEWE));*/

/* 设置地址和数据寄存器*/
EEAR = uiAddress;
EEDR = ucData;
/* 置位EEMWE */
EECR |= 0x04;
/* 置位EEWE 以启动写操作*/
EECR |= 0x02;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~往主芯片EEPROM中读取状态信息~~~~~~~~~~~~~~~~~~~~~~~~~~//

unsigned char EEPROM_read(unsigned int uiAddress)
{
/* 等待上一次写操作结束 
while(EECR & (1<<EEWE));*/

/* 设置地址寄存器*/
EEAR = uiAddress;
/* 设置EERE 以启动读操作*/
EECR |= 0x01;
/* 自数据寄存器返回数据 */
return EEDR;
}


void ReadFromChip(void)
{  
  
  for (i=0;i<64;i++)
  {
    
            as=0x20;
            write_SPI(as);
            as=tempadh;
            write_SPI(as);
            as=tempadl;
            write_SPI(as);
            as=0x00;
            rs=read_SPI();
            ws[z]=rs;
            z++;
            /*
            as=0x4C;
            IO_SPI();
            as=adh;
            IO_SPI();
            as=adl;
            IO_SPI();
            as=0x00;
            IO_SPI();
            */
            y=1;            
  
            as=0x28;
            write_SPI(as);
            as=tempadh;
            write_SPI(as);
            as=tempadl;
            write_SPI(as);
            as=0x00;
            rs=read_SPI();
            ws[z]=rs;
            z++;
            /*
            as=0x4C;
            IO_SPI();
            as=adh;
            IO_SPI();
            as=adl;
            IO_SPI();
            as=0x00;
            IO_SPI();
            */
          
            
                 tempadl++;
            
         
  }
  /*if (rs==0xFF)
  {_NOP();}
  else
  {_NOP();}*/
}




//~~~~~~~~~~~~~~~~开始编程Flash页~~~~~~~~~~~~~~~~//

void ProgrammingFlash(void)
{  
  PORTB |= 0x10;   //PB4(DF_CS)=1
  
  chip_1_page=page;
  //chip_1_number=number;
  
  z=0;
  
  while(Syn==0)   //激活SPI编程状态并判断时钟是否同步
                {
                  
                  SPCR = 0x00;
                  STA_SCL_LOW;  //激活SPI编程状态
                  STA_RESET_HIG;                  
                  _NOP();
                  _NOP();
                  //_NOP();
                  STA_RESET_LOW;                   
                  //delay1(20);
                  SPCR = 0x5D;
                  
                  
                  as=0xAC;  //判断时钟是否同步
                  write_SPI(as);
                  as=0x53;
                  write_SPI(as);
                  as=0x00;
                  cs=read_SPI();
                  as=0x00;
                  write_SPI(as);  
                  if(cs==0x53){Syn=1;}  //反馈正确则标志时钟同步成功                  
                }
  
  cs=0x00;
  Syn=0;
  
  
  
  
  for (i=0;i<64;i++)
  {
            as=0x40;
            write_SPI(as);
            as=tempadh&&0x3F;
            write_SPI(as);
            as=tempadl;
            write_SPI(as);
            as=datacache[z];
            //as=0x0F;
            write_SPI(as);
            z++;
            
        
            as=0x48;
            write_SPI(as);
            as=tempadh&&0x3F;
            write_SPI(as);
            as=tempadl;
            write_SPI(as);
            as=datacache[z];
            //as=0x0F;
            write_SPI(as);
            z++;
            
            tempadl++;
            
  }
  
  as=0x4C;
  write_SPI(as);
  as=adh&&0x3F;
  write_SPI(as);
  as=adl; 
  write_SPI(as);
  as=0x00;
  write_SPI(as);
  delay(5000);
    
  tempadh=adh;
  tempadl=adl;  
  
  z=0;
  /*tempadl=tempadl-0x3F;
  ReadFromChip();  
  
  tempadl=adl;*/
  
  if (tempadl==0xFF)
  {
    tempadh++;
    tempadl=0x00;
  }
  else
  {
    tempadl++;
  }
  
  STA_RESET_HIG;
  z=0;
  PORTB &= ~0x10;//PB4(DF_CS)=0
  
  page=chip_1_page;
  number=chip_1_number;
  
  if (chip_1_number<256)
  {
      chip_1_page = chip_1_page-2;
      write_SPI(MM_PAGE_TO_B1_XFER);//将第一页装入buffer1
      write_SPI((uchar)(chip_1_page>>7));
      write_SPI((uchar)(chip_1_page<<1));
      write_SPI(0x00);
      
      PORTB |= 0x10;//PB4(DF_CS)=1
      chip_1_page++;
      delay(10);
      PORTB &= ~0x10;//PB4(DF_CS)=0
      
      write_SPI(MM_PAGE_TO_B2_XFER);//将第二页装入buffer2
      write_SPI((uchar)(chip_1_page>>7));
      write_SPI((uchar)(chip_1_page<<1));
      write_SPI(0x00);
      
      PORTB |= 0x10;//PB4(DF_CS)=1
      chip_1_page++;
      delay(10);
      PORTB &= ~0x10;//PB4(DF_CS)=0
      
      write_SPI(BUFFER_1_READ);//准备好从buffer1读取数据
      write_SPI(0x00);
      write_SPI(0x00);
      write_SPI( (char)(number) );
  }
  else if (chip_1_number==256)
  {
      chip_1_page = chip_1_page-2;
      write_SPI(MM_PAGE_TO_B2_XFER);//将第二页装入buffer2
      write_SPI((uchar)(chip_1_page>>7));
      write_SPI((uchar)(chip_1_page<<1));
      write_SPI(0x00);
      
      PORTB |= 0x10;//PB4(DF_CS)=1

⌨️ 快捷键说明

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