使用ATMEGA8A 自己制作ARDUINO全过程

发布者:绿意盎然最新更新时间:2022-07-20 来源: csdn关键字:ATMEGA8A  ARDUINO  全过程 手机看文章 扫描二维码
随时随地手机看文章

手上多余一大堆Mega8,最近刚好在熟悉ISP,想自己做一批来测试,重新写了Bootload,把代码贴出来给大家自己做,只用了512个字节,使用0x1c00开始地址作为Bootload地址,开机进入Bootload,10秒钟重启一次,如有有代码自动进入用户程序。

先上代码:


include

#include

#include

#include

#include

//#include


//#define EEPROM 0

//FUCS FF D9 00 FF  0x1800

//FUCS FF DA 00 FF  0x1C00  OKOK


//#define F_CPU 16000000


/* We, Malmoitians, like slow interaction

 * therefore the slow baud rate ;-)

 */


//#define BAUD_RATE 9600


/* 6.000.000 is more or less 8 seconds at the

 * speed configured here

 */


//#define MAX_TIME_COUNT 6000000

#define MAX_TIME_COUNT (F_CPU>>1)

//#define MAX_TIME_COUNT_MORATORY 1600000


/* SW_MAJOR and MINOR needs to be updated from time to time to avoid warning message from AVR Studio */

#define HW_VER 0x02

#define SW_MAJOR 0x01

#define SW_MINOR 0x12


// AVR-GCC compiler compatibility

// avr-gcc compiler v3.1.x and older doesn't support outb() and inb()

//      if necessary, convert outb and inb to outp and inp

#ifndef outb

#define outb(sfr,val)  (_SFR_BYTE(sfr) = (val))

#endif

#ifndef inb

#define inb(sfr) _SFR_BYTE(sfr)

#endif


/* defines for future compatibility */

#ifndef cbi

#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))

#endif

#ifndef sbi

#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))

#endif


/* Adjust to suit whatever pin your hardware uses to enter the bootloader */

#define eeprom_rb(addr)   eeprom_read_byte ((uint8_t *)(addr))

#define eeprom_rw(addr)   eeprom_read_word ((uint16_t *)(addr))

#define eeprom_wb(addr, val)   eeprom_write_byte ((uint8_t *)(addr), (uint8_t)(val))


/* Onboard LED is connected to pin PB5 */

#define LED_DDR  DDRB

#define LED_PORT PORTB

#define LED_PIN  PIND

#define LED      PIND5


#define SIG1 0x1E // Yep, Atmel is the only manufacturer of AVR micros.  Single source :(

#define SIG2 0x93

#define SIG3 0x07

#define PAGE_SIZE 0x20U //32 words


void putch(char);

char getch(void);

void getNch(uint8_t);

void byte_response(uint8_t);

void nothing_response(void);

#if 1


union address_union {

  uint16_t word;

  uint8_t  byte[2];

} address;


union length_union {

  uint16_t word;

  uint8_t  byte[2];

} length;

#endif

//uint16_t length;

//uint16_t address;


struct flags_struct {

  unsigned eeprom : 1;

 //unsigned rampz  : 1;

} flags;


uint8_t buff[256];

//uint8_t address_high;


//uint8_t pagesz=0x80;


//uint8_t i;

//uint8_t bootuart0=0,bootuart1=0;



void (*app_start)(void) = 0x0000;



void putch(char ch)

{

  /* m8 */

  while (!(inb(UCSRA) & _BV(UDRE)));

  outb(UDR,ch);

}


char getch(void)

{

  /* m8 */

uint32_t count = 0;

  while(!(inb(UCSRA) & _BV(RXC))) {

/* HACKME:: here is a good place to count times*/

count++;

//putch('.');

if (count > MAX_TIME_COUNT){

putch('!');

app_start();

}

  }

  return (inb(UDR));

}


void getNch(uint8_t count)

{

  uint8_t i;

  for(i=0;i    /* m8 */

    //while(!(inb(UCSRA) & _BV(RXC)));

    //inb(UDR);

getch(); // need to handle time out

  }

}


void byte_response(uint8_t val)

{

  if (getch() ==0x20) {

    putch(0x14);

    putch(val);

    putch(0x10);

  }

}


void nothing_response(void)

{

  if (getch() == 0x20) {

    putch(0x14);

    putch(0x10);

  }

}



int main(void)

