Arduino-Lite开发参考文档

(Click here for the English Version)

关于Arduino-Lite的相关介绍和使用,请参考:

Arduino-Lite保留了Arduino固件库中的大部分接口,这些接口可以参考Arduino的文档:http://arduino.cc/en/Reference/HomePage
另外,任何avr-gcc提供的函数,例如_delay_ms()都可以在Arduino-Lite中使用(需要引用相关头文件)。

快速入口:

Arduino-Lite新增函数/宏

基本IO引脚控制

PWM输出控制

模拟量采集(ADC)

睡眠和延迟

中断处理和管理

串口通讯

调试功能

文本格式化

1 Arduino-Lite新增接口

这里我们介绍Arduino-Lite新增加的接口以及相对应的类似功能的arduino接口:

基本IO引脚控制

PIN_MODE(pin, mode)

设置制定AVR引脚的工作模式。

pinMode()函数的高效率版本,仅产生单条指令。

pin:

希望控制的Arduino-Lite的数字IO引脚号,接受数字常量、宏常量,不支持变量输入。

mode:

希望的IO引脚工作模式,取值可以为: INPUT, OUTPUT

例子: 设定第9号IO引脚工作为输出模式:

#define PIN_ID 9
PIN_MODE( PIN_ID, OUTPUT );
DIGITAL_WRITE( pin, value )

控制指定引脚输出指定电平状态

digitalWrite()的高效版本,仅产生单条指令

pin:

希望控制的Arduino-Lite的数字IO引脚号,接受数字常量、宏常量,不支持变量输入。

value:

IO输出的电平,接受数值: 0, 1 或者 LOW, HIGH

例子: 使得第9号引脚输出高电平

#define PIN_ID 9
PIN_MODE( PIN_ID, OUTPUT );
DIGITAL_WRITE( PIN_ID, HIGH );

DIGITAL_READ( pin )

读取指定IO引脚的输入电平状态

digitalRead()的高效版本,仅生成单条指令。

pin:

希望控制的Arduino-Lite的数字IO引脚号,接受数字常量、宏常量,不支持变量输入。

返回值:

0 – 当前IO引脚输入为低电平

非零值 – 当前IO引脚输入了高电平

例子: 读取第10号引脚的电平信息

#define PIN_ID 10
unsigned char input_level;
PIN_MODE( PIN_ID, INPUT );
input_level = DIGITAL_READ( PIN_ID );
if (input_level) {
  PRINT( "HIGHn" );
} else {
  PRINT( "LOWn" );
}

PWM输出控制

ANALOG_WRITE( pin, pwm_value )

在指定引脚上输出PWM信号,如果该引脚没有启用PWM输出模式,则自动开启

analogWrite()的高效版本,等价于如下代码。

PWM_ENABLE(pin);
PWM_SET( pin, pwm_value )

pin:

希望控制的Arduino-Lite的IO引脚号,对应引脚必须支持PWM输出,否则将编译错误。接受数字常量、宏常量,不支持变量输入。

pwmvalue

PWM占空比数值,范围0-255,接受立即数常量、变量、宏定义

例子: 在第9号引脚(PB1)输出占空比为100的PWM信号:

#define PWM_PIN 9
PIN_MODE( PWM_PIN, OUTPUT );
ANALOG_WRITE( PWM_PIN, 100 );
PWM_SET( pin, pwm_value )

在指定引脚上输出PWM信号,仅生成单条指令。指定引脚需要事先开启PWM输出模式(PWM_ENABLE)

pin:

希望控制的Arduino-Lite的IO引脚号,对应引脚必须支持PWM输出,否则将编译错误。接受数字常量、宏常量,不支持变量输入。

pwmvalue

PWM占空比数值,范围0-255,接受立即数常量、变量、宏定义

例子: 在第3号引脚(PD3)输出占空比为90的PWM信号

#define PWM_PIN 3
PIN_MODE( PWM_PIN, OUTPUT );
PWM_ENABLE( PWM_PIN );
PWM_SET( PWM_PIN, 90 );
PWM_SET_SAFE( pin, pwm_value )

