极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 6029|回复: 2

使用arduino 2560给atmega 644p做并行编程,请高人指点。

[复制链接]
发表于 2012-10-26 19:36:05 | 显示全部楼层 |阅读模式

小弟的atmega644p在一次读取熔丝值后,不知道什么原因就再也连不上usbasp了,刚开始以为usbasp坏了,就又买了一个,发现还是不行,就觉得是芯片出了问题。后来,发现可以并行高压编程进行恢复,恰好手上有块arduino 2560,就想自己搞一下。

我是直接将一个DIP40的座子焊到插针上,插在arduino上,接线如下:
atmega644p pb0 pb1 pb2 pb3 pb4 pb5 pb6 pb7 xa1 xa0 bs2 bs1 xtal1 oe wr bsy pagel   vcc avcc gnd   reset         
arduino2560 47   45   43   41   39   37   35   33   16   17   46  18   16    20 19 21  15        v5  v5    gnd   未接入
由于没有板子来加mos,所以用手动完成reset的0v到12v的转换。

最后发现不能用,翻了几遍datasheet也不明白错在哪里,请高人指点一下。

代码回帖跟上。
回复

使用道具 举报

 楼主| 发表于 2012-10-26 19:36:23 | 显示全部楼层
/**
* Atmega644p parallel promgram by using Aruino 2560
* version 0.1
* Author by Sahlite.hu
* Data by 2012/10/25
*/

/*
* the progammer(Arduino 2560) is called master.
* the slave is the Atmega644p to be programmed.
*/
/*
* data 0~7 I/O pins, read from or write to slave
*/
#define DATA0 47
#define DATA1 45
#define DATA2 43
#define DATA3 41
#define DATA4 39
#define DATA5 37
#define DATA6 35
#define DATA7 33
/*
* positive plus XTAL1 pin issue slave to excute the given command
* work with command(DATA0~7), XA0, XA1
*/
#define XTAL1 23
// RDYBSY is low as slave in working
#define RDYBSY 21
/*
* pull down OE to read from slave
* work witch data pins
*/
#define OE 20
/*
* pull down WR to write to slave
* work with data pins
*/
#define WR 19
/*
* BS2 | BS1 | flash/eeprom address | flash data reading/loading | fuse programing | read fuse and lock bits
*  0  |  0  | low byte             | low byte                   | low byte        | fuse low byte
*  0  |  1  | high byte            | high byte                  | high byte       | lock bits
*  1  |  0  | externed high byte   | reserved                   | externed byte   | externed fuse byte
*  1  |  1  | reseved              | reserved                   | reserved        | fuse high byte
*/
#define BS1 18
#define BS2 46
/*
* XA1 | XA0 | action when XTAL1 is plused
*  0  |  0  | load flash and eeprom addres
*  0  |  1  | load data
*  1  |  0  | load command
*  1  |  1  | no action, idle
*/
#define XA0 17
#define XA1 16
// program memory and eeprom data page load
#define PAGEL 15
//reserved for pcb
#define RESET12V

// switch the slave status for master to write or read.
#define SWITCH_WRITE_MODE \
  digitalWrite(WR, LOW);\
  digitalWrite(OE, HIGH)
  
#define SWITCH_READ_MODE \
digitalWrite(WR, HIGH);\
digitalWrite(OE, LOW)

// switch data pins status for master to write or read
#define SET_DATA_OUT \
  pinMode(DATA0, OUTPUT); \
  pinMode(DATA1, OUTPUT); \
  pinMode(DATA2, OUTPUT); \
  pinMode(DATA3, OUTPUT); \
  pinMode(DATA4, OUTPUT); \
  pinMode(DATA5, OUTPUT); \
  pinMode(DATA6, OUTPUT); \
  pinMode(DATA7, OUTPUT)
  
  
#define SET_DATA_IN \
  pinMode(DATA0, INPUT); \
  pinMode(DATA1, INPUT); \
  pinMode(DATA2, INPUT); \
  pinMode(DATA3, INPUT); \
  pinMode(DATA4, INPUT); \
  pinMode(DATA5, INPUT); \
  pinMode(DATA6, INPUT); \
  pinMode(DATA7, INPUT)
   
