EDN首页   博客首页

0

关于投票
FLASH变量和FLASH计"次"器的构成
FLASH变量和FLASH计"次"器的构成
雁塔菜农 发表于 2006-4-8 10:24:00
hotpower 发表于 2006-4-8 09:45 ZLG-ARM ←返回版面

FLASH变量和FLASH计"次"器的构成

由于FLASH写入次数和写入擦除等待时间等方面的约束,FLASH变量和FLASH计数器很难构成.
因为有'0'不能变'1'的束缚,所以FLASH变量不可以定位到某个存储单元地址上.
同理FLASH计数器也一样.

仔细分析"FLASH二次写入技术"后不难看出,若稍做变通,就可实现真正的FLASH变量和FLASH计数器.

计数器是每次遇到它都+/- 1,那么为什么不能每次清除1位变成"计次器"呢???
FLASH一般空间很大,而且几乎都是以扇区为单位擦除的.

那么假定FLASH计数器为8位,即0~255,那么就可分配256/8=32个字节作为"FLASH计次器",即:
0xff,0xff.....,0xff表示0x00
0xfe,0xff.....,0xff表示0x01
0xfc,0xff.....,0xff表示0x02
...........................
0x00,0xff.....,0xff表示0x07
0x00,0xfe.....,0xff表示0x08
0x00,0xfc.....,0xff表示0x09
...........................
0x00,0x00.....,0xff表示0x0f
...........................
0x00,0x00.....,0x00表示0xff

对于FLASH变量则必须采用每次改写地址+1的原则,还需要限制"写入次数".
故一般与FLASH计次器联合使用,即FLASH计次器实际为FLASH变量的"写入指针".
当"写入次数"满时才清除FLASH计次器和FLASH变量所在的扇区.

注意,FLASH计次器在初始化完成后就应该读到RAM中!!!
写入FLASH变量的同时也要更新FLASH计次器以备掉电后再将FLASH计次器的值读入RAM中.

一般FLASH变量是用于不频繁改写时,若需频繁改写,则再需要将FLASH变量读入RAM中.

即运行时在RAM中,掉电或上电时在FLASH中.

阅读全文(863) | 回复(0) |反映问题 | 引用通告(0) | 编辑
 


系统分类: 单片机
用户分类: 非典应用怪潭
标签: 无标签
来源: 原创
发表评论 阅读全文(339) | 回复(1)

0

关于投票
在GCCAVR C++中如何重载new
在GCCAVR C++中如何重载new,delete---对C说拜拜
雁塔菜农 发表于 2005-5-30 3:06:00
在GCCAVR C++中如何重载new,delete---对C说拜拜
hotpower 发表于 2005-1-31 00:24 AVR 单片机 ←返回版面 举报该贴

在GCCAVR C++中如何重载new,delete

void * operator new (size_t size)
{
void * ptr;
  ptr = malloc(size);
  if (!ptr) return ptr;
  memset(ptr, '\0', size);
  return ptr;
}


void  operator delete(void * obj)
{
  free(obj);
}

应用:
inline String::String(const char * str)
{
  if (!str) {
    _size = 0;
    _string = 0;
  }
  else {
    _size = strlen(str);
    _string = new char(_size + 1);
    strcpy(_string, str);
  }
}

inline String & String::operator = (const char * s)
{
  if (!s) {
    _size = 0;
    delete _string;
    _string = 0;
  }
  else {
    _size = strlen(s);
    delete _string;
    if (_size == 0) _string = 0;
    else {
      _string = new char(_size + 1);
      strcpy(_string, s);
    }
  }
  return *this;
}

阅读全文(440) | 回复(0) | 引用通告(4) | 编辑
 


系统分类: 单片机
用户分类: GCCAVR之C++
标签: 无标签
来源: 原创
发表评论 阅读全文(229) | 回复(0)

0

关于投票
新版WINAVR环境下Demo.c编译及调试具体步骤

新版WINAVR环境下Demo.c编译及调试具体步骤
雁塔菜农 发表于 2005-5-30 3:08:00

新版WINAVR环境下Demo.c编译及调试具体步骤
hotpower 发表于 2004-9-29 13:06 AVR 单片机 ←返回版面 举报该贴

新版WINAVR环境下Demo.c编译及调试具体步骤:
(HotPower@126.com 2004.9.28)

运行mfile.
运行Programmers Notepad 2.

