查看: 1930|回复: 0
打印 上一主题 下一主题

atmega 64 boot编程(附图)

[复制链接]
跳转到指定楼层
沙发
发表于 2016-4-17 00:11:32 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
/* 编译器:iccavr 6.31a
   M C U : ATmega64
   功 能 :将一个40*12的数组数据写入flash中
遇到的问题:1:程序运行后,40*12这个数组的数据确实能写入flash中,但是写入的地址不管我怎么改,都是从0x0050开始的,如下图 ;
            2:调用读flash函数,无法读出数据(读flash函数正确,我用其他方法验证过) ;
程序不长,如下,希望能够得到指点,非常感谢!!!
*/

#pragma abs_address:0xe000   //绝对地址定位到boot区

#include <iom64v.h>
#include <macros.h>

#define uchar        unsigned char
#define uint        unsigned int

#define PAGESIZEW                  128   //M16的一个Flash页为256字节(128字)
#define PAGESIZEB                  256   //M16的一个Flash页为256字节(128字)
                                          
//擦除(code=0x03)和写入(code=0x05)一个Flash页
void boot_page_ew(uint p_address,uchar code)
{
    asm("mov r30,r16");
    asm("mov r31,r17");
        asm("out 0x3b,r18");            //将页地址放入Z寄存器和RAMPZ的Bit0中
    SPMCSR = code;                //寄存器SPMCSR中为操作码
    asm("spm\n");                    //对指定Flash页进行操作
        //asm("ret");
}

//填充Flash缓冲页中的一个字
void boot_page_fill(uint address,uint data)
{
    asm("mov r30,r16");
    asm("mov r31,r17");            //Z寄存器中为填冲页内地址
    asm("mov r0,r18");
    asm("mov r1,r19");            //R0R1中为一个指令字
    SPMCSR = 0x01;
    asm("spm\n");
        //asm("ret");
}

//等待一个Flash页的写完成
void wait_page_rw_ok(void)
{
   while(SPMCSR & 0x40)
     {
         while(SPMCSR & 0x01);
         SPMCSR = 0x11;
         asm("spm\n");
                 //asm("ret");
     }
}

//更新一个Flash页的完整处理
void write_one_page(uint address,uchar data[])
{
    uint i;
        uint da[PAGESIZEW];
        uchar j;
    boot_page_ew(address,0x03);                    //擦除一个Flash页
    wait_page_rw_ok();                            //等待擦除完成
    for(i=0,j=0;i<AGESIZEB;i+=2,j++)                //将数据填入Flash缓冲页中
    {   
            da[j] = data[i+1];
                da[j] = data+ (da[j] <<8 );
        boot_page_fill(i,da[j]);
    }
    boot_page_ew(address,0x05);                    //将缓冲页数据写入一个Flash页
    wait_page_rw_ok();                            //等待写入完成
}

uchar read_flash(uint address)    //从flash中读取一字节
{
  asm("mov r30,r16");
  asm("mov r31,r17");
  asm("lpm r16,z");
  //asm("ret");
}
#pragma end_abs_address  //结束绝对地址定位

#include <eeprom.h>
uint ADDRESS[10] = {0x0000,0x0200,0x0400,0x0600,0x0800,0x0A00,0X0C00,0X0E00,0X1000,0X1200}; //10页flash的首地址
uchar DATA[40][12] = {
        {0,   1,   2,   3,   4,   5,   6,   7,   8,   9,   10,  11},
            {12,  13,  14,  15,  16,  17,  18,  19,  20,  21,  22,  23},
                {24,  25,  26,  27,  28,  29,  30,  31,  32,  33,  34,  35},  
                {36,  37,  38,  39,  40,  41,  42,  43,  44,  45,  46,  47},
                {48,  49,  50,  51,  52,  53,  54,  55,  56,  57,  58,  59},  
                {60,  61,  62,  63,  64,  65,  66,  67,  68,  69,  70,  71},  
                {72,  73,  74,  75,  76,  77,  78,  79,  80,  81,  82,  83},  
                {84,  85,  86,  87,  88,  89,  90,  91,  92,  93,  94,  95},
                {96,  97,  98,  99,  100, 101, 102, 103, 104, 105, 106, 107},
                {108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119},
                {120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131},
                {132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143},
                {144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155},
                {156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167},
                {168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179},
                {180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191},
                {192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203},
                {204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215},
                {216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227},
                {228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239},
                {0,   1,   2,   3,   4,   5,   6,   7,   8,   9,   10,  11},
            {12,  13,  14,  15,  16,  17,  18,  19,  20,  21,  22,  23},
                {24,  25,  26,  27,  28,  29,  30,  31,  32,  33,  34,  35},  
                {36,  37,  38,  39,  40,  41,  42,  43,  44,  45,  46,  47},
                {48,  49,  50,  51,  52,  53,  54,  55,  56,  57,  58,  59},  
                {60,  61,  62,  63,  64,  65,  66,  67,  68,  69,  70,  71},  
                {72,  73,  74,  75,  76,  77,  78,  79,  80,  81,  82,  83},  
                {84,  85,  86,  87,  88,  89,  90,  91,  92,  93,  94,  95},
                {96,  97,  98,  99,  100, 101, 102, 103, 104, 105, 106, 107},
                {108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119},
                {120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131},
                {132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143},
                {144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155},
                {156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167},
                {168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179},
                {180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191},
                {192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203},
                {204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215},
                {216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227},
                {228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239}
                      };     //待写入的数据
                                          
uchar data1[40][12];   //读出数据存储


void write_one_xg(uint address,uchar data[40][12])
{
  uint i;
  uchar da1[PAGESIZEB];
  uchar j=0,k=0;
  for(i=0;i<240;i++)
    {
          da1 = data[j][k];
          k++;
          if(k>=12)
            {
                  k = 0;
                  j++;
                }
        }

  write_one_page(address,da1);
  address = address + 256;
  j = 20;k=0;
  for(i=0;i<240;i++)
    {
          da1 = data[j][k];
          k++;
          if(k>=12)
            {
                  k = 0;
                  j++;
                }
        }

  write_one_page(address,da1);
}

uchar read_one_xg(uint address,uchar data[40][12])
{
  uint i;
  uchar j=0,k=0;
  for(i=0;i<240;i++)
    {
      data[j][k] = read_flash(address+i);
          k++;
          if(k >=12) {j++;k =0;}
        }
        
  j=20;k=0;        
  for(i=0;i<240;i++)
    {
      data[j][k] = read_flash(address+i);
          k++;
          if(k >=12) {j++;k =0;}
        }         
}  

void main()
{
uint i;
CLI();
MCUCR = 0x00;
TIMSK = 0x00;
SEI();

write_one_xg(ADDRESS[1],DATA);
read_one_xg(ADDRESS[1],data1);

while(1);
}

程序运行后flash存储状况 (原文件名Q截图未命名.jpg)

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 加入因仑

本版积分规则

快速回复 返回顶部 返回列表