// check the slave is busy or not   
#define IS_SLV_BUSY  (LOW == digitalRead(RDYBSY))   
#define IS_SLV_READY (HIGH == digitalRead(RDYBSY))

//send positive pluse to the given pin
#define SEND_POSITIVE_PLUSE(pin) \
  digitalWrite(pin, LOW); \
  delay(1); \
  digitalWrite(pin, HIGH); \
  delay(1); \
  digitalWrite(pin, LOW)
  
// send negative pluse to the given pin  
#define SEND_NEGATIVE_PLUSE(pin) \
  digitalWrite(pin, HIGH); \
  delay(1); \
  digitalWrite(pin, LOW); \
  delay(1); \
  digitalWrite(pin, HIGH)
  
// positive pluse the XTAL1 to excute the current command   
#define COMMAND_EXCUTION \
  SEND_POSITIVE_PLUSE(XTAL1)
  
// negative pluse to WR to write data
#define WRITE_DATA \
  SEND_NEGATIVE_PLUSE(WR)

// negative pluse to OE to read data
#define READ_DATA \
  SEND_NEGATIVE_PLUSE(OE)

/*
* command byte | command excuted
*  1000 0000   | chip erase
*  0100 0000   | write fuse bits
*  0010 0000   | write lock bits
*  0001 0000   | write flash
*  0001 0001   | write eeprom
*  0000 1000   | read signature byte and calibration byte
*  0000 0100   | read fuse and lock bits
*  0000 0010   | read flash
*  0000 0011   | read eeprom
*/
#define CMD_ERASE              0x80
#define CMD_WRITE_FUSE_BITS    0x40
#define CMD_WRITE_LOCK_BITS    0x20
#define CMD_WRITE_FLASH        0x10
#define CMD_WRITE_EEPROM       0x11
#define CMD_READ_SIGN_CALI     0x08
#define CMD_READ_FUSE_LOCK     0x04
#define CMD_READ_FLASH         0x02
#define CMD_READ_EEPROM        0x03

// set XA pins
#define SET_XA(data) \
  digitalWrite(XA1, (data>>1)&1); \
  digitalWrite(XA0, data&1)

#define SET_XA_00 \
  digitalWrite(XA1, 0x00);\
  digitalWrite(XA0, 0x00)

#define SET_XA_01 \
  digitalWrite(XA1, 0x00);\
  digitalWrite(XA0, 0x01)

#define SET_XA_10 \
  digitalWrite(XA1, 0x01);\
  digitalWrite(XA0, 0x00)

#define SET_XA_11 \
  digitalWrite(XA1, 0x01);\
  digitalWrite(XA0, 0x01)

#define SET_XA_IDLE SET_XA_11

//set byte select pins
#define SET_BS(data) \
  digitalWrite(BS2, (data>>1)&1); \
  digitalWrite(BS1, data&1)
  
#define SET_BS_00 \
  digitalWrite(BS2, 0x00); \
  digitalWrite(BS1, 0x00)

#define SET_BS_01 \
  digitalWrite(BS2, 0x00); \
  digitalWrite(BS1, 0x01)

#define SET_BS_10 \
  digitalWrite(BS2, 0x01); \
  digitalWrite(BS1, 0x00)

#define SET_BS_11 \
  digitalWrite(BS2, 0x01); \
  digitalWrite(BS1, 0x01)
  
// command or send data to slave  
#define SET_DATA(data) \
  digitalWrite(DATA7, (data&0x80)>>7); \
  digitalWrite(DATA6, (data&0x40)>>6); \
  digitalWrite(DATA5, (data&0x20)>>5); \
  digitalWrite(DATA4, (data&0x10)>>4); \
  digitalWrite(DATA3, (data&0x08)>>3); \
  digitalWrite(DATA2, (data&0x04)>>2); \
  digitalWrite(DATA1, (data&0x02)>>1); \
  digitalWrite(DATA0, data&1)
  
#define SET_DATA_CHECK(data, data7, data6, data5, data4, data3, data2, data1, data0) \
  data7 = (data&0x80)>>7); \
  data6 = (data&0x40)>>6); \
  data5 = (data&0x20)>>5); \
  data4 = (data&0x10)>>4); \
  data3 = (data&0x08)>>3); \
  data2 = (data&0x04)>>2); \
  data1 = (data&0x02)>>1); \
  data0 = data&0x01