1. 在Programmers Notepad 2环境下
   File->New->Project
   建立一个新项目: demo.pnproj
   在Projects窗口
   New Project Group->demo->Add Files
   打开C:\WinAvr\examples\demo\demo.c
2. 在mfile环境下
   File->Open..
   打开C:\WinAvr\mfile\makefile_template模版文件
   另存为C:\WinAvr\examples\demo\makefile
   点击ok确认.
3. 在mfile环境下
a.MakeFile->Main file name..
   设置main file为demo
b.Mainfile->Mcu type->At90->at90s2313
c.Mainfile->Debug format->Avr-ext-COFF(AVR Studio...)
   生成可以在avrstudio中打开进行源码级调试的目标文件
   C:\WinAvr\examples\demo\demo.cof
4. 在mfile环境下
   File->save保存make文件
5. 在Programmers Notepad 2环境下
   在Projects窗口
   New Project Group->demo->Add Files
   打开C:\WinAvr\examples\demo\makefile
   Tools->[WINAVR] Make ALL
   在Output窗口显示C:\WinAvr\examples\demo\demo.c的编译结果如下:

> "make.exe" all

-------- begin --------
avr-gcc (GCC) 3.4.1
Copyright (C) 2004 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.


Compiling: demo.c
avr-gcc -c -mmcu=at90s2313 -I. -gstabs   -Os -funsigned-char -funsigned-
bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-
adhlns=demo.lst  -std=gnu99 -Wp,-M,-MP,-MT,demo.o,-MF,.dep/demo.o.d demo.c -o
demo.o

Linking: demo.elf
avr-gcc -mmcu=at90s2313 -I. -gstabs   -Os -funsigned-char -funsigned-bitfields -
fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=demo.o  -
std=gnu99 -Wp,-M,-MP,-MT,demo.o,-MF,.dep/demo.elf.d demo.o    --output
demo.elf -Wl,-Map=demo.map,--cref    -lm

Creating load file for Flash: demo.hex
avr-objcopy -O ihex -R .eeprom demo.elf demo.hex

Creating load file for EEPROM: demo.eep
avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" \
--change-section-lma .eeprom=0 -O ihex demo.elf demo.eep

Creating Extended Listing: demo.lss
avr-objdump -h -S demo.elf > demo.lss

Creating Symbol Table: demo.sym
avr-nm -n demo.elf > demo.sym

Converting to AVR Extended COFF: demo.cof
avr-objcopy --debugging --change-section-address .data-0x800000 --change-
section-address .bss-0x800000 --change-section-address .noinit-0x800000 --
change-section-address .eeprom-0x810000  -O coff-ext-avr demo.elf demo.cof
Discarding local symbol outside any compilation unit: .do_copy_data_start
Discarding local symbol outside any compilation unit: .do_copy_data_loop
Discarding local symbol outside any compilation unit: .do_clear_bss_start
Discarding local symbol outside any compilation unit: .do_clear_bss_loop

Size after:
demo.elf  :
section    size      addr
.text       244         0
.data         0   8388704
.bss          3   8388704
.noinit       0   8388707
.eeprom       0   8454144
.stab       804         0
.stabstr   1234         0
Total      2285



Errors: none
-------- end --------


> Process Exit Code: 0
   

6.运行AVR Studio 4
  键入cancel放弃创建或打开AVR Studio的项目文件
  选择AVR Simulator ->AT90S2313
  键入finish, AVR Studio 4开始创建deno_cof.aps文件
  
7.在AVR Studio 4环境下Debug Demo.c
  ...............
  
  
  HotPower@126.com 2004.9.28 于中秋月下



 

现在觉得很方便
hotpower 发表于 2005-1-22 09:38 AVR 单片机 ←返回版面 举报该贴

d步骤对单个文件实际就是废话,主要用于多文件系统...

单文件也可用d步骤,但必须将include xxx.c左边的对勾去掉才行...这不更麻烦吗???

实际上,用熟了make工具后,只需3步即可:

1.打开自己已存在的同种MCU的makefile.
2.改写aMakeFile->Main file name..  
   设置main file为自己的主文件(不要加文件后缀)

如果想多文件
2.1 Mainfile->C/C++ source file(s)...  
    选择a1.c a2.c an.c  
    点击ok. (注意,include xxx.c左边的对勾不能去掉,xxx是主文件)


3.保存在现在的目录中  
   File->save as...保存make文件  


   

附1.如果想void main(void){}不警告,就直接改写makefile
CFLAGS +=  -ffreestanding

