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

📄 arm5.0.c

📁 基于AVR单片机的ARM编程器设计 目标芯片:AT91SAM7S64
💻 C
📖 第 1 页 / 共 2 页
字号:


  //至此,ARM芯片进入串行编程模式  


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~arm写准备及地址程序~~~~~~~~~~~~~~~~~~~~~~//    
void arm_write_RDY(unsigned long data_write_add)
{
  unsigned char i;
  PORTB|=0x10;
  
  write_handshake();
  
  mode_0();   //进入 Run-test/idle
  mode_1();   //进入Select-DR-scan
  mode_0();  //进入Capture-DR
  mode_0();  //进入Shift-DR
  
  sent_0();  //向DR输入0
  sent_1();   //向DR输入1
  sent_0();  //向DR输入0
  sent_0();  //向DR输入0   0x2
  
  sent_1();  //向DR输入1
  sent_1();  //向DR输入1
  sent_0();  //向DR输入0
  sent_0();  //向DR输入0   0x3  0x32
  
  for(i=0;i<8;i++)
  {
    sent_0();  //向DR输入0
  }               //向DR输入8个0, 0x0032(EWP)
  
  
  sent_0();  //向DR输入
  sent_0();  //向DR输入0
  sent_0();   //向DR输入0
  sent_0();  //向DR输入0   
  
  sent_0();
  sent_1();
  sent_0();
  sent_0();    //0x20  每次写入32个字,即一页
  
  for(i=0;i<8;i++)
  {
    sent_0();  //向DR输入0
  }                //向DR输入12个0, 0x000
  
  
  DR_write();
  //以上为输入写页命令程序
  
  write_handshake();
  
  mode_1();   //进入Select-DR-scan
  mode_0();  //进入Capture-DR
  mode_0();  //进入Shift-DR
  
  for(i=0;i<32;i++)
  {
    PORTB=((data_write_add>>i&1)<<2|0xFB)&(PORTB|0x04);
    PORTB|=0x01;   
    delay(1);
    PORTB&=~0x01;   // 提供一个TCK时钟
  }
  
  DR_write();    
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~arm芯片写程序~~~~~~~~~~~~~~~~~~~~~~//
void arm_write(unsigned long data_write)
{
  unsigned int i;
  
  write_handshake();
  
  PORTA|=0x80;              //点亮ARM写LED
  mode_0();  //进入 Run-test/idle
  mode_1();   //进入Select-DR-scan
  mode_0();  //进入Capture-DR
  mode_0();  //进入Shift-DR
  for(i=0;i<32;i++)
  {
    PORTB=((data_write>>i&1)<<2|0xFB)&(PORTB|0x04);
    PORTB|=0x01;   
    delay(1);
    PORTB&=~0x01;    // 提供一个TCK时钟
  }
  
  DR_write();
  PORTA&=~0x80;              //关闭ARM写LED
  
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~arm读页准备及地址程序~~~~~~~~~~~~~~~~~~~~~//    
void arm_read_RDY(unsigned long data_read_add)
{
  unsigned char i;
  PORTB|=0x10;
  
  write_handshake();
  
  
  mode_1();   //进入Select-DR-scan
  mode_0();  //进入Capture-DR
  mode_0();  //进入Shift-DR
  
  sent_1();  //向DR输入1
  sent_0();  //向DR输入0
  sent_0();  //向DR输入0
  sent_0();  //向DR输入0   0x1
  
  sent_1();  //向DR输入1
  sent_0();  //向DR输入0
  sent_0();  //向DR输入0
  sent_0();  //向DR输入0   0x1    0x11
  
  for(i=0;i<8;i++)
  {
    sent_0();  //向DR输入0
  }               //向DR输入8个0, 0x0011(READ)
  
  
  sent_0();  //向DR输入1
  sent_0();  //向DR输入0
  sent_0();  //向DR输入0
  sent_0();  //向DR输入0   0x1  0x01(写字数)每次写入两个字,即32位数据
  
   sent_0();
   sent_1();
   sent_0();
   sent_0();
  
  for(i=0;i<8;i++)
  {
    sent_0();  //向DR输入0
  }                //向DR输入12个0, 0x000
  
  DR_write();
 
  //以上为输入读命令程序
  
  write_handshake();
  
  mode_1();   //进入Select-DR-scan
  mode_0();  //进入Capture-DR
  mode_0();  //进入Shift-DR
  
  for(i=0;i<32;i++)
  {
    PORTB=((data_read_add>>i&1)<<2|0xFB)&(PORTB|0x04);
    PORTB|=0x01;   
    delay(1);
    PORTB&=~0x01;    // 提供一个TCK时钟
   
  }
  
  DR_write();
  
}


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~arm读程序~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
void arm_read(void)
{
  data_read=0x00000000;
  unsigned char i;
  
  read_handshake();
    
  mode_0();  //进入 Run-test/idle
  mode_1();   //进入Select-DR-scan
  mode_0();  //进入Capture-DR
  mode_0();  //进入Shift-DR
  
  for(i=0;i<32;i++)
  {
    sent_0();  //向DR输入0
    data_read=((PINB&0x02)>>1)<<i|data_read;
  }
  
  DR_read();
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~数据传输函数~~~~~~~~~~~~~~~~~~~~~~//      
void copy(void)
{
  //number_error=0;
  arm_write_add=0x00100000;
  unsigned int page_arm=0;
  unsigned int number_arm=0;
  unsigned int page=0;
 
  unsigned int number=0;
  unsigned char temp00;
  unsigned char temp01;
  unsigned char temp02;
  unsigned char temp03;
  unsigned long temp;
  
  
    PORTB|=0x10;               //PB4=1
    delay(1);
    PORTB &= ~0x10;            //PB4(DF_CS)=0;
    write_SPI(0x53);           //将第一页装入buffer1
    write_SPI((uchar)(page>>7));
    write_SPI((uchar)(page<<1));
    write_SPI(0x00);
    
    PORTB |= 0x10;            //PB4(DF_CS)=1
    page++;
    //delay(1000);
    PORTB &= ~0x10;           //PB4(DF_CS)=0
    
    write_SPI(0xD1);       //开始读取BUFFER1
    write_SPI(0x00);
    write_SPI(0x00);
    write_SPI(0x00);
    write_SPI(0x00);
    
    arm_write_RDY(arm_write_add);
    

    
 while(page_arm<512)         //如果ARM没有写满
  {
    
    

    temp00=read_SPI();  //读取flash
    number++;
    temp01=read_SPI();
    number++;
    temp02=read_SPI();
    number++;
    temp03=read_SPI();
    number++;
    PORTB |= 0x10;            //PB4(DF_CS)=1
     
    temp=(((temp03<<8)|temp02)<<8|temp01)<<8|temp00;
    
    
     
    
    arm_write(temp);
    
    number_arm++;
    //arm_write_add++;
     
    if(number_arm==32)    //写满一页
    {
      delay(2000);        //2ms 用于页存储
      page_arm++;
      number_arm=0;
      arm_write_add=arm_write_add+124;
      arm_write_RDY(arm_write_add);
        
    }
     
		
	if (number == 264)//buffer1读取完毕,主存转入buffer1,开始读取buffer2
            {
                  PORTB |= 0x10;  //PB4(DF_CS)=1
                  delay(1);
	          PORTB &= ~0x10; //PB4(DF_CS)=0
	
			  write_SPI(0x53);//主存转入buffer1
	          write_SPI((uchar)(page>>7));
	          write_SPI((uchar)(page<<1));
	          write_SPI(0x00);
	
			  PORTB |= 0x10;  //PB4(DF_CS)=1
	          page++;
	          PORTB &= ~0x10; //PB4(DF_CS)=0
	
			  write_SPI(0xD3);     //开始读取buffer2
	          write_SPI(0x00);
	          write_SPI(0x00);
	          write_SPI(0x00);
			  write_SPI(0x00);

             }

	 if (number == 528)           //buffer2读取完毕,主存转入buffer2,开始读取buffer1
	         {
		  PORTB |= 0x10;      //PB4(DF_CS)=1
	          number = 0;
	          PORTB &= ~0x10;            //PB4(DF_CS)=0
	
		  write_SPI(0x55);          //主存转入buffer2
	          write_SPI((uchar)(page>>7));
	          write_SPI((uchar)(page<<1));
	          write_SPI(0x00);
                  
                  write_SPI(0xD1);       //开始读取BUFFER1
                  write_SPI(0x00);
                  write_SPI(0x00);
                  write_SPI(0x00);
                  write_SPI(0x00);
	

             }
  }
 if(page_arm==512)          //如果arm写满
 {
     PORTB |= 0x10;    //PB4(DF_CS)=1
     PORTA|=0xF8;       //关闭指示校验的LED  
     delay(50000);
     PORTA&=~0xF8;
 }
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~校验程序~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
void validation(void)
{
  number_error=0;
  unsigned long arm_read_add=0x00100000;
  unsigned int page_arm=0;
  unsigned int number_arm=0;
  unsigned int page=0;
 
  unsigned int number=0;
  unsigned char temp00;
  unsigned char temp01;
  unsigned char temp02;
  unsigned char temp03;
  unsigned long temp;
  
  
  PORTB|=0x10;               //PB4=1
  delay(1);
  PORTB &= ~0x10;            //PB4(DF_CS)=0;
  write_SPI(0x53);           //将第一页装入buffer1
  write_SPI((uchar)(page>>7));
  write_SPI((uchar)(page<<1));
  write_SPI(0x00);
  
  PORTB |= 0x10;            //PB4(DF_CS)=1
    page++;
    //delay(1000);
    PORTB &= ~0x10;           //PB4(DF_CS)=0
    
    write_SPI(0xD1);       //开始读取BUFFER1
    write_SPI(0x00);
    write_SPI(0x00);
    write_SPI(0x00);
    write_SPI(0x00);
    
  PORTA|=0x40;        //点亮指示校验的LED
  
  arm_read_RDY(arm_read_add);
  
  while(page_arm<512)         //如果ARM没有写满
  {

    temp00=read_SPI();  //读取flash
    number++;
    temp01=read_SPI();
    number++;
    temp02=read_SPI();
    number++;
    temp03=read_SPI();
    number++;
    PORTB |= 0x10;            //PB4(DF_CS)=1
     
    temp=(((temp03<<8)|temp02)<<8|temp01)<<8|temp00;
    //temp=0xFFFF8787;
    
    arm_read();
    //number_arm++;
    
    if(temp==data_read)
    {
       number_arm++;
       //arm_read_add++;
    }
    else if(temp!=data_read)
    {
      PORTA|=0x20;        //点亮指示有错误的LED
      number_arm++;
      number_error++;     // 标记错误信息
    }

      /*arm_write_RDY(arm_read_add);
      arm_write(temp);
      if(temp==data_read)
       {
         //PORTA&=~0x80;        //关闭指示校验LED
         
         number_arm++;
         arm_read_add++;
       } 
      else if(temp!=data_read)
      {
        PORTA|=0x20;        //点亮指示有错误的LED
        number_arm++;
        arm_read_add++;
        number_error++;     // 标记错误信息
        
      }
    }*/
     if(number_arm==32)    //校验完一页
    {
      delay(2000);        //2ms 用于页存储
      page_arm++;
      number_arm=0;
      arm_read_add=arm_read_add+124;
      arm_read_RDY(arm_read_add);
    }
   
    if (number == 264)//buffer1读取完毕,主存转入buffer1,开始读取buffer2
            {
                  PORTB |= 0x10;  //PB4(DF_CS)=1
                  delay(1);
	          PORTB &= ~0x10; //PB4(DF_CS)=0
	
			  write_SPI(0x53);//主存转入buffer1
	          write_SPI((uchar)(page>>7));
	          write_SPI((uchar)(page<<1));
	          write_SPI(0x00);
	
			  PORTB |= 0x10;  //PB4(DF_CS)=1
	          page++;
	          PORTB &= ~0x10; //PB4(DF_CS)=0
	
			  write_SPI(0xD3);     //开始读取buffer2
	          write_SPI(0x00);
	          write_SPI(0x00);
	          write_SPI(0x00);
			  write_SPI(0x00);

             }

	 if (number == 528)           //buffer2读取完毕,主存转入buffer2,开始读取buffer1
	         {
		  PORTB |= 0x10;      //PB4(DF_CS)=1
	          number = 0;
	          PORTB &= ~0x10;            //PB4(DF_CS)=0
	
		  write_SPI(0x55);          //主存转入buffer2
	          write_SPI((uchar)(page>>7));
	          write_SPI((uchar)(page<<1));
	          write_SPI(0x00);
                  
                  write_SPI(0xD1);       //开始读取BUFFER1
                  write_SPI(0x00);
                  write_SPI(0x00);
                  write_SPI(0x00);
                  write_SPI(0x00);
	

             }
  }
 if(page_arm==512)          //如果校验完毕
 {
     PORTB |= 0x10;      //PB4(DF_CS)=1
     PORTA|=0xF8;       //关闭指示校验的LED  
     delay(50000);
     PORTA&=~0xF8;
     if(number_error>100)
     {
       PORTA|=0x08;    //点亮指示错误点超过10000的LED
     }
 }
}
  


// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ main函数  ~~~~~~~~~~~~~~~~~~~~~~~~~//
void main(void)
{
  init_devices(); //设备初始化
  PORTB|=0x10;    //  PB4=1
  arm_init();
  while(1)
  {
    
    if (temp1 >=121&&temp1<143)		        //6 erase键按下
     {
       delay(50000);  //按键50ms表示删除flash
       if (temp1 >=121&&temp1<143)		//6 erase键按下
       {
         TCCR0 =0x00;    //关闭定时/计数器0
         chip_erase();
         delay(2000);
         TCCR0 = 0x05;   //启动定时/计数器0
         PORTA&=0x07;
       }
     }
    
    
    if (temp1 >=250)		//ss键按下
    {
      delay(50000);  //按键50ms表示编程
      if (temp1 >=250)		//ss键按下
      {
       TCCR0 =0x00;    //关闭定时/计数器0
       copy();
       validation();
       PORTB |= 0x10;   //PB4(DF_CS)=1
       ADC1_init();     //启动ADC1转换
       TCCR0 = 0x05;    //启动定时/计数器0
       
       
       delay(50000);    //等待系统复位
       PORTA|=0x10;
       
       
       }
    }
  }
}

⌨️ 快捷键说明

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