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

📄 arm5.0.c

📁 基于AVR单片机的ARM编程器设计 目标芯片:AT91SAM7S64
💻 C
📖 第 1 页 / 共 2 页
字号:
//IAR-AVR application builder
// Target : M32
// Crystal: 16.000Mhz

#include <avr_macros.h>
#include <ioavr.h>
#include <ina90.h>
#include <iom32.h>

#define uchar unsigned char
#define uint unsigned int

unsigned long arm_write_add;
unsigned long number_error;
unsigned long data_read;
unsigned char temp1;
unsigned int m;
unsigned char flag;
unsigned char CNT;
unsigned char second;
unsigned int W;
unsigned int R;

//~~~~~~~~~~~~~~~~~~~~~~端口初始化函数~~~~~~~~~~~~~~~~~~~~~~~//
void port_init(void)
    {
     PORTA = 0x00;
     DDRA  = 0xF8;
     PORTB = 0x10;
     DDRB  = 0xFD;
     PORTC = 0x00;
     DDRC  = 0xC0;
     PORTD = 0x00;
     DDRD  = 0x03;
    }



//~~~~~~~~~~~~~~~~~~~~~~~ SPI初始化函数 ~~~~~~~~~~~~~~~~~~~~~~//
//SPI initialize  SPI模式0
// clock rate: 4,000,000hz
//传一个字节需要0.25*8=2us
void SPI_init(void)
    {
     SPCR = 0x5C; //setup SPI   Fosc/4  SPI使能,主模式,时钟极性,时钟相位,4分频  高位先发送
     SPSR = 0x00; //setup SPI   
    }


// ~~~~~~~~~~~~~~~ 定时器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预分频
    }

// ~~~~~~~~~~~~~~~~~~~~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 = 0x87;  //128分频
    }

// ~~~~~~~~~~~~~~~~~~~~~ AD读取函数~~~~~~~~~~~~~~~~~~~~~~//
char AD_Receive( void )
{
   while ( (ADCSRA & 0x40) );
   return ADCH;
}

//~~~~~~~~~~~~~~~~~~~~~ 读SPI函数~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
uchar read_SPI(void)
    {
         
	 SPDR = 0x00;
 	 while (!(SPSR&0x80));  //检查SPI中断标志,串行发送结束后,SPIF置位,判断是否发送结束
   	 return SPDR;           //返回SPI数据寄存器值
  
    }

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


//~~~~~~~~~定时器0中断采样键盘函数~~~~~~~~//
//#pragma interrupt_handler timer0_ovf_isr:12
#pragma vector = TIMER0_OVF_vect
__interrupt void timer0_ovf_isr(void)
{
 	TCNT0 = 0x64; //reload counter value
 	ADCSRA |= 0x40;
 	temp1 = AD_Receive();
}
	


//~~~~~~~~~~~~~~~~~~~~~~~~~定时器2初始化~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
//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;     //更新计数寄存器值
  m++;
}

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


//~~~~~~~~~~~~~~~~~~~~~~设备初始化~~~~~~~~~~~~~~~~~~~~~~~~//
void init_devices(void)
    {
 	 //stop errant interrupts until set up
 	 asm("cli");            //关闭所有中断
 	 port_init();           //端口初始化
         
         
         
	 timer0_init();    //定时/计数器0初始化(键盘采样)
         //timer1_init();    //定时/计数器1初始化
	 timer2_init();    //定时/计数器2初始化(延时)
         ADC1_init();      //模数转换初始化(键盘读取)
	 
         SPI_init();       //SPI初始化
         
	
	 MCUCR = 0x00;
 	 GICR  = 0x00;
 	 TIMSK = 0x55;     //timer interrupt sources
 	 asm("sei");        //使能中断
	 //all peripherals are now initialized
    }

//~~~~~~~~~~~~~~~~~~~~~~~~ARM输入1单元程序~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
void sent_1(void)
{
  PORTB|=0x04;     //PB2=1
  PORTB|=0x01;   
  delay(1);
  PORTB&=~0x01;    // 提供一个TCK时钟
}

//~~~~~~~~~~~~~~~~~~~~~~~~ARM输入0单元程序~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
void sent_0(void)
{
  PORTB&=~0x04;    //PB2=0
  PORTB|=0x01;   
  delay(1);
  PORTB&=~0x01;    // 提供一个TCK时钟
} 

//~~~~~~~~~~~~~~~~~~~~ARM模式选择输入1单元程序~~~~~~~~~~~~~~~~~~~~~~~~~//
void mode_1(void)
{
  PORTB|=0x08;     //PB3=1
  PORTB|=0x01;   
  delay(1);
  PORTB&=~0x01;    // 提供一个TCK时钟
} 