附2.如果想C++编程,也可直接改写makefile(不能用-ffreestanding)
将CC = avr-gcc改为CC = avr-g++

可以看出,实际每次只需改文件名即可...
如果都是main.c那么就直接拷贝makefile到当前目录即可...


刚开始觉得makefile有点烦,现在觉得很方便,几乎不费劲...


阅读全文(553) | 回复(0) | 引用通告(0) | 编辑
 


系统分类: 单片机
用户分类: GCCAVR之C++
标签: 无标签
来源: 原创
发表评论 阅读全文(435) | 回复(0)

0

关于投票
SST39VF800A之"FLASH二次写入"图解

点击开大图

从图中可以清晰地看出FLASH是在不擦除的情况下进行"FLASH二次写入"的.

所谓"FLASH二次写入"即某字节的某位为'1'时是可以写入'0'的,但'0'是不可以写入'1'的!!!

因为'0'想写入'1'是需要扇区擦除的!!!

利用"FLASH二次写入"是可以延长FLASH寿命和提高效率的.

常用的有"RAM计数器",即"FLASH计次器"

初始为0xff.

计数0为0xff--->1111 1111

计数1为0xfe--->1111 1110

计数2为0xfc--->1111 1100

...........................................

计数255为0x00--->0000 0000

系统分类: DSP
用户分类: 非典应用怪潭
标签: 无标签
来源: 原创
发表评论 阅读全文(238) | 回复(0)

0

关于投票
DSP2812串口FIFO设置及"手动触发"发送中断服务之C++程序

所谓"手动触发"发送中断祥见: 俺来非典非典---利用UDRIE实现"手动触发"

这次菜农又在DSP2812上再次倒塌成功,特发帖祝贺~~~

/*****************************************************

注: 引用此法(实际给出了一般和FIFO两种串口编程方法用SCI_FIFO_MODE区别)

切记是菜农倒塌的~~~

转载请注明: 雁塔菜地 HotPower@126.com  2008.5.7

*****************************************************/

1.设置

void UartObj::Init(void)
{
unsigned int i;
    for (i = 0; i < sizeof(ReceiveBuffer); i ++) {
        ReceiveBuffer[i] = 0;
    }
    for (i = 0; i < sizeof(SendBuffer); i ++) {
        SendBuffer[i] = 0;
    }
    ReceiveWritePtr = 0;
    ReceiveReadPtr = 0;
    ReceivePosition = 0;
    ReceiveCount = 0;
    SendWritePtr = 0;
    SendReadPtr = 0;
 SendBusy = false;
 State = 0;
  
 EALLOW;
    GpioMuxRegs.GPFMUX.bit.SCITXDA_GPIOF4 = 1;
    GpioMuxRegs.GPFMUX.bit.SCIRXDA_GPIOF5 = 1;
 EDIS;

    SciaRegs.SCICCR.all = 0x0007;   // 1 stop bit,  No loopback
                                  // No parity,8 char bits,
                                  // async mode, idle-line protocol
    SciaRegs.SCICTL1.all = 0x0003;  // enable TX, RX, internal SCICLK,
                                  // Disable RX ERR, SLEEP, TXWAKE
    SciaRegs.SCICTL2.bit.TXINTENA =1;
    SciaRegs.SCICTL2.bit.RXBKINTENA =1;
    SciaRegs.SCIHBAUD = 0x0000;
//    SciaRegs.SCILBAUD = SCI_PRD;
    SciaRegs.SCILBAUD = SCI_BAUD(CBR_38400);
#if SCI_FIFO_MODE
//    SciaRegs.SCICCR.bit.LOOPBKENA =1; // Enable loop back
    SciaRegs.SCIFFTX.all=0xE061;
    SciaRegs.SCIFFRX.all=0x2028;
#else   
    SciaRegs.SCIFFTX.all=0xA000;
    SciaRegs.SCIFFRX.all=0x201F;
#endif
    SciaRegs.SCIFFCT.all=0x00;

    SciaRegs.SCICTL1.all =0x0023;     // Relinquish SCI from Reset
#if SCI_FIFO_MODE
 SciaRegs.SCICTL1.bit.SWRESET = 1;
//    SciaRegs.SCIFFTX.bit.TXFIFOXRESET=1;
    SciaRegs.SCIFFRX.bit.RXFIFORESET=1;
    PieCtrlRegs.PIECRTL.bit.ENPIE = 1;   // Enable the PIE block
#endif 
 PieCtrlRegs.PIEIER9.bit.INTx1 = 1;
 PieCtrlRegs.PIEIER9.bit.INTx2 = 1;

 /*设置中断服务程序入口地址*/
 EALLOW; // This is needed to write to EALLOW protected registers
 PieVectTable.TXAINT = &ISRTxUart;
 PieVectTable.RXAINT = &ISRRxUart;
 EDIS;   // This is needed to disable write to EALLOW protected registers

 /*开中断*/
 IER |= M_INT9;
}

