日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Arduino 代码机制

發布時間:2023/12/10 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Arduino 代码机制 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
?? ? 新建一個Arduino程序。可是建完就郁悶了,因為只看到了setup和loop函數,卻沒有基本的c函數。
void setup() {// put your setup code here, to run once: }void loop() {// put your main code here, to run repeatedly: } ? ?? ? 于是好奇心就來了,當然對于開源代碼來說這個沒有什么秘密。查一下源代碼就知道了。
? ?? ? 從配置文件來看,核心代碼在cores\arduino下。進入代碼目錄可以看到這里各個文件都是按照功能來命名的,所以很好辨認。很容易就能找到main.cpp,我們打開來看看具體內容:
int main(void) {init();#if defined(USBCON)USBDevice.attach(); #endifsetup();for (;;) {loop();if (serialEventRun) serialEventRun();}return 0; }
? ?? ? 看到我們熟悉的main函數了吧,同時看到main函數里在初始化時調用了setup函數,在for循環里調用了loop函數,所以這下大家明白了為什么在arduino中寫代碼的時候只看到setup和loop函數了吧,setup函數和loop函數已經預調用了。

? ?? ? 接下來再打開一個最簡單的例子Blink。
int led = 13;// the setup routine runs once when you press reset: void setup() { // initialize the digital pin as an output.pinMode(led, OUTPUT); }// the loop routine runs over and over again forever: void loop() {digitalWrite(led, HIGH); // turn the LED on (HIGH is the voltage level)delay(1000); // wait for a seconddigitalWrite(led, LOW); // turn the LED off by making the voltage LOWdelay(1000); // wait for a second }
? ?? ? 這個代碼原理很簡單,把引腳13設置成輸出,然后使用for循環,在13腳交替輸出高低電平;這個邏輯很好理解。但是這其中又有疑問了;寫過avr c代碼的同學肯定都知道,一般對某個端口或者引腳操作都是使用DDRX,PORTX,PINX來操作的,為什么這里可以直接用數字來操作呢?
? ?? ? 接下來繼續分析一下pinMode這個函數,這個函數在cores\arduino\Wiring_digital.c文件里。
void pinMode(uint8_t pin, uint8_t mode) {uint8_t bit = digitalPinToBitMask(pin);uint8_t port = digitalPinToPort(pin);volatile uint8_t *reg, *out;if (port == NOT_A_PIN) return;// JWS: can I let the optimizer do this?reg = portModeRegister(port);out = portOutputRegister(port);………… }
? ?? ? 我只貼出了主要功能函數,其它部分代碼感興趣的可以自己去研究。這里可以看出主要函數是digitalPinToBitMask,digitalPinToPort,portModeRegister,portOutputRegister這幾個。本著打破砂鍋問到底的精神,我們繼續搜索這幾個函數的實現,這下可以看到是4個宏。
#define digitalPinToPort(P) ( pgm_read_byte( digital_pin_to_port_PGM + (P) ) ) #define digitalPinToBitMask(P) ( pgm_read_byte( digital_pin_to_bit_mask_PGM + (P) ) ) #define portInputRegister(P) ( (volatile uint8_t *)( pgm_read_word( port_to_input_PGM + (P))) ) #define portModeRegister(P) ( (volatile uint8_t *)( pgm_read_word( port_to_mode_PGM + (P))) )

? ?? ? 對于pgm_read_byte這個函數說明如下:

?????? 讀取指令pgm_read_xxx宏定義其實就是一段包括了flash讀取指令的內聯匯編代碼。函數原型為:

pgm_read_byte(address_short);pgm_read_word(address_short);pgm_read_dword(address_short);pgm_read_float(address_short);//括號中是地址值。
?????? 本文的關鍵,不是pgm_read_byte這個函數,而是pgm_read_byte這個函數里面的參數:digital_pin_to_port_PGM,digital_pin_to_bit_mask_PGM,pgm_read_word( port_to_input_PGM,pgm_read_word( port_to_mode_PGM。看看這四個參數的定義在哪里。

? ?? ? ?? 經過搜索發現在?? hardware\arduino\variants\leonardo\ Pins_arduino.h里,是不是很眼熟呀,是的,就是講配置文件的時候講過這個文件作用。

? ?? ? 所以不難發現,arduino是是先把各個芯片的端口和引腳的映射關系都定義成幾個表格,這幾個表格把引腳所在的位置作為索引,在使用的時候通過引腳位置,通過查表得到對應的功能寄存器。然后就可以設置輸出輸入模式,設置輸入輸出電平,對于arduino來說只需要告訴它需要操作哪個引腳,以及要怎么操作。而不需要去關心這個引腳在哪個port上,是在PORTA還是在PORTB,更不用關心這個芯片是什么型號。
? ?? ? 對于芯片的定時器,pwm等基礎功能arduino都是按照這種方式實現的。就不再多說了。有了這些相信各位同學對arduino的使用會更加得心應手。

總結

以上是生活随笔為你收集整理的Arduino 代码机制的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。