在指定引脚上输出PWM信号,仅生成单条指令。如果PWM占空比为0,则将引脚设置为输入模式

指定引脚需要事先开启PWM输出模式(PWM_ENABLE)

pin:

希望控制的Arduino-Lite的IO引脚号,对应引脚必须支持PWM输出,否则将编译错误。接受数字常量、宏常量,不支持变量输入。

pwmvalue

PWM占空比数值,范围0-255,接受立即数常量、变量、宏定义电平

例子: 在第3号引脚(PD3)输出占空比由变量pwm_val决定的的PWM信号

#define PWM_PIN 3
unsigned char pwm_value = 10;
PIN_MODE( PWM_PIN, OUTPUT );
PWM_ENABLE( PWM_PIN );
PWM_SET( PWM_PIN, pwm_value );
PWM_ENABLE( pin )

开启指定引脚的PWM输出模式,指定的引脚必须支持PWM输出,否则将出现编译错误

高效版本,仅生成单条指令。

pin:

希望设定的Arduino-Lite的PWM引脚号,接受数字常量、宏常量,不支持变量输入。

例子: 开启10号引脚的PWM输出功能

#define PWM_PIN 10
PIN_MODE( PWM_PIN, OUTPUT );
PWM_ENABLE( PWM_PIN );
PWM_DISABLE( pin )

关闭指定引脚的PWM输出模式,指定的引脚必须支持PWM输出,否则将出现编译错误

高效版本,仅生成单条指令。。

pin:

希望设定的Arduino-Lite的PWM引脚号,接受数字常量、宏常量,不支持变量输入。

例子: 关闭10号引脚的PWM输出功能

#define PWM_PIN 10
PWM_DISABLE( PWM_PIN );

模拟量采集(ADC)

Arduino-Lite沿用了Arduino的analogRead函数,但提供了如下ADC控制功能:

enable_adc()

开启AVR芯片的ADC转换模块,该函数在Arduino-Lite初始化后自动执行。

例子: 开启ADC转换模块,进行ADC测量

#define ADC_PIN 1
PIN_MODE( ADC_PIN, INPUT );
enable_adc();
unsigned int adc_value = analogRead(ADC_PIN);
disable_adc()

关闭AVR芯片的ADC转换模块,该操作可以降低AVR芯片耗电,节省电能。

中断处理和管理

ENABLE_INT(vector, mode)

开启对指定的外部中断的响应,并设置中断触发条件。

类似attachInterrupt()函数,区别在于中断响应函数需要用avr-libc的ISR()宏定义。高效率版本

vector:

希望开启的外部中断号,从0开始计数。

mode

外部中断的触发条件,取值范围是:

  • LOW – 低电平触发
  • CHANGE – 电平改变时触发
  • RISING – 电平由低到高变化时触发
  • FALLING – 电平由高到低变化时触发

开启对外部中断#0的响应处理,当中断信号为上升沿时,执行处理函数INT0_vect

#define EXT_INT 0
#define EXT_INT_PIN 2 //PD2
void main()
{
  PIN_MODE( EXT_INT_PIN, INPUT );
  ENABLE_INT( EXT_INT, RISING );
}

ISR(INT0_vect)
{
  PRINT("External Interrrupt invokedn");
}
DISABLE_INT( vector )
关闭对指定外部中断的响应。对应的中断处理函数将不会被调用。

串口通讯

为了代码尺寸和效率的考虑,Arduino中的Serial类在Arduino-Lite中移除,如下是Serial类的替代和改进函数。

SERIAL_BEGIN()

打开串口模块,使得串口工作在19200bps速率。也可以通过定义宏BAUD修改工作速率类似于Arduino中的Serial.begin(19200),高效率版本

例子: 将串口模块开启,工作在19200bps

SERIAL_BEIGN();
PRINT("Hello AVRn");
void serial_begin(unsigned long baud)

开启AVR的串口模块,并工作在指定速率。如果当前AVR芯片有多组串口模块,则该函数将对第一组串口进行操作。

