2024年3月16日土曜日

usart on atmega88/328

2進化10進のコードが難解なのでTをいれたら0,それ以外をいれたらXが返るようにした

;; USART.ASM RX/TX :: TERATERM 2400BAUD SUCCESS!

.include "m88def.inc"

.def STACK = R16

.def R_TEMP1 = R17

.def R_TEMP2 = R18

.def R_TEMP3 = R19

.EQU P_SW0 = PINC  ;SW0

.CSEG 

RJMP MAIN

;;---------------------------

;;  USART SEND ROUTINE

;;-----------------------

UARTS:

LDS R_TEMP1,UCSR0A

SBRS R_TEMP1,UDRE0

RJMP UARTS

STS UDR0,R_TEMP3 ; R_TEMP3 VAL SETUP IN MAIN ROUTINE

RET

; --------------- MAIN ROUTINE ---------------------

MAIN:

CLI

LDI R_TEMP1,0b11110000

LDI R_TEMP2,0b00001111

OUT DDRC,R_TEMP1

OUT PORTC,R_TEMP2

   

; -- USART INIT

LDI R_TEMP1,25 

STS UBRR0L,R_TEMP1

LDI R_TEMP1,0

STS UBRR0H,R_TEMP1 ; BAUD RATE 2400

LDS R_TEMP1,UCSR0C

SBR R_TEMP1,((1<<UCSZ01)+(1<<UCSZ00)) 

STS UCSR0C,R_TEMP1 ; NO-PARI/1STOP/8BIT-LEN

LDS R_TEMP1,UCSR0B

SBR R_TEMP1,((1<<RXEN0)+(1<<TXEN0)) 

STS UCSR0B,R_TEMP1 ; TX/RX ENABLE

SEI

MAIN01:

LDS R_TEMP1,UCSR0A ; 1 CHAR RECV

SBRS R_TEMP1,RXC0

RJMP MAIN01

LDS R_TEMP3,UDR0 ; RECV BUFFER IS EMPTY

CPI R_TEMP3,'T'

BRNE MAIN10 ; IF NOT T,GOTO MAIN10

;IN R_TEMP3,P_SW0  ;IF T, UNUSED BITS MASKING

;ANDI R_TEMP3,0x0F

;LDI R_TEMP1,0x0F

;EOR R_TEMP3,R_TEMP1 ; REAL CODE -> COMPLEMENTARY CODE CONV

LDI R_TEMP3,0x00

LDI R_TEMP1,0x30

ADD R_TEMP3,R_TEMP1

MAIN02:

RCALL UARTS ; CONVERTED CHAR SEND TO PC

RJMP MAIN01

MAIN10:

LDI R_TEMP3,'X'

RJMP MAIN02

ーーーーーーーーーーーATMEGA88 SEND TO PC ---------------------------- 

以下のコードはinoにしてarduinoIDEは通らんかったのでcにしてmicrochip studioで成功

#include <stdint.h>

#include <avr/io.h>

#include <util/delay.h>

#define F_CPU 1000000UL いらんかも。。。

// +-----------------------------------------------------------------------+ //

// | ATmega328p Baudrate calc is as below を88に変更

// +--https://qiita.com/k_match/items/c99d25adf6b1a984061f

//---------------------------------------------------------------------+ //

#define BAUD_RATE_2400_BPS  25 // 2400bps

// +-----------------------------------------------------------------------+ //

int main()

