📄 arm5.0.c
字号:
//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 + -