• 最近两天都在调试1602液晶显示功能,由于没有开发板作硬件调试,只能使用Proteus进行调试,而这个软件在调试过程中却频频失去响应,这使得调试工作及其困难。同时由于GCC的编译过程中出现的一点问题使得最终得到的代码在运行过程中出现错误。下面首先来探讨下GCC编译过程中所出现的问题:
    • 主要是Delay()函数调用的问题:当函数定义为void Delay(uint8_t timer){while(timer>0) timer--;}时编译的结果使用汇编查看是一个RET指令,也就是没有进行任何延时,由于GCC是从PC平台上移植过来的,而PC程序编写过程中很重要的一点在于,通过各种方法提高程序的效率,由于上述循环为空(即从程序本身来看没有起到任何的作用),于是GCC就将它优化掉了,事实上我们需要通过这个空的循环产生一定时长的软件延时,模拟一个脉冲。OurAVR上给出了这个问题的几种解决办法:1.通过调整makefile中的代码优化等级从而使编译器不做优化(我这里使用的默认的-s级别,代码最短。但我这里即便是把优化等级调到0,即不进行代码优化,好像还是不可以)2.使用volatile 关键字强制编译器不论后续代码是否出现变量value,此操作执行代码都要生成,这个方法是可行的,加上volatile uint8_t timer就可以了 3.当然最佳的解决方法是直接调用delay.h中的_delay_us(double timer)函数,这个函数是avr-libc自带的,使用时注意加上头文件uitl/delay.h。通过查看函数原型可以发现,它是通过调用相应的汇编指令_nop()_实现的。这样生成的代码会比较小。
    • 关于1602液晶的显示问题,基本上1602、1601和其它的字符型液晶显示器都使用的是HD44780控制器(不排除例外的,只是因为这个控制器在国内使用比较普遍)。对于同一种控制器的操作是相同的,可以参照日立的DataSheet (http://tigerwang202.blogbus.com/files/1170309605.pdf)。控制时要注意在将E置高电平前,先设置R/W信号,在 E下降沿到了之前,准备好写入的命令字或数据 。只需在适当的地方加上延时,就可以满足时序要求了。下面给出试验的源代码(没有通过硬件验证的,仅供参考之用)http://tigerwang202.blogbus.com/files/1170310024.rar
    • 还有一些有用的链接:
    • http://www.sunman.com.cn/web/default.asp (国内一家制造液晶显示的厂商,有中文的数据手册,和51上的例程)
    • 1602液晶几种典型显示状态及解决方法... (OurAVR上一位网友的经验总结,蛮好的,推荐初学的看看 这是他的Blog http://blog.21ic.com/user1/3493/index.html
    • HD44780内置字符发生器的字符表.p... (HD44780控制器的字符表 从太阳人网站上转载的)
    • Applicaton Notes for Character Mode LCDs (点阵液晶的使用指南,我现在正在看的一篇应用指南内容甚为详细,要点基本上都讲到的,包括型号选择、硬件设计指导、软件设计指导等 此外还有液晶通过总线方式与各种微处理器系统的连接(P.S:这个不常见,以前只看到51用总线连液晶的)。唯一遗憾之处是这份文档是E文的)

    由于条件限制液晶这方面的工作到此为止,回学校后我会在硬件调试,到时候再贴上代码。

  • 比起8051使用软件模拟时序实现SPI功能来,AVR的硬件SPI实在是先进了许多。通过读写相应的寄存器就能轻松实现SPI的操作,使得编程变得更加方面。下面是使用AVR SPI的几个步骤:

    • 首先,应设置相应管脚的读写寄存器以设定数据传输方向。在Mega16里,SPI的接口为以下管脚:PB4-PB7 (SS/MOSI/MISO/CLK)。如果工作在主模式则可以这么写(PORTB=0xff; DDRB=0xBF; PB7(SCK):输出 PB6(MISO):输入 PB5(MOSI):输出 PB4(SS):输出)

    • 接着还需要设定SPI工作寄存器,控制的寄存器只有三个:SPDR(SPI数据寄存器)、SPCR(SPI控制寄存器)、SPSR(SPI状态寄存器),其中SPDR是读写移位寄存器中的值,SPSR中包括了SPIE:SPI中断使能位 SPE:SPI使能位 DORD:数据传送从最高位或最低位开始MSTR:主从工作方式选择 COPL/CPHA:时钟极性相位选择 SPR1/SPR0:时钟速率选择;SPSR中主要是几个状态标志位,用来做软件查询,SPIF:SPI中断标志位 WCOL:冲则可以如下设置突标志位 如果使用的是软件查询, SPCR中只需要置SPE和MSTR两位。

    • 随后的工作就是往SPDR里读写数据,需要注意的是一次最少读写一个Byte(8 bit)的数据,这和硬件的设计有关。在读取数据前需要先写入数据。可以一次读写一个字节,也可以块读写,在OurAVR上的例程中这两种方式均有,可以参考下,连接地址:http://tigerwang202.blogbus.com/files/1170133680.rar(感谢HJJourAVR 的工作)

    源程序转载自:http://www.ouravr.com.cn/guide_index.html

  • AVR的定时器的功能远比51来的强大,除了基本的定时计数功能外还有PWM等方式,正因为如此导致控制它所用的寄存器繁多,不是很好学的。在练习时,我只是对照51的定时器使用方式练习了最最基本的几个功能,至于PWM由于暂时用不上也就没看。还有就是AVR内置的看门狗可以通过调用中的现成函数使用,对此也做过一个小的练习。

    发现OurAVR却是是个学习AVR的好地方,它上面的新手快速入门中的源码很有参考价值的,建议和我一样初学AVR的新手都去看看(网址贴在这里:http://www.ouravr.com.cn/guide_index.html

    还有一件比较头痛的事,就是WinAVR中lib-c的版本改动太大,经常是一个月不到换个版本,导致某些变量定义不兼容,加之国内现有的介绍GCC的书籍都比较陈旧,经常出现那上面的例程不能通过编译的错误(其中多半是由于函数定义发生变化,或者include中库文件的路径发生了改变)。这或许也是开源软件的一个弊病吧。幸好还有个E文的manual,(http://tigerwang202.blogbus.com/files/1169908524.bz2 有个三百多页的pdf,由于成本过高,没打印出来~!)得自己慢慢地啃。。。
    源代码暂时怪在上面,可以参考参考(很多来自芯艺的代码http://tigerwang202.blogbus.com/files/1170051984.rar

  • AVR单片机比起51来一个有一个很重要的优点那就是集成了许多的外置器件,比如8位AD转换器、RTC、EEPROM。今天粗略的看了下EEPROM。基本上avr-lib里已经包括了所有常用的EEPROM操作,需要时只要调用相应的函数就可以完成以前要写N条语句完成的功能。这些功能都是以函数的形式提供的。其中包括读写字节、读写块、等待设备准备就绪等功能,真的很好用。

    下面的连接是练习的代码,很基本的功能。从一个端口读状态,存入EEPROM,再从EEPROM中读出写到另一个端口上。http://tigerwang202.blogbus.com/files/1169961105.rar

  • 今天一早起来,把AVR的开发环境搭建起来,正如昨天帖子中说得,我使用的是WinAVR+AVR Studio。基本上是用GCC做编译器,mfile生成编译器所需的MakeFile文件,用AVR Studio做软件仿真。一开始使用的源代码编辑器是PN,但发现自己在熟悉Keil后对那个编辑器的代码缩进风格不太适应,同时BS下那个平滑的字体,只是感觉不太舒服。于是按照OurAVR上的帖子换成VC6.0作为代码编辑器。在使用AVR Studio进行软件仿真时出现程序一场推出的错误,在重装换过几个版本无效后,参考了网上的帖子,将目录改为英文名的,同时使用COF结尾的文件进行仿真终于解决问题。 接下来就是初步熟悉下AVR的IO,就是读写端口等基础的操作。发现的最新的Avr Lib里面竟然没有sbi、cbi等函数而是用_BV()加上逻辑与或等怪异操作代替,对此非常想不明白。 具体的练习程序写在下面:http://tigerwang202.blogbus.com/files/1169908473.rar 在这里使用了ISIS的硬件仿真。