//~~~~~~~~~~~~~~~~~~~~ARM模式选择输入0单元程序~~~~~~~~~~~~~~~~~~~~~~~~~//
void mode_0(void)
{
  PORTB&=~0x08;     //PB3=0
  PORTB|=0x01;   
  delay(1);
  PORTB&=~0x01;    // 提供一个TCK时钟
} 

//~~~~~~~~~~~~~~~~~~~DR数据读程序~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
void DR_read()
{
  sent_1();  //向DR输入1
  sent_0();  //向DR输入0
  sent_1();  //向DR输入1
  sent_0();  //向DR输入0
  sent_0();  //向DR输入0   向DR输入5位地址  0x05
  
  sent_0();  //向DR输入0    向DR读写位写入0,表示读
  
  mode_1();   //进入Exit1-DR
  mode_1();   //进入Updata-DR
  mode_0();  //进入 Run-test/idle
}

//~~~~~~~~~~~~~~~~~~~DR数据写程序~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
void DR_write()
{
  sent_1();  //向DR输入1
  sent_0();  //向DR输入0
  sent_1();  //向DR输入1
  sent_0();  //向DR输入0
  sent_0();  //向DR输入0   向DR输入5位地址  0x05
  
  sent_1();  //向DR输入1    向DR读写位写入1,表示写
  
  mode_1();   //进入Exit1-DR
  mode_1();   //进入Updata-DR
  mode_0();  //进入 Run-test/idle
}

//~~~~~~~~~~~~~~~~~~~~~~~ARM读握手程序~~~~~~~~~~~~~~~~~~~~~~~~~~~//
void read_handshake(void)
{
  W=0;
  while(W==0)
  {
    
    mode_1();   //进入Select-DR-scan
    mode_0();  //进入Capture-DR
    mode_0();  //进入Shift-DR
  
    sent_0();  //向DR输入0
    sent_0();  //向DR输入0
    sent_1();  //向DR输入1
    sent_0();  //向DR输入0
    sent_0();  //向DR输入0      0x04   DCCR地址
  
    sent_0();  //向DR输入0       表示读
  
    mode_1();   //进入Exit1-DR
    mode_1();   //进入Updata-DR
    mode_0();  //进入 Run-test/idle
  
  
    mode_1();   //进入Select-DR-scan
    mode_0();  //进入Capture-DR
    mode_0();  //进入Shift-DR
  
    sent_0();  //向DR输入0
    sent_0();  //向DR输入0
  
    W=(PINB&0x02)>>1;
    //data_read=((PINB&0x02)>>1)<<i|data_read;
    mode_1();   //进入Exit1-DR
    mode_1();   //进入Updata-DR
    mode_0();  //进入 Run-test/idle
  }
}

//~~~~~~~~~~~~~~~~~~~~~~~ARM写握手程序~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
void write_handshake(void)
{
  R=1;
  while(R==1)
  { 
    mode_1();   //进入Select-DR-scan
    mode_0();  //进入Capture-DR
    mode_0();  //进入Shift-DR
  
    sent_0();  //向DR输入0
    sent_0();  //向DR输入0
    sent_1();  //向DR输入1
    sent_0();  //向DR输入0
    sent_0();  //向DR输入0       DCCR地址
  
    sent_0();  //向DR输入0       表示读
  
    mode_1();   //进入Exit1-DR
    mode_1();   //进入Updata-DR
    mode_0();  //进入 Run-test/idle
  
  
    mode_1();   //进入Select-DR-scan
    mode_0();  //进入Capture-DR
    mode_0();  //进入Shift-DR
  
    sent_0();  //向DR输入0
    //sent_0();  //向DR输入0
  
    R=(PINB&0x02)>>1;
    //data_read=((PINB&0x02)>>1)<<i|data_read;
    mode_1();   //进入Exit1-DR
    mode_1();   //进入Updata-DR
    mode_0();  //进入 Run-test/idle
  }
}
  




