AVR Ada

初识AVR-Ada

1. 缘由

Ada语言,最初是从上学时一本计算机书里知道的,据说是 DoD 的专用语言,用在紧要场合。之所以把这种编程语言命名为 Ada 是为了纪念第一个给Babbage差分机写程序的程序员 Augusta Ada Byron(1815--1852)。我住处附件有条小街,街上有个店,招牌上就写着三个大字 Ada,每次路过这三个字都让我想起 Babbage 的机器和 Ada,我也没有注意那个店是干嘛的,不过至少有一点我可以肯定:一定不会是搞 Ada 程序的 :-)

我一直对 Babbage 的机器很感兴趣,他那台复杂的机械计算机可以说是一件杰出的艺术品,当然,了解计算机历史的人可能知道法国人 Joseph Marie Jacquard 和他的可编程自动织布机

因为根本用不上,从来没有去解一下这门语言的细节。近两年断断续续学了一些AVR单片机知识,主要是用C语言开发。昨天晚上不知道是什么原因,突然想到了 AVR-Ada。(不会是那个小店的招牌吧,哈哈)。

到目前为止,可以用很多种语言来开发 AVR 软件,当我得知 AVR 可以用 Ada 来编程时,还吃了一惊。 2006年8月31日在 ouravr 发了一个贴,感兴趣的人不多,Ada 这种语言比较冷门。

对这个好玩的东西当然不能放过,于是决定要弄一下,了解一些 Ada 的语法,看用它怎样给 AVR 开发程序。好的,先从一个简单的例子开始吧:闪烁一个 LED 。

2. 电路

电路很简单:LED接在 OC1A 上,通过一个330 Ohm 的限流电阻接地。

3. 程序

这是编译器附带的例程,我把它取出来作为一个独立的项目,原例子用的是AT90S8515,我把 MCU 改成了常用的 ATmega16,在编译的过程中发现一个错误:没有定义CTC1,因为在新器件中寄存器的名字已经改了。

我查看了一下 mega16 的 datasheet,仅把下面这一句:

-- use CLK/64 prescale value, clear timer/counter on compareA match

Set (TCCR1B, TMC16_CK64 or CTC1);

修改为:

-- use CLK/64 prescale value, clear timer/counter on compareA match

Set (TCCR1B, TMC16_CK64 or WGM12);

下面是修改过的代码:

---------------------------------------------------------------------------

-- The AVR-Ada Library is free software; you can redistribute it and/or --

-- modify it under terms of the GNU General Public License as published --

-- by the Free Software Foundation; either version 2, or (at your --

-- option) any later version. The AVR-Ada Library is distributed in the --

-- hope that it will be useful, but WITHOUT ANY WARRANTY; without even --

-- the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR --

-- PURPOSE. See the GNU General Public License for more details. --

---------------------------------------------------------------------------

-- Title: Timer/Counter Output Compare Mode: Pin PD5 (OC1A) toggles

-- with 1Hz

-- Author: Peter Fleury <pfleury@gmx.ch> http://jump.to/fleury

-- Date: December 2002

-- Software: AVR-GCC 3.3

-- Hardware: AT90S8515 at 4 Mhz, STK200 compatible starter kit

-- Description:

-- Timer1 support the possibility to react on timer interrupt events

-- on a purely hardware basis without the need to execute

-- code. Related output pins can be configured to be set, cleared or

-- toggled automatically on a compare match.

-- This examples shows how to toggle an output pin and flashing a

-- LED with 1 Hz. After initialization, the LED flashes on both OC1A

-- and OC1B output pin without code execution.

-- A LED with a series resistor should be connected from OC1A/OC1B

-- pin to GND.

-- See also Atmel AVR Application Note AVR130

with Interfaces; use Interfaces;

with AVR.IO; use AVR.IO;

with AVR.MCU; use AVR.MCU;

procedure Flash_Led is

-- output compareA pin on ATmega16

OC1A : constant AVR.Bit_Number := PORTD5_Bit;

-- Timer1 Preset for 1Hz clock

TIMER_1_CNT : constant Unsigned_16 := 16#F424#;

-- 16 bit Timer Counter Prescaler Values

TMC16_CK64 : constant Unsigned_8 := CS10 + CS11;

begin

--

-- Initialisation

--

-- set OC1A pin as output, required for output toggling

-- 将 OC1A 设为输出, 触发 LED

Set_Bit (DDRD, OC1A, True);

-- enable toggle OC1A and OC1B output on compare match

-- 比较匹配使能

Set (TCCR1A, COM1A0 or COM1B0);

-- use CLK/64 prescale value, clear timer/counter on compareA match

-- Timer1 64 分频, 匹配时清零计数器