类似于Arduino的Serial.beign(),采用了相对高效的实现。

baud

串口的工作速率

例子: 开启串口并工作在115200bps,然后将buffer数组的数据发送

serial_begin(115200);
uint8_t buffer[100];
serial_puts(buffer, sizeof(buffer));
uint8_t serial_available(void)

获得串口接受缓冲区中尚未读取的字节数。如果AVR芯片具有多个串口模块,则对第一个进行操作。

类似Arduino中的Serial.available();

返回值:

接受缓冲区中尚未读取的字节数,如果缓冲区为空,则返回0

int serial_getc(void)

从串口接受缓冲区中取出一个字节的数据,如果缓冲区中没有内容,则返回一个负值。如果AVR芯片具有多个串口模块,则对第一个串口进行操作。

类似于Arduino中的Serial.getc()函数

返回值

读取得到的字节,如果返回负数,则表示当前接受缓冲区不存在内容。

例子: 将串口接收到的数据发送回去

SERIAL_BEGIN();
while(1)
{
  int current_char = serial_getc();
  if (current_char >= 0 )
  {
    serial_putc( current_char );
  }
}
void serial_flush(void)

清空串口接收缓冲区中未读取的数据。如果AVR芯片具有多个串口模块,则对第一个串口进行操作。

类似Arduino中的Serial.flush()

void serial_putc(uint8_t c)

将一个字节的数据从串口发送出去。如果AVR芯片具有多个串口模块,则对第一个串口进行操作。

类似于Arduino中的Serial.putc()函数

例子: 将串口接收到的数据发送回去

SERIAL_BEGIN();
while(1)
{
  int current_char = serial_getc();
  if (current_char >= 0 )
  {
    serial_putc( current_char );
  }
}
void serial_puts(uint8_t *buf, size_t size)

将缓冲区的数据经过串口发送出去。如果AVR芯片具有多个串口模块,则对第一个串口进行操作。

类似于Arduino中的Serial.puts()函数

buf:

用于发送的数据指针

size:

需要发送的字节数

例子: 开启串口并工作在115200bps,然后将buffer数组的数据发送

serial_begin(115200);
uint8_t buffer[100];
serial_puts(buffer, sizeof(buffer));
void serial_puts(uint8_t *buf)

依次发送缓冲区数组中的每个字节,直到发送的字节是0时停止。如果AVR芯片具有多个串口模块,则对第一个串口进行操作。

类似于Arduino中的Serial.puts()函数

buf:

指向以0数据作为结尾的内存指针

例子: 开启串口并工作在115200bps,然后将字符串的数据发送

serial_begin(115200);
serial_puts((uint8_t *)"Hello Worldn");
serial_xxxx_at() 系列函数

这是一系列函数,比如serial_getc_at(),用于具有多组串口模块的AVR芯片,具体使用请参见代码net_serial.h和net_serial.cpp

睡眠和延迟

sleep(unsigned long ms)

将AVR芯片睡眠指定时间后唤醒,睡眠期间芯片将工作在低功耗模式。

效果类似delay()函数,但具有节能效果。

ms:

睡眠的时长,以毫秒为单位

例子: 使得AVR芯片睡眠1.5秒

sleep(1500);
delay_alert(unsigned long ms)

将AVR进入等待模式,在等待期间有中断函数调用了alert()或者等待时间到,则函数返回继续后续执行。

该函数可用来实现信号(Event)同步机制。配合alert()函数使用

ms:

睡眠的时长,以毫秒为单位

例子: 等待5秒钟, 有用户按键(使用外部中断1)则提前退出

void main()
{
  ENABLE_INT( 1, LOW );
  PRINT("wait or press key...n");
  delay_alert(5000);
  PRINT("exit...n");
}

ISR(INT1_vect)
{
  PRINT("key pressedn");
  alert();
}
alert()

通知使得当前正在执行的delay_alert()提前退出。

调试功能

PRINT( msg, [base] )

将字符串、数字或是指定输出进制的数字从串口输出。代码等价与:

print( msg, [base], serial_puts );

msg:

