📄 uart-io.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 "def.h"
char temp;
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 = 0x5C; //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;
}
//~~~~~~~~~~~~~~~~开始编程Flash页~~~~~~~~~~~~~~~~//
void ProgrammingFlash(void)
{
as=0x4C;
IO_SPI();
as=adh;
IO_SPI();
as=adl;
IO_SPI();
as=0x00;
IO_SPI();
delay1(5);
tempadh=adh;
tempadl=adl;
}
//~~~~~~~~~~~~~~~~补零~~~~~~~~~~~~~~~~//
void zero(void)
{
if (tadl!=adl)
{
while(tadl!=adl)
{
as=0x40;
IO_SPI();
as=tadh;
IO_SPI();
as=tadl;
IO_SPI();
as=0x00;
IO_SPI();
as=0x48;
IO_SPI();
as=tadh;
IO_SPI();
as=tadl;
IO_SPI();
as=0x00;
IO_SPI();
if (tadl==0xFF)
{
tadl=adl;
adh--;
adl=0xFF;
ProgrammingFlash();
adh++;
adl=tadl;
tadh++;
}
else
{
fadl=tadl&0x3F; //取LSB后六位
if (fadl==0x3F)
{
tadl1=adl;
adl=tadl;
ProgrammingFlash();
adl=tadl1;
}
}
tadl++;
}
ads--;
}
beg=1;
}
void end(void)
{
if (rxtxend==0&&temp==':')
{
ts=0;
rxtxend=1;
}
if (rxtxend==1)
{
if (ts<7)
{
ts++;
}
else if (ts==7)
{
if (temp=='0')
{
ts++;
}
else
{
rxtxend=0;
ts=0;
}
}
else if (ts==8)
{
if (temp=='1')
{
rxtxend=2;
ts=0;
}
else
{
rxtxend=0;
ts=0;
}
}
}
if (rxtxend==2&&temp==0x0A)
{
rxtxend++;
}
}
//~~~~~~~~~~~~~~~~判断下载或编程是否结束并发送地址和长度~~~~~~~~~~~~~~~~//
void jud(void)
{
if (rxtxend==0&&temp==':')
{
ts=0;
rxtxend=1;
beg=0;
//tempadr=trueadr;
}
if (rxtxend==1)
{
if (ts==0)
{
ts++;
}
else if (ts==1)
{
xs=ds;
xs=xs-0x30;
xs=xs<<4;
ts++;
}
else if (ts==2)
{
ys=ds;
ys=ys-0x30;
cc=xs|ys;
ts++;
if (cc!=0x14)
{
ads++;
}
}
else if (ts==3)
{
xs=ds;
xs=xs-0x30;
xs=xs<<4;
ts++;
}
else if (ts==4)
{
ys=ds;
ys=ys-0x30;
trueadr=xs|ys;
trueadr=trueadr<<8;
ts++;
}
else if (ts==5)
{
xs=ds;
xs=xs-0x30;
xs=xs<<4;
ts++;
}
else if (ts==6)
{
ys=ds;
ys=ys-0x30;
trueadr=trueadr|(xs|ys);
adl=(char)((trueadr>>1)&0x00FF);
adh=(char)((trueadr>>9)&0x00FF);
ts++;
}
else if (ts==7)
{
if (temp=='0')
{
ts++;
}
else
{
rxtxend=0;
ts=0;
}
}
else if (ts==8)
{
if (temp=='1')
{
rxtxend=2;
ts=0;
ci=0;
ads=0;
fadl=tempadl&0xC0;
if (fadl==0xC0)
{
tempadh++;
tempadl=0x00;
adh=tempadh;
adl=tempadl;
ProgrammingFlash();
}
else
{
tempadl++;
adh=tempadh;
adl=tempadl;
ProgrammingFlash();
}
}
else if (temp=='0'&&ads==0)
{
if (prof==1)
{
if (DataFlashstate==0x05||DataFlashstate==0x04||(proe==1&&temp2==1))
{
beg=1;
}
else if ((proe==1&&temp2==0))
{
beg=2;
}
}
else if (prof==0)
{
if (proe==1&&temp2==1)
{
beg=2;
}
}
rxtxend=0;
ts=0;
}
else if (temp=='0'&&ads!=0)
{
if (prof==1)
{
if (DataFlashstate==0x05||DataFlashstate==0x04||(proe==1&&temp2==1))
{
beg=1;
zero();
}
else if ((proe==1&&temp2==0))
{
beg=2;
ads=0;
}
}
else if (prof==0)
{
if (proe==1&&temp2==1)
{
beg=2;
ads=0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -