認識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
相關文章
相關標籤/搜索