{

  uint8_t ch,ch2;

  uint16_t w;


  //cbi(BL_DDR,BL);

  //sbi(BL_PORT,BL);


  asm volatile("nopnt");


  /* check if flash is programmed already, if not start bootloader anyway */

  //if(pgm_read_byte_near(0x0000) != 0xFF) {


    /* check if bootloader pin is set low */

   // if(bit_is_set(BL_PIN,BL)) app_start();

  //}


  /* initialize UART(s) depending on CPU defined */

  /* m8 */

  UBRRH = (((F_CPU/BAUD_RATE)/16)-1)>>8; // set baud rate

  UBRRL = (((F_CPU/BAUD_RATE)/16)-1);

  UCSRB = (1<  UCSRC = (1<

  //UBRRL = (uint8_t)(F_CPU/(BAUD_RATE*16L)-1);

  //UBRRH = (F_CPU/(BAUD_RATE*16L)-1) >> 8;

  //UCSRA = 0x00;

  //UCSRC = 0x86;

  //UCSRB = _BV(TXEN)|_BV(RXEN);



  /* this was giving uisp problems, so I removed it; without it, the boot

     works on with uisp and avrdude on the mac (at least). */

  putch('');


  //uint32_t l;

  //uint32_t time_count;

  //time_count=0;


  /* set LED pin as output */

//  sbi(LED_DDR,LED);

// for (i = 0; i < 16; i++) {

// outb(LED_PORT, inb(LED_PORT) ^ _BV(LED));

// _delay_loop_2(0);

// }

//for (l=0; l<40000000; l++)

//outb(LED_PORT, inb(LED_PORT) ^= _BV(LED));


  /* flash onboard LED three times to signal entering of bootloader */

  //for(i=0; i<3; ++i) {

    //for(l=0; l<40000000; ++l);

   // sbi(LED_PORT,LED);

    //for(l=0; l<40000000; ++l);

    //

  //}


 /* see comment at previous call to putch() */

 //putch(''); // this line is needed for the synchronization of the programmer

//cbi(LED_PORT,LED); 

  /* forever */

  for (;;) {

 //sbi(LED_PORT,LED);

    //if((inb(UCSRA) & _BV(RXC))){

    /* get character from UART */

ch = getch();

/* A bunch of if...else if... gives smaller code than switch...case ! */

/* Hello is anyone home ? */ 

if((ch=='P')||(ch=='Q')||(ch=='R')||(ch=='0')) {

  nothing_response();

  

  if (ch=='Q')app_start();

}

/* Request programmer ID */

/* Not using PROGMEM string due to boot block in m128 being beyond 64kB boundry  */

/* Would need to selectively manipulate RAMPZ, and it's only 9 characters anyway so who cares.  */

else if(ch=='1') {

if (getch() == ' ') {

putch(0x14);

putch('A');

putch('V');

putch('R');

putch(' ');

putch('I');

putch('S');

putch('P');

putch(0x10);

  }

}

/* AVR ISP/STK500 board commands  DON'T CARE so default nothing_response */

else if(ch=='@') {

  ch2 = getch();

  if (ch2>0x85) getch();

  nothing_response();

}

/* AVR ISP/STK500 board requests */

else if(ch=='A') {

  ch2 = getch();

  if(ch2==0x80) byte_response(HW_VER); // Hardware version

  else if(ch2==0x81) byte_response(SW_MAJOR); // Software major version

  else if(ch2==0x82) byte_response(SW_MINOR); // Software minor version

  //else if(ch2==0x98) byte_response(0x03); // Unknown but seems to be required by avr studio 3.56

  else byte_response(0x00); // Covers various unnecessary responses we don't care about

}

/* Device Parameters  DON'T CARE, DEVICE IS FIXED  */

else if(ch=='B') {

  getNch(20);

  nothing_response();

}

/* Parallel programming stuff  DON'T CARE  */

else if(ch=='E') {

  getNch(5);

  nothing_response();

}



/* Universal SPI programming command, disabled.  Would be used for fuses and lock bits.  */

else if(ch=='V') {

  getNch(4);

  byte_response(00);

}

/* Write memory, length is big endian and is in bytes  */

else if(ch=='d') {

  length.byte[1] = getch();

  length.byte[0]= getch();

  flags.eeprom = 0;

  

  if (getch() == 'E') flags.eeprom = 1;

  

  // putch(length);  

  // putch(length>>8);

   

  for (w=0;w     buff[w] = getch();                         // Store data in buffer, can't keep up with serial data stream whilst programming pages

  }


  if (getch() ==0x20) 

  {

//   putch('W');

#ifdef EERPOM

if (flags.eeprom) {                 //Write to EEPROM one byte at a time

for(w=0;w eeprom_wb(address.word,buff[w]);

address.word++;

}

// putch('E');

} else

#else

if (flags.eeprom==0)

#endif 

{ //Write to FLASH one page at a time

//if (address.byte[1]>127) address_high = 0x01; //Only possible with m128, m256 will need 3rd address byte. FIXME

//else address_high = 0x00;

//address = address << 1;         //address * 2 -> byte location

//if ((length.byte[0] & 0x01)) length++; //Even up an odd number of bytes


// putch('F');


#if 1

cli(); //Disable interrupts, just to be sure

// sbi(PORTD,3);

//sbi(LED_PORT,LED);

while(bit_is_set(EECR,EEWE)); //Wait for previous EEPROM writes to complete

// sbi(PORTD,3);

//cbi(LED_PORT,LED);

asm volatile(

"clr r17 nt" //page_word_count

 

"lds r30,address nt" //Address of FLASH location (in words)

"lds r31,address+1 nt"

"lsl   r30 nt"  //address * 2 -> byte location

"rol   r31 nt" 

 

"ldi r28,lo8(buff) nt" //Start of buffer array in RAM

"ldi r29,hi8(buff) nt"

 

"lds r24,length nt" //Length of data to be written (in bytes)

"lds r25,length+1 nt"

 

"sbrs r24,0 nt"  //Even up an odd number of bytes

"rjmp length_loop nt"

"adiw r24,1 nt"

 

"length_loop: nt" //Main loop, repeat for number of words in block  

"cpi r17,0x00 nt" //If page_word_count=0 then erase page

[1] [2] [3]
关键字:ATMEGA8A  ARDUINO  全过程 引用地址:使用ATMEGA8A 自己制作ARDUINO全过程

上一篇:Atmel Studio 6使用
下一篇:利用Arduino IDE对ATMEGA8等单片机编程

推荐阅读最新更新时间:2024-11-12 20:53

AVR开发 Arduino方法(七) 嵌入式操作系统FreeRTOS
FreeRTOS可以提供任务管理,队列管理,中断管理,资源管理和内存管理等功能,由于占用资源少,它可以运行在Arduino UNO R3开发板上。 你可以在 https://github.com/greiman/FreeRTOS-Arduino 上下载到它,将下载到的FreeRTOS-Arduino-master.zip解压,并将/FreeRTOS-Arduino-master/libraries文件夹下的内容全部复制到Arduino IDE安装目录下的libraries文件夹里就可以使用了。下面是它提供的frBlink示例: 1 // frBlink.ino 2 #include FreeRTOS_AVR.h 3
[单片机]
Arduino宣布加入AWS ISV计划
日前,Arduino 正式宣布与亚马逊网络服务 (AWS) 合作,为边缘硬件和云服务提供新方向。 新的合作伙伴关系将为 Arduino 和 Arduino Cloud 客户提供更多选择,将 AWS 集成到物联网项目中。 为所有人提供云计算 Arduino Cloud 从三年前开始就在 AWS 基础设施上运行,自发布以来,Arduino 增加了对该产品的投资,扩大了团队,添加了新功能,并创建了商业和教育版本。 事实证明,这是一个正确的决定。 Arduino Cloud目前已经每月处理40 亿条设备消息,成为 AWS 上部署的最重要的 IoT SaaS 平台之一。 同时,企业级业务也是大力投资且增长最快的领域之一,包括
[嵌入式]
13岁极客DIY“谷歌眼镜”
Google Glass作为未来可穿戴设备的明星产品成为了众多极客模仿的对象,而今天一名13岁的男孩Clay Haight自己DIY了“Google Glass”,由Arduino Esplora上的传感器、Arduino LCD屏幕和一个3D打印镜架组成,能够使用语音命令来设置日历项、查看当地地图、温度和天气信息等等。 Clay表示:“眼镜佩戴起来非常的舒适,事实上当我们在家里戴上这副眼镜然后告诉我的父母现在的温度,这是多么的有趣。”Clay从小就展现了对DIY的天赋,在他8岁的时候他从他的外公手中拿到了一本关于事物如何创造和如何修复日常设备的书籍,对此他对电子、机器人和其他DIY项目产生了浓厚的兴趣,在他10岁的时
[手机便携]
13岁极客DIY“谷歌眼镜”
Arduino+Avr libc制作Badusb原理及示例讲解
一、 前言 2014年美国黑帽大会上研究人员JakobLell和Karsten Nohl展示了badusb的攻击方法后,国内与badusb相关的文章虽然有了一些,但是大部分人把相关文章都阅读后还是会有种“不明觉厉”的感觉,badusb仍有一层朦胧的面纱。经过一段时间的学习和研究后,笔者希望通过自己的一些心得体会可以帮助其他人更清晰地认识badusb,也希望这篇文章能够起到一定的启发。这篇文章主要分为五个部分——知识扫盲部分、badusb固件编写部分、badusb配置界面部分、技术展望部分和总结部分。 二、硬件准备 本文使用的硬件是Arduino Leonardo开发板,但是不难将Leonardo开发板替换为其它Arduino
[单片机]
<font color='red'>Arduino</font>+Avr libc制作Badusb原理及示例讲解
DS18B20温度计制作详细全过程
元件盒一直躺着几只DS18B20,从没试过,决定用它做个电子温度计,说干就干... 1、构思  Mega8做大脑、小塑料盒做外壳、3位LED数码管显示、废弃手机电池做电源、线路板热转印制作、设置2个开关(1个按键式、1个拨动式可常开)、RS232升级程序。先想这些吧,开始干了。 2、画电路出图  电路原理图很简单,很快用PROTEL99SE画完;  根据小塑料盒大小设计PCB板,布好线,这步也不复杂。 裁好热转印纸,准备出图了,我喜欢打印时选择 Show Holes ,这样在焊盘上就有孔。用我刚买的HP3050Z一体机,那天逛科技市场,看了感觉不错就搬回来了,从没用它打过转印纸,还不知道效果呢。   ......图出来了,还不错
[单片机]
DS18B20温度计制作详细<font color='red'>全过程</font>
瑞萨对话Arduino:开源硬件正获得企业级青睐
Arduino 的用户群不断多元化,已不止业余爱好者,越来越多的企业级应用正在采用 瑞萨电子 1000 万美元的投资使 Arduino 能够推出 Uno R4,它将处理元件从 8 位提升到 32 位,性能大幅提升 这一进步加速了 Arduino 在企业级的应用普及 瑞萨电子合作伙伴证明 Arduino 不仅仅适合周末 DIY 爱好者 瑞萨电子最近与 Arduino 首席执行官 Fabio Violante 进行了座谈,讨论了开源开发环境如何随着用户群的扩大而不断发展。 此次谈话发生在瑞萨电子向 Arduino 投资 1000 万美元(3200 万美元 B 轮融资的一部分)一年多之后。 这项投资还使 Arduino
[嵌入式]
瑞萨对话<font color='red'>Arduino</font>:开源硬件正获得企业级青睐
Arduino 回应嵌入式系统 Mbed 终止支持影响:已找到替代方案,年底前发布首个测试版
7 月 26 日消息,Arm 公司于 7 月 9 日发布公告, 宣布将于 2026 年 7 月终止支持开源嵌入式操作系统 Mbed OS ,后续不再继续维护,届时 Mbed 网站将被存档,并且将无法通过在线工具构建项目。 这则消息在嵌入式开发社区引起广泛讨论,影响 Arm 支持的项目(如 micro:bit、Arduino 和 Raspberry Pi)。 Arduino 公司于 7 月 24 日发布博文,表示几年前就开始寻找替代解决方案,因此于 2023 年加入 Zephyr 项目,并成为该项目银牌成员,并在 ZephyrOS 中找到了一个很好的替代品。 Arduino 公司为了让用户能够继续使用其熟悉的语言和库,就需要在
[嵌入式]
<font color='red'>Arduino</font> 回应嵌入式系统 Mbed 终止支持影响:已找到替代方案,年底前发布首个测试版
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
  • 学习ARM开发(16)
    ARM有很多东西要学习,那么中断,就肯定是需要学习的东西。自从CPU引入中断以来,才真正地进入多任务系统工作,并且大大提高了工作效率。采 ...
  • 学习ARM开发(17)
    因为嵌入式系统里全部要使用中断的,那么我的S3C44B0怎么样中断流程呢?那我就需要了解整个流程了。要深入了解,最好的方法,就是去写程序 ...
  • 学习ARM开发(18)
    上一次已经了解ARM的中断处理过程,并且可以设置中断函数,那么它这样就可以工作了吗?答案是否定的。因为S3C44B0还有好几个寄存器是控制中 ...
  • 嵌入式系统调试仿真工具
    嵌入式硬件系统设计出来后就要进行调试,不管是硬件调试还是软件调试或者程序固化,都需要用到调试仿真工具。 随着处理器新品种、新 ...
  • 最近困扰在心中的一个小疑问终于解惑了~~
    最近在驱动方面一直在概念上不能很好的理解 有时候结合别人写的一点usb的例子能有点感觉,但是因为arm体系里面没有像单片机那样直接讲解引脚 ...
  • 学习ARM开发(1)
  • 学习ARM开发(2)
  • 学习ARM开发(4)
  • 学习ARM开发(6)
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved