Arduino Leonardo 板子上的 LED 分析

正经的 Arduino Leonardo 上面有四个LED(DFrobot 的Leonardo&XBEE V1.2 上面有5个LED)。长得是下面这个样子:

led1

对照电路图 LED 连接如下:

led2

LED 控制Pin 说明
L D13 (PC7) GPIO 控制
TX PD5 USB发送数据亮
RX PB0 USB接收数据亮
ON 5V 上电就亮

初始化在 \arduino-1.8.4\hardware\arduino\avr\cores\arduino\USBCore.cpp 有定义

void USBDevice_::attach()
{
	_usbConfiguration = 0;
	_usbCurrentStatus = 0;
	_usbSuspendState = 0;
	USB_ClockEnable();

	UDINT &= ~((1<<WAKEUPI) | (1<<SUSPI)); // clear already pending WAKEUP / SUSPEND requests
	UDIEN = (1<<EORSTE) | (1<<SOFE) | (1<<SUSPE);	// Enable interrupts for EOR (End of Reset), SOF (start of frame) and SUSPEND
	
	TX_RX_LED_INIT;

#if MAGIC_KEY_POS != (RAMEND-1)
	if (pgm_read_word(FLASHEND - 1) == NEW_LUFA_SIGNATURE) {
		_updatedLUFAbootloader = true;
	}
#endif
}

 

其中的 一些宏定义在 \arduino-1.8.4\hardware\arduino\avr\variants\leonardo\pins_arduino.h

#define TX_RX_LED_INIT	DDRD |= (1<<5), DDRB |= (1<<0)
#define TXLED0			PORTD |= (1<<5)
#define TXLED1			PORTD &= ~(1<<5)
#define RXLED0			PORTB |= (1<<0)
#define RXLED1			PORTB &= ~(1<<0)

 

Tx/Rx 的作用是用来指示传输,而实际上传输是一下就发生和结束的,因此,设计上使用了一个延时

/** Pulse generation counters to keep track of the number of milliseconds remaining for each pulse type */
#define TX_RX_LED_PULSE_MS 100
volatile u8 TxLEDPulse; /**< Milliseconds remaining for data Tx LED pulse */
volatile u8 RxLEDPulse; /**< Milliseconds remaining for data Rx LED pulse */

 

当收到数据时,就Enable Led,同时重置计时器

static inline void Recv(volatile u8* data, u8 count)
{
	while (count--)


		*data++ = UEDATX;
	
	RXLED1;					// light the RX LED
	RxLEDPulse = TX_RX_LED_PULSE_MS;	
}

static inline u8 Recv8()
{
	RXLED1;					// light the RX LED
	RxLEDPulse = TX_RX_LED_PULSE_MS;

	return UEDATX;	
}
在每一个 SOF 的时候检查LED
	//	Start of Frame - happens every millisecond so we use it for TX and RX LED one-shot timing, too
	if (udint & (1<<SOFI))
	{
		USB_Flush(CDC_TX);				// Send a tx frame if found
		
		// check whether the one-shot period has elapsed.  if so, turn off the LED
		if (TxLEDPulse && !(--TxLEDPulse))
			TXLED0;
		if (RxLEDPulse && !(--RxLEDPulse))
			RXLED0;
	}

 

例子:

arduino-1.8.4\hardware\arduino\avr\variants\leonardo\pins_arduino.h

#define NUM_DIGITAL_PINS  31
#define NUM_ANALOG_INPUTS 12

/*
#define TX_RX_LED_INIT	DDRD |= (1<<5), DDRB |= (1<<0)
#define TXLED0			PORTD |= (1<<5)
#define TXLED1			PORTD &= ~(1<<5)
#define RXLED0			PORTB |= (1<<0)
#define RXLED1			PORTB &= ~(1<<0)
*/

//labz_Start
#define TX_RX_LED_INIT	DDRD |= (1<<5), DDRB |= (1<<0),DDRF = 0x81
#define TXLED0			PORTD |= (1<<5);PORTF &= ~ 0x01
#define TXLED1			PORTD &= ~(1<<5);PORTF |= 0x01
#define RXLED0			PORTB |= (1<<0);PORTF &= ~ 0x80 
#define RXLED1			PORTB &= ~(1<<0);PORTF |= 0x80
// labz _End

#define PIN_WIRE_SDA         (2)
#define PIN_WIRE_SCL         (3)


// the setup function runs once when you press reset or power the board
void setup() {
  // initialize digital pin LED_BUILTIN as an output.
  pinMode(LED_BUILTIN, OUTPUT);
}

// the loop function runs over and over again forever
void loop() {
  while (Serial.available())
    {  byte c=Serial.read();
       Serial.write(c);
      }
}

 

参考:
1.Leonardo 电路图
https://www.arduino.cc/en/uploads/Main/arduino-leonardo-schematic_3b.pdf
2.引脚关系
http://www.zembedded.com/wp-content/uploads/2013/04/Ardunio_leonardo.png

发表评论

电子邮件地址不会被公开。 必填项已用*标注