Переписываем код arduino для MSP430 на примере nRF24_multipro, проекта для управления игрушечными мультикоптерами


قبل البدء ، أود أن أحجز على الفور أنني لم أكتب الرمز وأخذه من هنا . هذا البرنامج مكتوب في Arduino IDE وبالاشتراك مع arduino pro mini و nrf24l01 + يسمح لك بالتحكم في لعبة المروحيات المتعددة (مع رقائق راديو XN297 ، استنساخ nrf24l01) من أي معدات تحكم بها خرج PPM. يمكن العثور على جميع المعلومات حول طائرات الهليكوبتر المدعومة على الرابط أعلاه.
قررت إعادة كتابة هذا الرمز للتحكم في المروحية الصغيرة Everyine H8 من معدات Radiolink AT9. أطلب تفاصيل تحت القط.

تم اختيار MSP430 لأنه يحتوي على جهد إمداد يبلغ 3.3 فولت ، كما أن جهد الإمداد nrf24l01 هو أيضًا 3.3 فولت ، وأنا أحب MPS430 بطريقة أو بأخرى. يوجد داخل الجهاز جهات اتصال 3V3 و OUT و GND ، والتي سنتصل بها.

, , = , .



IDE Energia ( Arduino IDE MSP430 TI) , . , . , .


nRF24_multipro.ino include’. atomic EEPROM.

atomic


#include <util/atomic.h>
void update_ppm()
ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
__disable_interrupt();
__enable_interrupt();

ATOMIC_BLOCK() , «» , , ATOMIC_BLOCK().

EEPROM


MSP430 EEPROM , FLASH MspFlash.
#include <EEPROM.h>
MspFlash (Sketch->Import Library…->MspFlash), FLASH
#define flash SEGMENT_D
void selectProtocol()
else 
	current_protocol = constrain(EEPROM.read(ee_PROTOCOL_ID),0,PROTO_END-1);      
// update eeprom 
EEPROM.update(ee_PROTOCOL_ID, current_protocol);

// update eeprom 
Flash.write(flash+ee_PROTOCOL_ID, & current_protocol,1);
نزيل تمامًا قراءة معرف البروتوكول (لماذا ، اقرأ أدناه).
في الفراغ set_txid (تجديد منطقي) ، تحتاج إلى القيام بأكثر من استبدال سطرين بقليل. في ذاكرة فلاش ، لا يمكننا سوى بتات صفر. لتعيين قيمة 1 في بتات ذاكرة FLASH ، تحتاج إلى مسح المقطع بالكامل (ثم ستتم كتابة القيم 1 عليه). تُسمى هذه الوظيفة (set_txid) في وقت سابق عن selectProtocol ، لذلك سنمحو المقطع هنا.
كان:
void set_txid(bool renew)
{
    uint8_t i;
    for(i=0; i<4; i++)
        transmitterID[i] = EEPROM.read(ee_TXID0+i);
    if(renew || (transmitterID[0]==0xFF && transmitterID[1]==0x0FF)) {
        for(i=0; i<4; i++) {
            transmitterID[i] = random() & 0xFF;
            EEPROM.update(ee_TXID0+i, transmitterID[i]); 
        }            
    }
}

أصبح:
void set_txid(bool renew)
{
    uint8_t i;
    unsigned char p;
    for(i=0; i<4; i++) {
        Flash.read(flash+ee_TXID0+i,&p,1);
        transmitterID[i] =p;
    }
	Flash.read(flash+ee_PROTOCOL_ID,&p,1);
    current_protocol = constrain(p,0,PROTO_END-1);
	Flash.erase(flash);
    if(renew || (transmitterID[0]==0xFF && transmitterID[1]==0x0FF)) {
        for(i=0; i<4; i++) {
            transmitterID[i] = random(0xff) & 0xFF;
            p = transmitterID[i];
            Flash.write(flash+ee_TXID0+i, &p,1); 
        }            
    }else{
        for(i=0; i<4; i++) {
            p = transmitterID[i];
            Flash.write(flash+ee_TXID0+i, &p,1); 
        }  	
	}
}
هنا نقرأ قيمة معرفات جهاز الإرسال والبروتوكول ، ونمسح المقطع ، وإذا تم إصدار أمر لتحديث معرف جهاز الإرسال ، فإننا نكتب قيمة جديدة ، وإلا فإننا نسجل القيمة القديمة. ظل فلاش FLASH للذاكرة مع فلاش العنوان + ee_PROTOCOL_ID نظيفًا (0xFF) ، لذلك لا نقرأه في وظيفة selectProtocol () ، ولكن نكتب معرف البروتوكول على الفور.

يسجل


