认识Arduino,开始嵌入式之旅

须要的工具

硬件设备

软件

  • Atmel Studiohtml

    • 安装Atmel Studio,里面会有atmel的编译器,还会安装PC端的virtual comm port driver用来打印信息到TeraTerm
    • 固然也能够下载一个Arduino IDE,Arduino IDE能够快速地对Arduino进行编程,但我比较习惯用Atmel Studio。
  • AvrDudegit

    • 这个软件能够经过串口下载代码到Arduino
  • 串口通讯软件,putty 或者 TeraTerm
  • 代码编辑软件,Atom 或者其余任何能够编辑文本的软件

文档

开启Arduino之旅

项目介绍

这个小项目主要是带你们入门嵌入式开发领域。github

  • 点亮本身的LED小灯
  • 经过串口进行debug
  • 写一个简单的command line interface用来和板子通讯

初识Arduino硬件

咱们的核心是Arduino Uno开发板,下面这张图是Arduino的电路图。我把它的几个大块标记出来,下面我一一来讲明下。编程

  • Voltage Regulator: 它的任务是为系统提供稳定的3.3V和5V的电压。在蓝色区域有两个voltage regulator,一个是LP2985,输入5V,输出3.3V;一个是NCP1117,输入最高20V,输出5V。Arduino的供电有两种,一种是USB供电,这时候只从蓝色区域左下角的USBVCC为板子提供5V电压,而后经过一个regulator为板子提供3.3V电压。另外一种供电是经过供电插口(在板子上USB插口的下方有个圆形的黑色电源插口),这个供电插口是蓝色区域中靠中间的长方形区域,它的电压能够最高到20V,而后经过NCP1117变成5V电压,而后再经过LP2985变成3.3V电压。这里面有个值得注意的地方是蓝色区域的USBVCC出来后链接了一个三极管,三极管上面有个比较器,比较器的正向输入端链接了一个分压电路,反向输入端链接着3.3V。它的目的是若是从供电插口输入的电压不足5V,那就用USB的5V电压,不然就用供电插口的5V电压。
  • USB Control chip: USB的控制芯片,买回来的Arduino中这个芯片的固件都是已经在里面的,它的做用是把USB接口的东西转成串行通讯数据(在电路图红色的Serial Comm部分)发送给CPU,还用把CPU从串行通讯发出来的东西,传换成USB信号发送给PC机。
  • Main CPU: 主CPU是Atmel328P。8-bit CPU, 由于Arduino没有外接的serial flash 或者外接的SDRAM,因此根据芯片手册,一共有32KB 芯片上的programming flash,编译的代码能够放在这个flash里面。有2KB的SRAM,一些寄存器的信息,stack和heap,全局变量等都放在RAM里。
  • Crystal: 16MHz的晶振
  • LED: LED的输入标记是SCK,对应链接的是atmel328P上的B5管脚。LED链接了一个放大器,目的是电流不经过放大器,只是经过电压来控制LED,这样的话B5管脚能够作其余用途。
  • Serial Comm: 串口通讯端口,在CPU上经过usart给PC端发送数据。

ArduinoUno3Schematic

点亮Arduino LED小灯

建立项目

  • 选择File -> Project -> GCC executable projectssh

    • 输入项目名称,以后的芯片请选择atmel328p
  • 而后须要配置avrdude, 选择tool -> external tool开始配置avrdude函数

    • Title:avrdude programmer
    • Command: C:\avrdude\avrdude.exe 请填写到avrdude的路径。
    • Arguments: -F -V -c arduino -p ATMEGA328P -P COM6 -b 115200 -U flash:w:"$(ProjectDir)Debug\$(ItemFileName).hex":i 里面的COM6请从device manager中找出当前的comm port.

点亮LED灯

  • 点亮LED灯,须要配置PB5 GPIO寄存器。经过Atmel328p的data sheet和Arduino的电路图,输出高电平使LED亮,输出低电平使LED灭。