2."手动触发"发送中断

void UartObj::putchar(const char dat)
{
char ch;
    ch = dat;
    SendBuffer[SendWritePtr ++] = ch;//写入发送缓冲区(并非FIFO!!!)
    SendWritePtr &= sizeof(SendBuffer) - 1;
    if ((!SendBusy) && (dat == 0x0a))
    {
     SendBusy = true;
#if SCI_FIFO_MODE
     SciaRegs.SCIFFTX.bit.TXFIFOXRESET=1;//.手动触发"发送中断

#else
  SciaRegs.SCITXBUF = SendBuffer[SendReadPtr ++];
  SendReadPtr &= sizeof(SendBuffer) - 1;
#endif  
    }
}

3.收发中断服务程序

interrupt void ISRTxUart(void)
{
#if SCI_FIFO_MODE//串口为FIFO中断模式
 for (int i = 14 - SciaRegs.SCIFFTX.bit.TXFFST; (i > 0) && (Uart.SendWritePtr != Uart.SendReadPtr); i --)
 {//最多发送14个字符,16个容易丢字符
  SciaRegs.SCITXBUF = Uart.SendBuffer[Uart.SendReadPtr ++];
  Uart.SendReadPtr &= sizeof(Uart.SendBuffer) - 1;
 }
 Uart.SendBusy = Uart.SendWritePtr != Uart.SendReadPtr;//判断缓冲区空

//注意下句是成功的关键!!!
 SciaRegs.SCIFFTX.bit.TXFIFOXRESET = Uart.SendBusy//缓冲区非空
                                  || SciaRegs.SCIFFTX.bit.TXFFST;//FIFO非空
 SciaRegs.SCIFFTX.bit.TXINTCLR = 1;
#else//串口为一般中断模式
 if (Uart.SendWritePtr != Uart.SendReadPtr)//缓冲区非空允许发送
 {
  SciaRegs.SCITXBUF = Uart.SendBuffer[Uart.SendReadPtr ++];
  Uart.SendReadPtr &= sizeof(Uart.SendBuffer) - 1;
 }
 Uart.SendBusy = Uart.SendWritePtr != Uart.SendReadPtr;//判断缓冲区空
#endif 
 PieCtrlRegs.PIEACK.bit.ACK9 = 1;
}


interrupt void ISRRxUart(void)
{
#if SCI_FIFO_MODE//串口为FIFO中断模式
 for (int i = SciaRegs.SCIFFRX.bit.RXFIFST; i > 0; i --)
 {
  Uart.ReceiveBuffer[Uart.ReceiveWritePtr ++] = SciaRegs.SCIRXBUF.all;
  Uart.ReceiveWritePtr &= sizeof(Uart.ReceiveBuffer) - 1;
 }
 SciaRegs.SCIFFRX.bit.RXFFOVRCLR = 1;
 SciaRegs.SCIFFRX.bit.RXFFINTCLR = 1;
#else//串口为一般中断模式
 Uart.ReceiveBuffer[Uart.ReceiveWritePtr ++] = SciaRegs.SCIRXBUF.all;
 Uart.ReceiveWritePtr &= sizeof(Uart.ReceiveBuffer) - 1;
#endif 
 PieCtrlRegs.PIEACK.bit.ACK9 = 1;
}

interrupt void ISRADC(void)
{
   Adc.Result[0] = AdcRegs.ADCRESULT0 >>4;
   Adc.Result[1] = AdcRegs.ADCRESULT1 >>4;

   // Reinitialize for next ADC sequence
   AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1;         // Reset SEQ1
   AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1;       // Clear INT SEQ1 bit
   PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;   // Acknowledge interrupt to PIE
}

有关帖图如下:

 

点击开大图

点击开大图

系统分类: DSP
用户分类: DSP2812
标签: 无标签
来源: 原创
发表评论 阅读全文(806) | 回复(0)
总共 , 当前 /