//~~~~~~~~~~~~~~~~~~~~~芯片解保护及擦除~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//   
void chip_erase(void)
{
  //unsigned long data1=0x00000000;
  //unsigned long data2=0;
  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_1();   //向DR输入1
  sent_0();  //向DR输入0
  sent_1();   //向DR输入1
  sent_0();  //向DR输入0   0x5
  
  sent_1();   //向DR输入1
  sent_0();  //向DR输入0
  sent_0();  //向DR输入0
  sent_0();  //向DR输入0   ox1   0x0015(GLB)
  
  for(i=0;i<24;i++)
  {
    sent_0();  //向DR输入0
  }            //向DR连续输入24个0   0x00 00 00
  
  DR_write();
  // 以上为输入GLB命令程序
  
  PORTA|=0x80;
  delay(50000);
  
  read_handshake();
  
  mode_1();   //进入Select-DR-scan
  mode_0();  //进入Capture-DR
  mode_0();  //进入Shift-DR
  
  for(i=0;i<32;i++)
  {
    sent_0();    //向DR输入0
    
    data1=((PINB&0x02)>>1)<<i|data1;
    //data_read=((PINB&0x02)>>1)<<i|data_read;
    
  }
  DR_read();
  
  
  //以上程序为读出锁定位
  PORTA|=0x40;
  delay(50000);
  
  write_handshake();
  
  mode_1();   //进入Select-DR-scan
  mode_0();  //进入Capture-DR
  mode_0();  //进入Shift-DR
  
  sent_0();  //向DR输入0
  sent_0();  //向DR输入0
  sent_1();  //向DR输入1
  sent_0();  //向DR输入0   0x4
  
  sent_0();  //向DR输入0
  sent_1();  //向DR输入1
  sent_0();  //向DR输入0
  sent_0();  //向DR输入0  0x2  0x24(CLB)
  
  for(i=0;i<24;i++)
  {
    sent_0();  //向DR输入0
  }                //向DR输入24个0   0x00 00 00
  
  DR_write();
  //以上为写入CLB命令程序
  
  PORTA|=0x20;
  delay(50000);
  
  write_handshake();
  
  mode_1();   //进入Select-DR-scan
  mode_0();  //进入Capture-DR
  mode_0();  //进入Shift-DR
  
  for(i=0;i<32;i++)
  {
   
    PORTB=((data1>>i&1)<<2|0xFB)&(PORTB|0x04);
    PORTB|=0x01;   
    delay(1);
    PORTB&=~0x01;    // 提供一个TCK时钟
    
  }
  
  DR_write();
  //以上是解除锁定位程序
  
  PORTA|=0x10;
  delay(50000);
  */
  write_handshake();
  
  mode_1();   //进入Select-DR-scan
  mode_0();  //进入Capture-DR
  mode_0();  //进入Shift-DR
  
  sent_1();  //向DR输入1
  sent_1();  //向DR输入1
  sent_0();  //向DR输入0
  sent_0();  //向DR输入0   0x3
  
  sent_1();  //向DR输入1
  sent_0();  //向DR输入0
  sent_0();  //向DR输入0
  sent_0();  //向DR输入0   0x1   0x13(EA)
  
  for(i=0;i<24;i++)
  {
    sent_0();  //向DR输入0
  }                //向DR输入24个0   0x00 00 00
  
  DR_write();
  //以上是写入芯片擦除命令程序
  
  
  PORTA|=0x08;
  
  

  delay(60000);
}


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~arm初始化~~~~~~~~~~~~~~~~~~~~~~~~//      
void arm_init(void)
{
  PORTA&=~0x01;
  PORTB|=0x01;   
  delay(1);
  PORTB&=~0x01;    // 提供一个TCK时钟;
  PORTA|=0x01;   //arm处理器reset
  
  
  mode_1();
  mode_1();
  mode_1();
  mode_1();
  mode_1();   //进入test-logic-reset完毕
  
  mode_0();  //进入Run-test/idle
  mode_1();   //进入Select-DR-scan
  mode_1();   //进入Select-IR-scan
  mode_0();  //进入Capture-IR
  mode_0();  //进入Shift-IR
  
  sent_0();  //向IR输入0
  sent_1();   //向IR输入1
  sent_0();  //向IR输入0
  sent_0();  //向IR输入0  向IR输入了0010,即输入了2  SCAN-N
  
  mode_1();   //进入Exit1-IR
  mode_1();   //进入Updata-IR
  //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  向DR输入了0010,即输入了2  扫描链2
  
  mode_1();   //进入Exit1-DR
  mode_1();   //进入Updata-DR
  //mode_0();  //进入Run-test/idle
  
  mode_1();   //进入Select-DR-scan
  mode_1();   //进入Select-IR-scan
  mode_0();  //进入Capture-IR
  mode_0();  //进入Shift-IR
  
  sent_0();  //向IR输入0
  sent_0();  //向IR输入0  
  sent_1();   //向IR输入1
  sent_1();   //向IR输入1 向IR输入了1100,即输入了Oxc  INTEST
  
  mode_1();   //进入Exit1-IR
  mode_1();   //进入Updata-IR
  mode_0();  //进入Run-test/idle模式,且保持
  
  delay(10000);
}

⌨️ 快捷键说明

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