DDRB |= (1 << PB5);   //配置PB5的data direction register
PORTB |= (1 << PB5);  //使PB5输出高电平
PORTB &= ~(1 << PB5); //使PB5输出低电平

串口通讯

  • 当可以控制LED的开关,这时候能够说明编译器和Avrdude的代码下载也没问题。这时候为了咱们更好地debug程序,咱们须要让串口通讯正常工做,这样能够把信息打印到PC端。
  • 根据Arduino电路图,咱们须要让红色区域的serial comm正常工做。USB controller chip能够把数据从USB端口输出到PC端。
  • 在atmel328P的data sheet, section 24。有详细的USART的描述,对于USART来讲,首先确定是要配置波特率了,而后须要配置USART的一些传输模式,好比一次发8 bit 或者一次发7 bit,有没有stop bit等等。工具

    • 要注意的是data sheet里面给出了如何把波特率计算成寄存器须要的值,计算公式和板子的晶振频率有关。具体在数据手册第227页。
  • 在传输过程,就是不断的把想要发送的数据写到寄存器里,而后Atmel328P会经过两个pin发送到USB controller chip,而后USB controller chip再发送给PC端。
//配置USART
UBRR0H = (uint8_t)(BAUDRATE_9600_UBRR >> 8);    // 配置波特率
UBRR0L = (uint8_t)BAUDRATE_9600_UBRR;

UCSR0B = (1<<RXEN0) | (1<<TXEN0) | (1 << RXCIE0);   //enable接收和发送数据  

UCSR0C = (3<<UCSZ00);    //配置发送模式,8 bit 数据 1 bit stop bit
//发送数据
void USART_Transmit(uint8_t * Data, uint16_t Length)
{
  uint16_t i;
  for (i = 0; i < Length; i++)
  {
    /* Wait for empty transmit buffer */
      while (!( UCSR0A & (1<<UDRE0)));
      /* Put data into buffer, sends the data */
      UDR0 = Data[i];
  }
}
//接收数据, 使用中断接收数据
ISR(USART_RX_vect)
{
  uint8_t ReceivedData;
  ReceivedData = UDR0;
}

Command Line Interface

  • 当肯定Arduino和PC端能够正常通讯,咱们就能够开始写command line interface。顾名思义,是经过PC端输入指令,Arduino作相应的动做。通常大部分的电子产品都有本身的cli用来和产品通讯,不少状况若是要开发新的功能,就增长一条新的command,而后PC端的driver能够发送这个新的command给嵌入式设备,这样它就能够执行新的功能了。
  • command line interface源码, 里面能够输入指令使Arduino的LED开启或者关闭。
  • 在command line interface的实现过程当中,有些蛮有趣的地方。优化

    • 我用了一个circular buffer来实现数据的接收和处理,有一个read index和一个write index,使用buffer的目的就在于用户输入命令的速度要和计算机处理的速度不一样,因此咱们须要一个buffer来平衡它们。好比计算机要处理某个命令须要好久,而用户在这个命令后又连续输入了好几个其余的命令,全部其余的命令都会放到这个circular buffer而后依次处理。
    • 这个小project使用了这个volatile来定义一个变量, USART_StartCmdProcess,用来记录当前在receive buffer中有多少个命令。缘由是咱们是在中断中把这个变量自加1,当编译器编译这段代码的时候,若是没有volatile的话,编译器并不知道何时这个变量何时会加1,由于中断在任什么时候候均可能发生。所以在主函数里面有if (变量 > 0),这个判断会被编译器认为永远不会发生(编译器将这个判断为永远false)。因此加了volatile就强制编译器在编译去真正判断地判断变量的值,简单地说是不会优化主函数里面地if (变量 > 0)。

clipboard.png

  • 输入GetLedStatus, Arduino返回LED OFF
  • 输入SetLed ON,Arduino点亮LED
  • 输入GetLedStatus, Arduino返回LED ON
  • 输入SetLed OFF, Arduino关闭LED
相关文章
相关标签/搜索