需要输出的内容,接受如下数据:

  • 文本字符串常量、变量(char *类型)
  • 单个字符常量或者变量(char类型)
  • 整数常量或者变量(int)

base:

可选参数,使用时msg必须是整数或者字符类型。用于指定输出数字的进制表示,比如10-十进制,16-十六进制。

例子: 依次在串口输出字符串、10进制表示的数字、16进制表示的数字

SERIAL_BEIGN();
char * text = "hellow AVRn";
int number = 12;
PRINT("Direct Text outputn");
PRINT( 1234 );
PRINT( text );
PRINT( number );
PRINT( number, 16);
DBG_PRINT(msg, [base])

用于调试模式的串口输出,当定义_DEBUG宏时,行为与PRINT()一致。否则该宏将不存在任何作用。

该宏可以用于程序调试阶段输出调试信息。

例子: 输出调试用信息

#define _DEBUG
DBG_PRINT( "program started.n" );

文本格式化

print(val, [base], put_func)

将val的数字数据转化成文本表示,通过回调putc_func输出。

val:

支持如下类型的数值变量或者常量:

  • char
  • unsigned char (uint8_t)
  • int
  • unsigned int (uint16_t)
  • long
  • unsigned long (uint32_t)
  • double

base:
可选参数,当使用时val不能是double类型。用于指定输出的进制表示,如果不指定,将采用10进制表示。

put_func:

当val为char或者uint8_t类型(单字节)时,需要符合如下定义的函数指针类型:

typedef void (*putc_func)( uint8_t);

print函数在进行数值到文本转换时,对于每一个新转换生成的字符,都会回调putc_func输出。
可以serial_putc作为该参数,此时print将会把val数值的文本表示输出到串口。

当val为其他数值类型时,需要符合如下定义的函数指针类型:

typedef void (*puts_func)(uint8_t *);

print函数会调用puts_func将产生的字符串输出通过它输出。
可以用serial_puts作为该参数,此时print将会把str数据输出到串口。

例子: 将变量number的数值用文本表示存储在字符串buffer,并将它从串口发送出去

char buffer[20];
uint8_t pos = 0;
void putc_to_buffer(uint8_t c)
{
  buffer[pos++] = c;
}

void main()
{
  int number = 123456;
  char byte = 120;
  print( byte, putc_to_buffer);

  SERIAL_BEGIN();
  print( number, serial_puts );
}
print(const char str[], puts_func)

将str存储的文本通过调用puts_func存储或者发送。

str:

支持字符串常量或变量

puts_func:

符合如下定义的函数指针类型:

typedef void (*puts_func)(uint8_t *);

print函数会调用puts_func将产生的字符串输出通过它输出。
可以serial_puts该参数,此时print将会把str数据输出到串口。

println(puts_func)

调用puts_func,输出一个换行符。

puts_func:

符合如下定义的函数指针类型:

typedef void (*puts_func)( uint8_t *);

例子: 通过串口发送一个换行符

  SERIAL_BEGIN();
  println( serial_puts );
}
println(val, [base], put_func)

类似print(val, [base], put_func),会在末尾追加换行符。

println(str, puts_func)
类似print(str, puts_func),会在末尾追加换行符。

2 不被Arduino-Lite支持的接口/类

以下Arduino函数/类在Arduino-Lite中没有提供:

类别 条目 替代方案
Class String 使用print函数以及prints等libc函数代替,或者直接使用Arduino中的代码。
Serial 使用serial_xxx函数代替
Function tone() 可以直接使用Arduino源代码
noTone() 可以直接使用Arduino源代码

2 Arduino-Lite的引脚编号定义

对于Atmega8/Atmegax8(m48, m88, m168, m328等),Arduino-Lite采用了与Arduino兼容的引脚编号,并且做了一定的扩展,使得ADC引脚也可以作为通用IO使用。

对Arduino并不支持的Attiny芯片,Arduino-Lite也定义了他们的引脚序号。

注意,只有Arduino-Lite新增的函数支持Arduino-Lite新扩展的引脚编号。

  • Atmega8/Atmegax8
