(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引脚控制
设置制定AVR引脚的工作模式。
pinMode()函数的高效率版本,仅产生单条指令。
pin:
希望控制的Arduino-Lite的数字IO引脚号,接受数字常量、宏常量,不支持变量输入。
mode:
希望的IO引脚工作模式,取值可以为: INPUT, OUTPUT
例子: 设定第9号IO引脚工作为输出模式:
#define PIN_ID 9 PIN_MODE( PIN_ID, OUTPUT );
控制指定引脚输出指定电平状态
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 );
读取指定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输出控制
在指定引脚上输出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信号,仅生成单条指令。指定引脚需要事先开启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信号,仅生成单条指令。如果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输出模式,指定的引脚必须支持PWM输出,否则将出现编译错误。
高效版本,仅生成单条指令。
pin:
希望设定的Arduino-Lite的PWM引脚号,接受数字常量、宏常量,不支持变量输入。
例子: 开启10号引脚的PWM输出功能
#define PWM_PIN 10 PIN_MODE( PWM_PIN, OUTPUT ); PWM_ENABLE( PWM_PIN );
关闭指定引脚的PWM输出模式,指定的引脚必须支持PWM输出,否则将出现编译错误。
高效版本,仅生成单条指令。。
pin:
希望设定的Arduino-Lite的PWM引脚号,接受数字常量、宏常量,不支持变量输入。
例子: 关闭10号引脚的PWM输出功能
#define PWM_PIN 10 PWM_DISABLE( PWM_PIN );
模拟量采集(ADC)
Arduino-Lite沿用了Arduino的analogRead函数,但提供了如下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);
中断处理和管理
开启对指定的外部中断的响应,并设置中断触发条件。
类似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"); }
串口通讯
为了代码尺寸和效率的考虑,Arduino中的Serial类在Arduino-Lite中移除,如下是Serial类的替代和改进函数。
打开串口模块,使得串口工作在19200bps速率。也可以通过定义宏BAUD修改工作速率类似于Arduino中的Serial.begin(19200),高效率版本
例子: 将串口模块开启,工作在19200bps
SERIAL_BEIGN(); PRINT("Hello AVRn");
开启AVR的串口模块,并工作在指定速率。如果当前AVR芯片有多组串口模块,则该函数将对第一组串口进行操作。
类似于Arduino的Serial.beign(),采用了相对高效的实现。
baud
串口的工作速率
例子: 开启串口并工作在115200bps,然后将buffer数组的数据发送
serial_begin(115200); uint8_t buffer[100]; serial_puts(buffer, sizeof(buffer));
获得串口接受缓冲区中尚未读取的字节数。如果AVR芯片具有多个串口模块,则对第一个进行操作。
类似Arduino中的Serial.available();
返回值:
接受缓冲区中尚未读取的字节数,如果缓冲区为空,则返回0
从串口接受缓冲区中取出一个字节的数据,如果缓冲区中没有内容,则返回一个负值。如果AVR芯片具有多个串口模块,则对第一个串口进行操作。
类似于Arduino中的Serial.getc()函数
返回值
读取得到的字节,如果返回负数,则表示当前接受缓冲区不存在内容。
例子: 将串口接收到的数据发送回去
SERIAL_BEGIN(); while(1) { int current_char = serial_getc(); if (current_char >= 0 ) { serial_putc( current_char ); } }
将一个字节的数据从串口发送出去。如果AVR芯片具有多个串口模块,则对第一个串口进行操作。
类似于Arduino中的Serial.putc()函数
例子: 将串口接收到的数据发送回去
SERIAL_BEGIN(); while(1) { int current_char = serial_getc(); if (current_char >= 0 ) { serial_putc( current_char ); } }
将缓冲区的数据经过串口发送出去。如果AVR芯片具有多个串口模块,则对第一个串口进行操作。
类似于Arduino中的Serial.puts()函数
buf:
用于发送的数据指针
size:
需要发送的字节数
例子: 开启串口并工作在115200bps,然后将buffer数组的数据发送
serial_begin(115200); uint8_t buffer[100]; serial_puts(buffer, sizeof(buffer));
依次发送缓冲区数组中的每个字节,直到发送的字节是0时停止。如果AVR芯片具有多个串口模块,则对第一个串口进行操作。
类似于Arduino中的Serial.puts()函数
buf:
指向以0数据作为结尾的内存指针
例子: 开启串口并工作在115200bps,然后将字符串的数据发送
serial_begin(115200); serial_puts((uint8_t *)"Hello Worldn");
这是一系列函数,比如serial_getc_at(),用于具有多组串口模块的AVR芯片,具体使用请参见代码net_serial.h和net_serial.cpp
睡眠和延迟
将AVR芯片睡眠指定时间后唤醒,睡眠期间芯片将工作在低功耗模式。
效果类似delay()函数,但具有节能效果。
ms:
睡眠的时长,以毫秒为单位
例子: 使得AVR芯片睡眠1.5秒
sleep(1500);
将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(); }
调试功能
将字符串、数字或是指定输出进制的数字从串口输出。代码等价与:
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);
用于调试模式的串口输出,当定义_DEBUG宏时,行为与PRINT()一致。否则该宏将不存在任何作用。
该宏可以用于程序调试阶段输出调试信息。
例子: 输出调试用信息
#define _DEBUG DBG_PRINT( "program started.n" );
文本格式化
将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 ); }
将str存储的文本通过调用puts_func存储或者发送。
str:
支持字符串常量或变量
puts_func:
符合如下定义的函数指针类型:
typedef void (*puts_func)(uint8_t *);print函数会调用puts_func将产生的字符串输出通过它输出。
可以serial_puts该参数,此时print将会把str数据输出到串口。
调用puts_func,输出一个换行符。
puts_func:
符合如下定义的函数指针类型:
typedef void (*puts_func)( uint8_t *);
例子: 通过串口发送一个换行符
SERIAL_BEGIN(); println( serial_puts ); }
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的最小运行系统:
本软件只支持命令行界面啊,上面的代码是在arduino IDE中的界面吧!