أولاً ، دعنا نتعامل مع الدبابيس. في هذا المشروع ، يتم استخدام تطبيق برنامج SPI ، حيث يتم استخدام وحدات الماكرو في "اهتزاز" الساقين من خلال التسجيلات.
أعد كتابة تعريفات الدبابيس
#define PPM_pin   2  // PPM in
//SPI Comm.pins with nRF24L01
#define MOSI_pin  3  // MOSI - D3
#define SCK_pin   4  // SCK  - D4
#define CE_pin    5  // CE   - D5
#define MISO_pin  A0 // MISO - A0
#define CS_pin    A1 // CS   - A1
#define ledPin    13 // LED  - D13
#define PPM_pin   P1_5  // PPM in
//SPI Comm.pins with nRF24L01
#define MOSI_pin  P2_0  // MOSI 
#define SCK_pin   P2_1  // SCK  
#define CE_pin    P2_2  // CE 
#define MISO_pin  P2_3 // MISO 
#define CS_pin    P2_4 // CS   
#define ledPin    P1_4 // LED  
#define MOSI_on PORTD |= _BV(3)  // PD3
#define MOSI_off PORTD &= ~_BV(3)// PD3
#define SCK_on PORTD |= _BV(4)   // PD4
#define SCK_off PORTD &= ~_BV(4) // PD4
#define CE_on PORTD |= _BV(5)    // PD5
#define CE_off PORTD &= ~_BV(5)  // PD5
#define CS_on PORTC |= _BV(1)    // PC1
#define CS_off PORTC &= ~_BV(1)  // PC1
// SPI input
#define  MISO_on (PINC & _BV(0)) // PC0
#define MOSI_on P2OUT |= _BV(0)// P2_0
#define MOSI_off P2OUT &= ~_BV(0)// P2_0
#define SCK_on P2OUT |= _BV(1)// P2_1
#define SCK_off P2OUT &= ~_BV(1)// P2_1
#define CE_on P2OUT |= _BV(2)// P2_2
#define CE_off P2OUT &= ~_BV(2)// P2_2
#define CS_on P2OUT |= _BV(4)// P2_4
#define CS_off P2OUT &= ~_BV(4) // P2_4
// SPI input
#define  MISO_on (P2IN & _BV(3)) // P2_3

في ATMEL MKs ، تكون سجلات PORTx في MSP430 PxOUT مسؤولة عن حالة الإخراج. بالنسبة لحالة الإدخال ، يسجل PINx و PxIN ، على التوالي. بالمناسبة ، لا توجد وظيفة _BV (x) في Energia IDE ، لذا أضفها بنفسك:
#define _BV(val) 1<<val
في إعداد الفراغ الوظيفي () ، نغير قيم الدبوس للمدخلات التناظرية مجانًا
randomSeed((analogRead(A4) & 0x1F) | (analogRead(A5) << 5));
على سبيل المثال في
randomSeed((analogRead(A0) & 0x1F) | (analogRead(A1) << 5));
في MSP430 ، تتوافق المدخلات التناظرية A0 و A1 و A2 و ... و A7 مع الدبابيس P1_0 و P1_1 و P1_2 و ... و P1_7.
عند ربط تغيير المقاطعة
attachInterrupt(PPM_pin - 2, ISR_ppm, CHANGE);
على
attachInterrupt(PPM_pin , ISR_ppm, CHANGE);
في Arduino Uno و Nano و Mini وما إلى ذلك على mega328 ، يتوفر فقط دبابيس (2 ، 3) لتوصيل المقاطعة ، وفي وظيفة attachInterrupt ، الوسيطة الأولى هي رقم المقاطعة ، وليس الدبوس كما هو الحال في MSP430. المزيد عن attachInterrupt () .

مؤقت


التغيير في إعداد الفراغ ()
TCCR1A = 0;  //reset timer1
TCCR1B = 0;
TCCR1B |= (1 << CS11);  //set timer1 to increment every 1 us @ 8MHz, 0.5 us @16MHz
مفعّلة
TACTL = TASSEL_2 + ID_3 + MC_2 + TACLR; //16000000 / 8
مطلوب جهاز ضبط الوقت لتحديد مدة النبض في جزء في المليون. قمنا بضبطه على وضع العد المباشر بتردد 2 ميجاهرتز (تردد ساعة 16 ميجاهرتز ومقسم 8).
في دالة الفراغ ISR_ppm () نغير
counterPPM = TCNT1;
TCNT1 = 0;
على
counterPPM = TAR;
TAR = 0;
السجلات TCNT1 و TAR هي عدادات عداد الوقت.

عشوائي ()


لا أعرف السبب ، ولكن لا يتم استدعاء الوظيفة العشوائية () بدون وسيطات في Energia ، ولكن نظرًا لأننا نحتاج إلى رقم عشوائي واحد بايت ، فإننا نستبدل nRF24_multipro.ino و Bayang.ino في الملفات
random() & 0xFF; 
على
random(0xFF);
و
random() % 0x42;
على
random(0x41);

؟؟؟


وأخيرًا ، في ملف MJX.ino ، في دالة MJX_bind () باطلة ، نقوم بإضافة أقواس إلى استدعاء دالة mjx_init2 ؛
نقوم بتجميع المشروع والحصول على نتيجة ناجحة.

رمز مصدر المشروع تم
تغيير رمز المشروع

لنقل البرنامج بنجاح إلى نظام أساسي آخر ، تحتاج إلى فهم ما يتم تنفيذه في هذا الرمز وكيف ولماذا ، وفهم ميزات المكتبات المتصلة والغرض من التسجيلات ، وفي أثناء العمل ، غالبًا ما تبحث في سجل الترجمة للعثور على الأخطاء.
حسنًا ، إذا فعلت شيئًا جيدًا ، فأنت بحاجة إلى نقل المشروع إلى بيئة تطوير أخرى ، وتوصيل SPI للأجهزة والعمل فقط مع السجلات ، لكن هذه قصة مختلفة تمامًا.

Source: https://habr.com/ru/post/ar392609/


All Articles