//                  +-/-+
//            PC6  1|    |28  PC5 (AI 5/*D19)
//      (D 0) PD0  2|    |27  PC4 (AI 4/*D18)
//      (D 1) PD1  3|    |26  PC3 (AI 3/*D17)
//      (D 2) PD2  4|    |25  PC2 (AI 2/*D16)
// PWM+ (D 3) PD3  5|    |24  PC1 (AI 1/*D15)
//      (D 4) PD4  6|    |23  PC0 (AI 0/*D14)
//            VCC  7|    |22  GND
//            GND  8|    |21  AREF
//     *(D20) PB6  9|    |20  AVCC
//     *(D21) PB7 10|    |19  PB5 (D 13)
// PWM+ (D 5) PD5 11|    |18  PB4 (D 12)
// PWM+ (D 6) PD6 12|    |17  PB3 (D 11) PWM
//      (D 7) PD7 13|    |16  PB2 (D 10) PWM
//      (D 8 )PB0 14|    |15  PB1 (D 9) PWM
//                  +----+
// (PWM+ indicates the additional PWM pins on the ATmega168.)
// Pins with the star(*): arduinoLite extention
  • Attiny2313
//Fuse setting for 2313: eFuse: 0xFF lFuse: 0xDF hFuse:0xDD
//                               +-/-+
//                       RESET  1|    |20  VCC
//  D0               (RXD) PD0  2|    |19  PB7 (UCSK/SCL/PCINT7)    D14
//  D1               (TXD) PD1  3|    |18  PB6 (MISO/DO/PCINT6)     D13
//                 (XTAL2) PA1  4|    |17  PB5 (MOSI/DI/SDA/PCINT5) D12
//                 (XTAL1) PA0  5|    |16  PB4 (OC1B/PCINT4)        D11 PWM
//  D2    (CKOUT/XCK/INT0) PD2  6|    |15  PB3 (OC1A/PCINT3)        D10 PWM
//  D3              (INT1) PD3  7|    |14  PB2 (OC0A/PCINT2)        D9  PWM
//  D4                (T0) PD4  8|    |13  PB1 (AIN1/PCINT1)        D8
//  PWM D5       (OC0B/T1) PD5  9|    |12  PB0 (AIN0/PCINT0)        D7
//                         GND 10|    |11  PD6 (ICP)                D6
//                               +----+
  • Attiny26
//                                    +-/-+
//  ~PWM  D0 MOSI/DI/SDA/!OC1A) PB0  1|    |20  PA0 (ADC0)               A0/D7
//  PWM D1       (MISO/DO/OC1A) PB1  2|    |19  PA1 (ADC1)               A1/D8
//  ~PWM  D2    (SCK/SCL/!OC1B) PB2  3|    |18  PA2 (ADC2)               A2/D9
//  PWM D3               (OC1B) PB3  4|    |17  PA3 (AREF)
//                              VCC  5|    |16  GND
//                              GND  6|    |15  AVCC
//  D4/A7          (ADC7/XTAL1) PB4  7|    |14  PA4 (ADC3)               A3/D10
//  D5/A8          (ADC8/XTAL2) PB5  8|    |13  PA5 (ADC4)               A4/D11
//  D6/A9        (ADC9/INT0/T0) PB6  9|    |12  PA6 (ADC5/AIN0)          A5/D12
//                (ADC10/RESET) PB7 10|    |11  PA7 (ADC6/AIN1)          A6/D13
//                                    +----+

3 电路原理图参考(最小系统参考)

  • Atmega8或者Atmegax8(Atmega48, Atmega88, Atmega168等)

支持串口固件下载的最小系统:

图中的石英振荡器可以省去并采用AVR内部的RC振荡器工作。可以通过给上述电路预先烧录支持STK500v1协议的bootloader从而实现串口自编程(使用Arduino-Lite的make upload命令)

  • Attiny26

这里给出Attiny26的最小运行系统:

3 thoughts on “Arduino-Lite开发参考文档”

Leave a Reply

Your email address will not be published. Required fields are marked *