Chinaunix首页 | 论坛 | 博客
  • 博客访问: 165801
  • 博文数量: 73
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 235
  • 用 户 组: 普通用户
  • 注册时间: 2014-06-27 09:43
个人简介

为兴趣挑灯夜战

文章分类
文章存档

2018年(4)

2017年(7)

2016年(9)

2015年(4)

2014年(49)

分类: 嵌入式

2017-03-09 23:48:00

好久没用AVR单片机了,最近用了一下,被折腾惨了...........
由于要在公司的老产品上添加一些新的功能,这是很久前的工程师做的代码,两年前我曾用过atmega64单片机,但那是在Atmel studio 6上,现在在IAR里开发AVR还是头一次。
由于不能在线调试,只能用串口打印数据来调试代码,所以就编了一些打印函数,可是问题来了,代码运用不正常。为了便于观察,我把数据转化成16进制字符格式输出。先来看看转化函数:

点击(此处)折叠或打开

  1. void PrintStr(char *Strings)
  2. {
  3.     char *str;
  4.     str=Strings;
  5.     
  6.     while(*str!='\0')
  7.     {        
  8.         putchar(*str);
  9.         str++;
  10.     }
  11. }


  12. void printHex(unsigned char c)
  13. {
  14. unsigned char numstr[16]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
  15.    putchar(numstr[c>>4]);
  16.    putchar(numstr[c&0x0f]);
  17. }


  18. void printStrLhex(char *str,void *databuf,unsigned short int num)
  19. {
  20.   unsigned short int i;
  21.   unsigned char *buf=(unsigned char *)databuf;
  22.   PrintStr(str);
  23.   for(i=0;i<num;i++)
  24.   {
  25.     printHex(buf[i]);
  26.   }
  27.   
  28.   PrintStr("\r\n");
  29. }


函数printStrLhex()的用法是先打印一串 ,然后在后面接着打印指定指针起的n个数据的十六进制字符,比如:
unsigned char databuf[10]={1,2,3,4,5,6,7,8,9,10};
执行printStrLhex
(“databuf= ”,databuf,10);后,串口输出字符串:databuf=01 02 03 04 05 06 07 08 09 0A,这个代码在STM32上能够正常运行,但是在AVR上,老是出问题,数据转十六进制部分会输出乱码,或不停的输出乱码或同一个相同的数据,有时候单片机还会复位,出现看起来是numstr数组没被初始化一样,不停的输出同一个数据像是没正常的读到指定数据的长度,复位现象又像是内存泄漏,三个问题绞在一起实在头疼,最后不numstr数组的定义到函数外,并加const 限制,打印出来的数据字符就不出现乱码了,但是有时会不停的打印数据,根本就停不下来,打印的数据也不对,也还会有复位现象。有了前面数组问题的经验,我后面也是把怀疑的目光投向了数组,把定义在函数内的数组,需要一指针传参给其他函数时的数组都加了statc限制,这回一运行一切都OK。
这是什么原因呢,我想这是编译器的问题了,人家原来在keil里面用得好好的代码,在IAR的却不行,这是编译器的问题了,加上static后问题是解决了,但是这样会让这些数字一直占着内存,大大减小了内存的利用率。

另外再贴结果常用的函数
void printHexS(void *c,unsigned short int len),将指定缓冲区的数据按指定长度以十六进制格式字符打印。
void printHexS(void *c,unsigned short int len)
{
  unsigned short int i;
  unsigned char *buf=(unsigned char *)c;

  for(i=0;i   {
    printHex(buf[i]);
  }
  PrintStr("\r\n");
}


//memset
void _memset(unsigned char* databuf,unsigned char value,unsigned short int length)
{
   unsigned short int i;
    
    if(!databuf)
        return;
    for(i=0;i     {
        databuf[i]=value;
    }
}

//memcpy
char _memcpy(unsigned char * dbuf,unsigned char *sbuf,unsigned short int len)
{
    unsigned short int i;
    
    if((!dbuf) || (!sbuf))
        return FALSE;
    for(i=0;i     {
        dbuf[i]=sbuf[i];            
    }    
    return TRUE ;
}


//内存数据比较
char _memcmp(unsigned char * destr,unsigned char *cmpstr,unsigned short int len)
{
    unsigned short int i;
    for(i=0;i     {
        if(destr[i]!=cmpstr[i])
            return FALSE;
    }
    
    return TRUE;
}
//将缓冲区数据按字节颠倒。
void _memtranspose(unsigned char *databuf,unsigned short int len)
{
    unsigned short int i;
    unsigned char temp;
    
    for(i=0;i     {
        temp=databuf[i];
        databuf[i]=databuf[len-i-1];
        databuf[len-i-1]=temp;
    }        
}


这些函数在编程中使用频率很好,自己实现,不需要调用系统库函数。

阅读(1241) | 评论(0) | 转发(0) |
0

上一篇:串口通信 DTR DSR RTS CTS

下一篇:RFID之--开篇

给主人留下些什么吧!~~