// get data from slave
#define GET_DATA(data) \
  data = (digitalRead(DATA7)<<7) \
        ||(digitalRead(DATA6)<<6) \
        ||(digitalRead(DATA5)<<5) \
        ||(digitalRead(DATA4)<<4) \
        ||(digitalRead(DATA3)<<3) \
        ||(digitalRead(DATA2)<<2) \
        ||(digitalRead(DATA1)<<1) \
        ||(digitalRead(DATA0))

#define GET_DATA_CHECK(data, data7, data6, data5, data4, data3, data2, data1, data0) \
  data = ((data7<<7)&0x80)|((data6<<6)&0x40)|((data5<<5)&0x20)|((data4<<4)&0x10)|((data3<<3)&0x08)|((data2<<2)&0x04)|((data1<<1)&0x02)|((data0&0x01)
  
//set page load pin
#define SET_PAGEL(state) digitalWrite(PAGEL, state)

void setup()
{
  Serial.begin(19200);
  pinMode(XTAL1, OUTPUT);
  pinMode(RDYBSY, INPUT);
  pinMode(OE, OUTPUT);
  pinMode(WR, OUTPUT);
  pinMode(BS1, OUTPUT);
  pinMode(BS2, OUTPUT);
  pinMode(XA0, OUTPUT);
  pinMode(XA1, OUTPUT);
  pinMode(PAGEL, OUTPUT);
  //pinMode(RESET12V, OUTPUT);
  
  digitalWrite(WR, HIGH);
  digitalWrite(OE, HIGH);
  SET_DATA_OUT;
  SET_XA_IDLE;
}

int op_ch;
int num_ch;
int high_wch;
int low_wch;
int data = 0x00;
int data0 = 0x00;
int data1 = 0x01;
int data2 = 0x01;
int data3 = 0x00;
int data4 = 0x01;
int data5 = 0x00;
int data6 = 0x00;
int data7 = 0x01;

void loop()
{
  //int op_ch;
  //int num_ch;
  
  if(Serial.available())
  {
    op_ch = Serial.read();
    Serial.print(op_ch);
   
    //if (80 == op_ch)
    //{
      //num_ch = Serial.read();
      //Serial.print(op_ch);
      //Serial.print(num_ch);
      Serial.print("\n");
      switch(op_ch)
      {
        case '0': // enter parallel program mode
        enter_parallel_program();
        Serial.print("Welcom!\n");
        Serial.print("You have enter the parallel world!\n");
        Serial.print("Enjoy youself!\n");
        break;
        case '1': // erase chip
        erase_chip();
        Serial.print("Chip erased done!\n");
        break;
        case '2': // write flash
        Serial.print("/n");
        Serial.print("Sorry!Under construction\n");
        break;
        case '3': // write eeprom
        Serial.print("Sorry!Under construction\n");
        break;
        case '4': // read flash
        Serial.print("Sorry!Under construction\n");
        break;
        case '5': // read eeprom
        Serial.print("Sorry!Under construction\n");
        break;
        case '6': // write fuse
        write_fuse();
        Serial.print("Write fuse done\n");
        break;
        case '7': // read fuse and lock bits
        read_fuse();
        Serial.print("Read fuse done\n");
        Serial.print(high_wch);
        Serial.print("\n");
        Serial.print(low_wch);
        Serial.print("\n");
        break;
        case '8': // write lock bits
        Serial.print("Sorry!Under construction\n");
        break;
        case '9': // read the signature and calibration
        Serial.print("Sorry!Under construction\n");
        break;
        default:
        Serial.print("No such operation number\n");
      }
    //}
  }
}

/*
* first of all, give vcc,avcc 5+ voltage, and gnd and reset to ground.
* after this function, give reset pin 12+ voltage.
* caution: any change on [PAGEL, XA1, XA0, BS1] in 100ns after the 12+ apply to reset, will casuse failing to enter parallel program.
*/
void enter_parallel_program()
{
  int i;
  
  // send at least 6 pluse on XTAL1
  for(i=0;i<6;i++)
  {
    //COMMAND_EXCUTION;
    digitalWrite(XTAL1, HIGH);
    delay(1);
    digitalWrite(XTAL1, LOW);
    delay(1);
  }
  
  // set PAGEL, XA1, XA0, BS1 to 0x00
  SET_PAGEL(LOW);
  SET_XA(0x00);
  SET_BS(0x00);
  delay(1);  
}

/*
* 'A'
* load command to slave
*/
void load_command(int command)
{
  // set XA1,XA0 to 10 to enable command loading
  SET_XA_10;
  // set BS1 to 0
  SET_BS_00;
  // set command
  SET_DATA(command);
  // excute
  COMMAND_EXCUTION;
  // wait for slave to excute
  while(IS_SLV_BUSY);  
}

/*
* 'B'
* load low byte of address
*/
void load_address_low_byte(int address)
{
}

/*
* 'C'
* load low byte of data
*/
void load_data_low_byte(int data)
{
  // set XA1, XA0 to 01 to enable data loading
  SET_XA_01;
  // set BS2, BS1 to 00 to select low byte
  SET_BS_00;
  // set DATA[0:7] to data
  SET_DATA(data);
  // give positive pluse on XTAL1 to load data
  COMMAND_EXCUTION;
}

/*
* 'D'
* load high byte of data
*/
void load_data_hight_byte(int data)
{
  // set XA1, XA0 to 01 to enable data loading
  SET_XA_01;
  // set BS2, BS1 to 01 to select low byte
  SET_BS_01;
  // set DATA[0:7] to data
  SET_DATA(data);
  // give positive pluse on XTAL1 to load data
  COMMAND_EXCUTION;  
}

void erase_chip()
{
  load_command(CMD_ERASE);
}

void write_fuse()
{
  int data = 0;
  
  // programing fuse low bits
  // load command
  load_command(CMD_WRITE_FUSE_BITS);
  // load data low byte
  data = 0xff;
  load_data_low_byte(data);
  // send pluse to write
  WRITE_DATA;
  // wait for slave to write data
  while(IS_SLV_BUSY);
  
  // programing fuse high bits
  // load command
  load_command(CMD_WRITE_FUSE_BITS);
  // load data low byte
  data = 0xff;
  load_data_low_byte(data);
  // set BS2, BS1 to 01, select high bits
  SET_BS_01;
  // send pluse to write
  WRITE_DATA;
  // wait for slave to write data
  while(IS_SLV_BUSY);
  // set BS2, BS1 to 00
  SET_BS_00;
  
  // programing fuse externed bits
  // load command
  load_command(CMD_WRITE_FUSE_BITS);
  // load data low byte
  data = 0xff;
  load_data_low_byte(data);
  // set BS2, BS1 to 10, select externed bits
  SET_BS_10;
  // send pluse to write
  WRITE_DATA;
  // wait for slave to write data
  while(IS_SLV_BUSY);
  // set BS2, BS1 to 00
  SET_BS_00;
}

void read_fuse()
{
  int data = 0;
  
  // load command
  load_command(CMD_READ_FUSE_LOCK);
  
  // reading fuse low byte
  // set OE to 0
  digitalWrite(OE, LOW);
  // set BS2, BS1 to 00 to read low byte fuse
  SET_BS_00;
  // get data
  GET_DATA(data);
  Serial.print(data);
  low_wch |= (data&0x00ff);
  
  // reading fuse high byte
  // set OE to 0
  digitalWrite(OE, LOW);
  // set BS2, BS1 to 11 to read high byte fuse
  SET_BS_11;
  // get data
  GET_DATA(data);
  Serial.print(data);
  low_wch |= (data&0x00ff)<<8;

  // reading externed fuse byte  
  // set OE to 0
  digitalWrite(OE, LOW);
  // set BS2, BS1 to 10 to read externed byte fuse
  SET_BS_10;
  // get data
  GET_DATA(data);
  Serial.print(data);
  high_wch |= (data&0x00ff);
  
  // reading lock bits
  // set OE to 0
  digitalWrite(OE, LOW);
  // set BS2, BS1 to 01 to read lock bits
  SET_BS_01;
  // get data
  GET_DATA(data);
  Serial.print(data);
  high_wch |= (data&0x00ff)<<8;
  digitalWrite(OE, HIGH);
}
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|联系我们|极客工坊

GMT+8, 2026-6-6 00:28 , Processed in 0.034828 second(s), 18 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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