这个通过串口自升级应用程序的问题我弄了好久,还是不能往flash里面写入数据。求各位大虾帮忙!assembly.h文件:
void write_page (unsigned int adr, unsigned char function);
void fill_temp_buffer (unsigned int data,unsigned int adr);
unsigned int read_program_memory (unsigned int adr,unsigned char cmd);
void write_lock_bits (unsigned char val);
void enableRWW(void);
assembly.s文件内容:
.text
;*********************************************************
; Place a 1 for the processor you want use
;*********************************************************
MEGATYPE8 = 0
MEGATYPE16 = 0
MEGATYPE32 = 0
MEGATYPE64 = 0
MEGATYPE128 = 1
MEGATYPE162 = 0
MEGATYPE169 = 0
MEGATYPE8515 = 0
MEGATYPE8535 = 0
MEGATYPE2313 = 0
MEGATYPE48 = 0
MEGATYPE88 = 0
MEGATYPE168 = 0
MEGATYPE165 = 0
MEGATYPE3250 = 0
MEGATYPE6450 = 0
MEGATYPE3290 = 0
MEGATYPE6490 = 0
MEGATYPE406 = 0
MEGATYPE640 = 0
MEGATYPE1280 = 0
MEGATYPE2560 = 0
MEGATYPE1128 = 0
;*********************************************************
;*********************************************************
;*********************************************************
;*********************************************************
; DO NOT CHANGE ANYTHING BELOW THIS LINE !!!!!!!
;*********************************************************
;*********************************************************
;*********************************************************
;*********************************************************
.if MEGATYPE64 | MEGATYPE128
SPMCR = 0x68
.else
SPMCR = 0x57
.endif
;-----------------------------------------
; void write_page (unsigned int adr, unsigned char function);
; bits 8:15 adr addresses the page...(must setup RAMPZ beforehand!!!)
_write_page::
XCALL __WAIT_SPMEN__
movw r30, r16 ;move address to z pointer (R31 = ZH, R30 = ZL)
STS SPMCR, R18 ;argument 2 decides function
SPM ;perform pagewrite
RET
;-----------------------------------------
; void fill_temp_buffer (unsigned int data, unsigned int adr);
; bits 7:1 in adr addresses the word in the page... (2=first word, 4=second word etc..)
_fill_temp_buffer::
XCALL __WAIT_SPMEN__
movw r30, r18 ;move adress to z pointer (R31=ZH R30=ZL)
movw r0, r16 ;move data to reg 0 and 1
LDI R19, 0x01
STS SPMCR, R19
SPM ;Store program memory
RET
;-----------------------------------------
;unsigned int read_program_memory (unsigned int adr ,unsigned char cmd);
_read_program_memory::
movw r30, r16 ;move adress to z pointer
SBRC R18, 0 ;read lockbits? (second argument = 0x09)
STS SPMCR, R18 ;if so, place second argument in SPMEN register
.if MEGATYPE128
ELPM r16, Z+ ;read LSB
ELPM r17, Z ;read MSB
.else
LPM r16, Z+
LPM r17, Z
.endif
RET
;-----------------------------------------
;void write_lock_bits (unsigned char val);
_write_lock_bits::
MOV R0, R16
LDI R17, 0x09
STS SPMCR, R17
SPM ;write lockbits
RET
;-----------------------------------------
_enableRWW::
XCALL __WAIT_SPMEN__
LDI R27,0x11
STS SPMCR,R27
SPM
RET
;-----------------------------------------
__WAIT_SPMEN__:
LDS R27,SPMCR ; load SPMCR to R27
SBRC R27,0 ; check SPMEN flag
RJMP __WAIT_SPMEN__ ; wait for SPMEN flag cleared
RET
;-----------------------------------------
uart.h文件内容:
void port_init(void);
void timer0_init(void);
void uart0_init(void);
void init_devices(void);
void PutString(unsigned char *str,unsigned char n);
uart.c文件内容:
//ICC-AVR application builder : 2010-6-20 下午 08:43:47
// Target : M128
// Crystal: 7.3728Mhz
#include
#include
unsigned char data;
unsigned char uart_event=0;
unsigned char timer2_event=0;
static unsigned char timeNum=0;
void port_init(void)
{
PORTA = 0x00;
DDRA = 0x00;
PORTB = 0x00;
DDRB = 0x00;
PORTC = 0x00; //m103 output only
DDRC = 0x00;
PORTD = 0x00;
DDRD = 0x00;
PORTE = 0x00;
DDRE = 0x00;
PORTF = 0x00;
DDRF = 0x00;
PORTG = 0x00;
DDRG = 0x00;
}
//UART0 initialize
// desired baud rate: 2400
// actual: invalid baud rate
// char size: 8 bit
// parity: Even
void uart0_init(void)
{
UCSR0B = 0x00; //disable while setting baud rate
UCSR0A = 0x00;
UCSR0C = 0x26;
UBRR0L = 0xbf; //set baud rate lo
UBRR0H = 0x00; //set baud rate hi
UCSR0B = 0x98;
}
//TIMER0 initialize - prescale:Stop
// WGM: Normal
// desired value: 1mSec
// actual value: Out of range
void timer0_init(void)
{
TCCR0 = 0x00; //stop
ASSR = 0x00; //set async mode
TCNT0 = 0x00;/*INVALID SETTING*/ //set count
OCR0 = 0xff;/*INVALID SETTING*/
TCCR0 = 0x17; //start timer
}
//TIMER2 initialize - prescale:1024
// WGM: CTC
// desired value: 1Sec
// actual value: Out of range
void timer2_init(void)
{
TCCR2 = 0x00; //stop
TCNT2 = 0x00; /*INVALID SETTING*/ //setup
OCR2 = 0xff;/*INVALID SETTING*/
TCCR2 = 0x00; //start//shut down time2
}
#pragma interrupt_handler timer2_comp_isr:10
void timer2_comp_isr(void)
{
//compare occured TCNT2=OCR2
TCNT2 = 0x00;
//PutString("timer2_interrut\n",17);
if(timeNum>10)
{
timer2_event=1;
}
timeNum++;
}
#pragma interrupt_handler uart0_rx_isr:19
void uart0_rx_isr(void)
{
//uart has received a character in UDR
data=UDR0;
TCCR2 = 0x00;
TCNT2 = 0x00;
uart_event=1;
timeNum=0;
}
/*
#pragma interrupt_handler timer0_ovf_isr:17
void timer0_ovf_isr(void)
{
TCNT0 = 0x00 ; //reload counter value
}*/
//call this routine to initialize all peripherals
void init_devices(void)
{
//stop errant interrupts until set up
CLI(); //disable all interrupts
XDIV = 0x00; //xtal divider
XMCRA = 0x00; //external memory
port_init();
timer0_init();
uart0_init();
MCUCR = 0x00;
EICRA = 0x00; //extended ext ints
EICRB = 0x00; //extended ext ints
EIMSK = 0x00;
TIMSK = 0x00; //timer interrupt sources
TIMSK|=0x80;
ETIMSK = 0x00; //extended timer interrupt sources
SEI(); //re-enable interrupts
//all peripherals are now initialized
}
/********************************************
//function: DelayIR()
//input:tt: ms want to delay
//output: NULL
//Describtion:
*********************************************/
void DelayIR(unsigned int tt)
{
unsigned char i;
while(tt--)
{
for (i=8000; i>0; i--)
{
asm(" nop");
}
}
}
void PutString(unsigned char *str,unsigned char n)
{
unsigned char i;
for(i=0;i
{
UDR0=str;
while(!(UCSR0A&0x40));
UCSR0A|=0x40;
}
}
main.c文件内容:
#include "uart.h"
#include "assembly.h"
#include
#include
#define SPM_PAGESIZE 128 //flash的每页的大小为128字节
void WriteFlash(void);
void quit(void);
unsigned int address=0x0080;
extern unsigned char data;
extern unsigned char uart_event;
extern unsigned char timer2_event;
unsigned char f_data[128];
void WriteFlash(void)
{
unsigned int i;
unsigned int temp;
for(i=0;i
{
temp=f_data+f_data[i+1];
fill_temp_buffer(temp,i);
}
write_page(address,0x03);
write_page(address,0x05);
enableRWW();
}
void quit(void)
{
while(!(UCSR0A & 0x20)); //等待结束提示信息回送完成
MCUCR = 0x01;
MCUCR = 0x00; //将中断向量表迁移到应用程序区头部
RAMPZ = 0x00; //RAMPZ清零初始化
asm("jmp 0x0000\n"); //跳转到Flash的0x0000处,执行用户的应用程序
}
void main(void)
{
unsigned char num;
unsigned char dataCount=0;
unsigned char timecount=0;
init_devices();
DelayIR(1000);
PutString("input U to update!\n",20);
while(1)
{
if(data=='u')
{
uart_event=0;
break;
}
if(TIFR & 0x02)
{
if(timecount>200)
{
quit();
}
TIFR|=0x02;
timecount++;
}
}
while(1)
{
if(uart_event==1&&timer2_event==0)
{
f_data[dataCount]=data;
uart_event=0;
TCCR2 = 0x05; //打开定时器2
if(dataCount>=SPM_PAGESIZE)
{
PutString("NEW\n",4);
WriteFlash(); //收到256字节写入一页Flash中
address += SPM_PAGESIZE; //Flash页加1
memset(f_data,128,0);
dataCount=0;
}
dataCount++;
}
if(timer2_event==1&&dataCount>0)
{
PutString("timer2A\n",8);
PutString("spm_over\n",10);
WriteFlash(); //收到256字节写入一页Flash中
PutString("quitA\n",6);
quit();
}
if(timer2_event==1)
{
quit();
}
}
}
熔丝位我设定为:
EXTENDED=0xFF
HIGH=0xdd
LOW=0xFF。
串口波特率为2400,奇校验。数据位8位
木有人呀?除了熔丝位,还有别的什么需要设置的么?木有人来救救我呀!
帮你顶
我不熟悉avr , avr 没有官方的demo 么?
写入flash 前,要擦除flash,好像没看到你擦
已经有擦除了。在writeflash函数里面有擦除
flash的缓冲区在什么地方?flash里面还是ram里面?每次写一个字还是一个字节?