搜索
bottom↓
回复: 8

有关avr单片机IAP的应用设计问题

[复制链接]

出0入0汤圆

发表于 2012-10-10 16:51:41 | 显示全部楼层 |阅读模式
参照马潮老师的http://www.amobbs.com/forum.php? ... st%3D1%26digest%3D1技术帖,想要将ATmega128在ICC环境下的功能实现移植到AVR STDIO环境下,进行了一些改动,但结果总显示Type 'd' download, Others run app。 OK    并且不能发送.BIN文件,请问哪里还有问题?请高手指教。。
我改动的程序如下:
#include <avr/io.h>
#include<avr/boot.h>
#define SPM_PAGESIZE 256 //M128的一个Flash页为256字节(128字)
#define BAUD 38400 //波特率采用38400bps
#define CRYSTAL 8000000 //系统时钟8MHz

#define DATA_BUFFER_SIZE SPM_PAGESIZE //定义接收缓冲区长度
//定义Xmoden控制字符
#define XMODEM_NUL 0x00
#define XMODEM_SOH 0x01
#define XMODEM_STX 0x02
#define XMODEM_EOT 0x04
#define XMODEM_ACK 0x06
#define XMODEM_NAK 0x15
#define XMODEM_CAN 0x18
#define XMODEM_EOF 0x1A
#define XMODEM_RECIEVING_WAIT_CHAR 'C'
//定义全局变量
const char startupString[]="Type 'd' download, Others run app.\n\r\0";
char data[DATA_BUFFER_SIZE];
long address = 0;

