📄 uart-spi-730.c
字号:
// 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 + -