Как написать функцию задержки на ассемблере для Atmega 328p Microcontroller, присутствующего в Arduino? - PullRequest
0 голосов
/ 12 июня 2018

Я очень новичок в программе на языке ассемблера, я пытаюсь запрограммировать Atmel 328P на мигание светодиода на выводе 13, но мигание светодиода слишком быстрое, я не могу сделать различий между включением и выключением светодиода, который выглядиткак на все время, поэтому я пытаюсь создать функцию задержки так, чтобы она мигала с задержкой в ​​1 секунду, как я могу это сделать, моя программа такая, как показано ниже

word millisecs; 
void setup() 
{

  asm volatile(
    "          ldi r16,0x3F    ; r16 = 00111111\n"
    "          out 4,r16       ; set pins 8-13 as outputs in DDRB\n"
    ::: "r16");
  millisecs = 1000;            // 1s blink delay
  Serial.begin(9600);
}
void loop() 
{
  long starttime = millis();        // make a note of the start time

    asm volatile(
    "            rjmp  blink%=        ; relative jump to 'blink' \n"

    /* Input variable - millisecond count in register pair r30:r31

    registers used:
     r31 - millisecond count (lo byte)
     r30 - millisecond count (hi byte)
     r17 - 100 microsecond count
     r16 - 1 microsecond count

     Overall delay (ms) = r30:r31 * r17 * r16
    ---------------------------------------------------------------------*/
    "delay_ms%=:     nop "
    "delay_100us%=: nop  "
    "delay_1us%=:   nop  "
    "             sbiw r30,1 ; decrement ms count (r31:r30)\n"
    "             brne delay_ms%=  ; loop to delay_ms while > 0  \n"
    "              ret          ; return from subroutine      \n "


    " blink%=:                               ; start of blink code    \n"
    //
    // turn onboard LED on
    //   
    "               ldi  r18,0x20            ; bit 5 (pin 13) = high  \n"
    "               out  5,r18               ; output to port B       \n"
    //
    // delay by value in millisecs variable
    //
    "               lds  r30,millisecs      ; r30 = hi byte           \n"
    "               lds  r31,millisecs + 1  ; r31 = lo byte           \n"
    "               call delay_ms%=         ; call millisec delay sub \n"
    //
    // turn onboard LED off
    // 
    "               ldi  r18,0x00           ; value for all LEDs off  \n"
    "               out  5,r18              ; output to port B        \n"
    //
    // delay by value in millisecs variable
    //
    "               lds  r30,millisecs      ; r30 = hi byte           \n"
    "               lds  r31,millisecs + 1  ; r31 = lo byte           \n"
    "               call delay_ms%=         ; call millisec delay sub \n"

    ::: "r16", "r17", "r18", "r30", "r31");    // clobbered registers

  //--------------------------------------------------------------------------------
  // calculate the execution time of the blink routine, and print details 
  long endtime = millis();                  // make a note of the end time
  float ms = endtime-starttime;             // calculate the interval
  float expected = 2 * millisecs;           // expected delay is millisecs * 2 (2 delays in blink)
  float overheads = 17;                     // overheads due to the timing
  expected = expected + overheads;   
  float error_percent = 100.0*(ms-expected)/expected;
  Serial.print("delay="); Serial.print(ms); Serial.print("ms  "); 
  Serial.print("error: ");
  if(error_percent>0)
    Serial.print("+");
  Serial.print(error_percent);Serial.println("%");
}

Я пытаюсьчтобы создать 3 разных экземпляра задержек, я обозначил delay_ms% = :, delay_100us% =: и delay_1us% = :.Детали, относящиеся к используемым регистрам, я упоминал в комментариях. Кроме того, я рассчитываю время выполнения процедуры мигания и процент ошибок, чтобы отображаемая ошибка оставалась менее 1%, как показано ниже

delay=1.00ms  error: -99.95%
delay=0.00ms  error: -100.00%
delay=1.00ms  error: -99.95%
delay=1.00ms  error: -99.95%
delay=1.00ms  error: -99.95%
delay=1.00ms  error: -99.95%
delay=1.00ms  error: -99.95%
delay=1.00ms  error: -99.95%
delay=2.00ms  error: -99.90%

Так какя могу это сделать?Пожалуйста, спросите меня, если у вас есть какие-либо вопросы

...