//更新一个Flash页的完整处理
void write_one_page(void)
{
      int i;
      boot_page_erase(address); //擦除一个Flash页
      boot_spm_busy_wait (); //等待擦除完成
      for(i=0;i<SPM_PAGESIZE;i+=2) //将数据填入Flash缓冲页中
      {
            boot_page_fill(i, (i-address)+((i-address+1)<<8));
      }
      boot_page_erase(address); //将缓冲页数据写入一个Flash页
      boot_spm_busy_wait (); //等待写入完成
}
//从RS232发送一个字节
void uart_putchar(char c)
{
      while(!(UCSR0A & 0x20));
      UDR0 = c;
}
//从RS232接收一个字节
int uart_getchar(void)
{
      unsigned char status,res;
      if(!(UCSR0A & 0x80)) return -1; //no data to be received
      status = UCSR0A;
      res = UDR0;
      if (status & 0x1c) return -1; // If error, return -1
      return res;
}
//等待从RS232接收一个有效的字节
char uart_waitchar(void)
{
      int c;
      while((c=uart_getchar())==-1);
      return (char)c;
}
//计算CRC
int calcrc(char *ptr, int count)
{
      int crc = 0;
      char i;
      while (--count >= 0)
      {
            crc = crc ^ (int) *ptr++ << 8;
            i = 8;
            do
            {
                  if (crc & 0x8000)
                        crc = crc << 1 ^ 0x1021;
                  else
                        crc = crc << 1;
            } while(--i);
      }
      return (crc);
}
//退出Bootloader程序,从0x0000处执行应用程序
void quit(void)
{    uart_putchar('O');uart_putchar('K');
uart_putchar(0x0d);uart_putchar(0x0a);
     while(!(UCSR0A & 0x20));            //等待结束提示信息回送完成
     MCUCR = 0x01;
     MCUCR = 0x00;                    //将中断向量表迁移到应用程序区头部
     RAMPZ = 0x00;                    //RAMPZ清零初始化
     asm("jmp 0x0000
");                //跳转到Flash的0x0000处,执行用户的应用程序
}

//主程序
void main(void)
{
      int i = 0;
      unsigned char timercount = 0;
      unsigned char packNO = 1;
      int bufferPoint = 0;
      unsigned int crc;
      //初始化M128的USART0
      UBRR0H = (CRYSTAL/BAUD/16-1)>>8;
      UBRR0L = CRYSTAL/BAUD/16-1; //Set baud rate
      UCSR0B = 0x18; //Enable Receiver and Transmitter
      UCSR0C = 0x0E; //Set frame format: 8data, 2stop bit
      //初始化M128的T/C0,15ms自动重载
TCNT0=0x00;
      OCR0 = 0x78;
      TCCR0 = 0x0F;
      //向PC机发送开始提示信息
      while(startupString!='\0')
      {
            uart_putchar(startupString);
            i++;
      }
      //3秒种等待PC下发“d”,否则退出Bootloader程序,从0x0000处执行应用程序
      while(1)
      {
            if(uart_getchar()== 'd') break;
            if (TIFR & 0x02) //timer0 over flow
            {
                  if (++timercount > 200) quit(); //200*15ms = 3s
                        TIFR = TIFR|0x02;
            }
      }
      //每秒向PC机发送一个控制字符“C”,等待控制字〈soh〉
      while(uart_getchar()!=XMODEM_SOH) //receive the start of Xmodem
      {
            if(TIFR & 0x02) //timer0 over flow
            {
                  if(++timercount > 67) //wait about 1 second
                  {
                        uart_putchar(XMODEM_RECIEVING_WAIT_CHAR); //send a "C"
                        timercount=0;
                  }
                  TIFR=TIFR | 0x02;
            }
      }
      //开始接收数据块
      do
      {
            if ((packNO == uart_waitchar()) && (packNO ==(~uart_waitchar())))
            { //核对数据块编号正确
                  for(i=0;i<128;i++) //接收128个字节数据
                  {
                        data[bufferPoint]= uart_waitchar();
                        bufferPoint++;
                  }
                  crc = (uart_waitchar()<<8);
                  crc += uart_waitchar(); //接收2个字节的CRC效验字
                  if(calcrc(&data[bufferPoint-128],128)==crc) //CRC校验验证
                  { //正确接收128个字节数据
                        while(bufferPoint >= SPM_PAGESIZE)
                        { //正确接受256个字节的数据
                              write_one_page(); //收到256字节写入一页Flash中
                              address += SPM_PAGESIZE; //Flash页加1
                              bufferPoint = 0;
                        }
                        uart_putchar(XMODEM_ACK); //正确收到一个数据块
                        packNO++; //数据块编号加1
                  }
                  else
                  {
                        uart_putchar(XMODEM_NAK); //要求重发数据块
                  }
            }
            else
            {
                  uart_putchar(XMODEM_NAK); //要求重发数据块
            }
      }while(uart_waitchar()!=XMODEM_EOT); //循环接收,直到全部发完
      uart_putchar(XMODEM_ACK); //通知PC机全部收到

      if(bufferPoint)
            write_one_page(); //把剩余的数据写入Flash中
      quit(); //退出Bootloader程序,从0x0000处执行应用程序
}

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

发表于 2012-10-10 20:10:13 | 显示全部楼层
我们甚至不知道你的问题是什么,能不能说清楚问题,粘代码都在其次

出0入0汤圆

 楼主| 发表于 2012-10-11 09:30:49 | 显示全部楼层
改版没改好 发表于 2012-10-10 20:10
我们甚至不知道你的问题是什么,能不能说清楚问题,粘代码都在其次

我的意思就是,我参考的源程序是在ICC环境下编译实现的,而我现在想要在AVR STDIO环境下进行编译,所以程序要进行相应改动,而我改的不是很成功,没有出现预期现象,结果总显示Type 'd' download, Others run app。 OK    并且不能发送.BIN文件,我觉得可能还是程序的问题,但找不出错误在哪,所以想别人帮我看看

出0入0汤圆

发表于 2012-10-11 15:06:34 | 显示全部楼层
1.打开串口监视工具查看PC与板子串口的数据包发送记录
2.根据记录查找问题

出0入0汤圆

发表于 2012-10-13 13:46:10 | 显示全部楼层
lsn2012 发表于 2012-10-11 09:30
我的意思就是,我参考的源程序是在ICC环境下编译实现的,而我现在想要在AVR STDIO环境下进行编译,所以程 ...

你试着搜搜shaoziyang的例子,他给出了一个demo,我测试过好用。如果要通过bootload下载的话,需要avrubd.exe这个软件,网上都可以下到。

出0入0汤圆

 楼主| 发表于 2012-10-13 19:39:28 | 显示全部楼层
我进行了一下单步调试,发现每次在出现Type 'd' download, Others run app后,键盘输入d,单缓冲区的UDR0都接收不到这个字母,所以肯定没有反应,程序每次都会从头执行。现在我的电脑能从串口接收程序,但键盘输入的字母没法通过串口发回到板子上,难道是键盘的问题吗?

出0入0汤圆

发表于 2012-12-1 08:48:21 | 显示全部楼层
lsn2012 发表于 2012-10-13 19:39
我进行了一下单步调试,发现每次在出现Type 'd' download, Others run app后,键盘输入d,单缓冲区的UDR0都 ...

作个mark,有时间学习下

出0入0汤圆

发表于 2012-12-1 08:57:15 来自手机 | 显示全部楼层
Mark手机上网

出0入0汤圆

发表于 2013-10-10 17:47:07 | 显示全部楼层
mark  测试中
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-24 02:28

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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