{

  int i = 0;

  unsigned int ubrr = BAUD_RATE_2400_BPS;

  unsigned char data[] = "Hello from ATmega88  ";

  /* Set Baudrate  */

  UBRR0H = (ubrr>>8);

 // Shift the 16bit value ubrr 8 times to the right and

//  transfer the upper 8 bits to UBBR0H register.

  UBRR0L = (ubrr);   

 // Copy the 16 bit value ubrr to the 8 bit UBBR0L register,

// Upper 8 bits are truncated while lower 8 bits are copied

  UCSR0C = 0x06;       /* Set frame format: 8data, 1stop bit  */

  UCSR0B = (1<<TXEN0); /* Enable  transmitter                 */

  while(1) /* Loop the messsage continously */

  {

    i = 0;

    while(data[i] != 0) /* print the String  "Hello from ATmega328p" */

    {

      while (!( UCSR0A & (1<<UDRE0))); /* Wait for empty transmit buffer       */

      /* When UDRE0 = 0,data transmisson ongoing.                         */

      /* So NOT{[UCSR0A & (1<<UDRE0)] = 0} = 1 ,While(1) loop stays there */

      /* When UDRE0 = 1,data transmisson completed.                       */

      /* So NOT{[UCSR0A & (1<<UDRE0)] = 1} = 0 ,While(0) loop fails       */

      UDR0 = data[i];          /* Put data into buffer, sends the data */

      i++;                             /* increment counter                    */

    }

    /* Sending '\n'  '\r' Character pair helps to format the output properly on console putty Screen */

    /*************************************************************/

    /* Send "\n" Character */

    while (!( UCSR0A & (1<<UDRE0)));   /* Wait for empty transmit buffer       */

    UDR0 = '\n';              /* Put data into buffer, sends the data */

    /* Send "\r" Character */

    while (!( UCSR0A & (1<<UDRE0)));   /* Wait for empty transmit buffer       */

    UDR0 = '\r';              /* Put data into buffer, sends the data */

    /*---------------------------------------------------------------------------*/

    _delay_ms(100);

  }

}

--------FROM PC TO ATMEGA328P 8MHZ ----これはテラタームから動かせたが-----------
void setup() { 
  Serial.begin(9600); 
void loop() { 
  if(Serial.available() > 0) { 
    int data = Serial.read(); 
    Serial.println(data,HEX); 
    if (data==0X61)
    digitalWrite(LED_BUILTIN,HIGH);
    delay(500);
    digitalWrite(LED_BUILTIN,LOW);
  } 
----------PC TO ATMEGA328P 8MHZ ------本命成功---------------------------------------
以下をinoで保存しarduinoIDEでコンパイル arduinoUNOに空コードを書き込み
rx/txをクロスせずにつないでarduinoIDEで9600ボーにして
改行なしでAをいれるとLEDついた! もちろんTERATERMでも動いた!
// External Oscillator = 11.0592MHz -> Internal 8mhzに変更
// Controller ATmega328p 
//| Compiler           : AVR GCC (WinAVR)                                                          |
//| Microcontroller    : ATmega328p                                                                |

#include <stdint.h>
#include <avr/io.h>
#include <util/delay.h>
#define F_CPU 8000000UL
#define BAUD_RATE_9600_BPS  51  // 9600bps for 8mhz
// +-----------------------------------------------------------------------+ //

int main()
{
unsigned int ubrr = BAUD_RATE_9600_BPS;
PORTC = 0x00; //All LED's OFF
PORTD = 0x00;
/* Set Baudrate @ 230.4k bps */
UBRR0H = (ubrr>>8);
UBRR0L = (ubrr);
/*Enable receiver  */
UCSR0B = (1<<RXEN0);
/* Set frame format: 8data, 1stop bit */
UCSR0C = 0x06;
DDRC  |= (1<<PC4); // Blinks LED
PORTC |= (1<<PC4);
_delay_ms(500);
PORTC &= ~(1<<PC4); // LEDの試運転コード
while(1)
{
while ( !(UCSR0A & (1<<RXC0)) ); /* Wait for data to be received */
     // using the switch() statement to  control the LED and Buzzer
switch(UDR0) 
{
case 'A' : DDRC  |= (1<<PC4); // Blinks LED
PORTC |= (1<<PC4);
_delay_ms(500);
PORTC &= ~(1<<PC4);
break;
case 'B' : DDRC  |= (1<<PC5); // Beeps Buzzer
PORTC |= (1<<PC5);
_delay_ms(500);
PORTC &= ~(1<<PC5);
break;
default  :
break;
}//end of Switch()
}//end of While(1)
}//end of main

0 件のコメント:

コメントを投稿