Set (TCCR1B, TMC16_CK64 or WGM12);

-- preset timer1 high/low byte

-- 向计数器预置计数值

Set16 (OCR1A, TIMER_1_CNT);

Set16 (OCR1B, TIMER_1_CNT);

--

-- Initialisation done, LED will now flash without executing any code !

--

loop -- loop forever

null;

end loop;

end Flash_Led;

4. 工程文件和Makefile

到目前为止,我还没有仔细研究过 GCC 的 Makefile,所以我准备找一个现有的 Makefile 来修改,在ada-examples 目录中正好有一个 ds1820 的例子,我把它复制到我的项目文件夹中,并作了相应的修改,无外乎就是修改 mcu 的型号、要编译器的目标文件、avrdude 所用的编程器以及编程器所用端口。

OK,我自以为万事具备只欠东风了,在命令行执行 make all 命令,没想到根本行不通,出现一些错误提示,于是我又观察了一下 ds1820 的例子。原来在目录中还有一个扩展名为 gpr 的 GNAT project file 文件,这是一个工程文件,在其中定义了这个工程,因为是用英语描述,也能看懂个大概,于是我也复制了一个到我的项目文件夹中,把名字作了改成 flash_led.gpr 并进行了相应的修改,如下:

---------------------------------------------------------------------------

-- The AVR-Ada Library is free software; you can redistribute it and/or --

-- modify it under terms of the GNU General Public License as published --

-- by the Free Software Foundation; either version 2, or (at your --

-- option) any later version. The AVR-Ada Library is distributed in the --

-- hope that it will be useful, but WITHOUT ANY WARRANTY; without even --

-- the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR --

-- PURPOSE. See the GNU General Public License for more details. --

---------------------------------------------------------------------------

with "avr.gpr";

project flash_led is

for Main use ("flash_led");

for Languages use ("Ada");

for Object_Dir use "obj";

for Exec_Dir use ".";

package Builder is

for Default_Switches ("Ada") use AVR.Builder'Default_Switches ("Ada");

for Global_Configuration_Pragmas use

AVR.Builder'Global_Configuration_Pragmas;

for Executable_Suffix use ".elf";

end Builder;

package Compiler is

for Default_Switches ("Ada") use AVR.Compiler'Default_Switches ("Ada");

end Compiler;

package Binder is

for Default_Switches ("Ada") use AVR.Binder'Default_Switches ("Ada");

end Binder;

package Linker is

for Default_Switches ("Ada") use AVR.Linker'Default_Switches ("Ada");

end Linker;

for Source_Dirs use (".");

end flash_led;

5. 实验结果

最后,我在命令行执行 make all,编译通过!在面包板上搭好电路,将生成的hex文件写入mcu,LED闪烁起来啦!电路上用的是 8MHz 晶振,对照时钟观察了一下,LED 以 1Hz 的频率闪烁。

我们来作一个计算,下面是 ATmega16 数据手册上的公式:

f_OCnA:生成波形的频率;

f_clk_I/O: MCU时钟频率;

N:计时器分频系数;

OCRnA:输出比较寄存器中存的值,在此例中,Timer1 的计数值会不停地和它比较,一旦配匹则清除 Timer1 计数值。

F424 转换成十进制是 62500,Timer1 64分频,代入具体的数字,作一个计算:

F = 8000000/[2x64x(1+62500)] = 0.9999... (结果表明,生成方波的频率是 1Hz)

啊哈,真是好玩极了!发觉 Ada 的语法和 Pascal 很相似,Lisp 语言也是一种很优美、古怪的语言,要是可以用 LISP 给 AVR 编程,我也要下功夫学一学 Lisp

嗯,我写文章总是这里扯到那里,或许这就是我的风格吧。

6. 下载

有四个文件,分别是:

1) 源程序 flash_led.adb

2) 工程文件 flash_led.gpr

3) Makefile

4) Eagle原理图 ada_flash_led.sch

点击此处下载(RAR, 24KB)

7. 相关资料

1. AVR-Ada 官方网站:http://avr-ada.sourceforge.net/

2. Snapshot 版本下载地址:https://sourceforge.net/project/showfiles.php?group_id=74228

3. Ada 程序设计语言:http://all.163.com/it/school/apl/

4. 中文Ada语言FAQ站点:http://adaicq.gro.clinux.org/

5.《贝比奇奇特的一生》见《现代世界中的数学》第83页,上海教育出版社

6. 另一篇关于 Babbage 的文章:http://libai.math.ncu.edu.tw/bcc16/pool/3.01.shtml

7. An Illustrated History of Computers:

http://www.computersciencelab.com/ComputerHistory/HistoryPt2.htm

Atommann 创建日期:2007-11-22 最后编辑:2007-11-25