Busan IT/AVR 컨트롤러2015. 4. 28. 17:43

USART를 통한 데이터 전송, LCD에 사용자 지정 문자 출력

 

USART0_Init 함수의 설명(지난블로그에 소스로 올림)

 

 

USB to Serial에서 나온 신호를 그대로 ATmega에 연결하면 과전류가 흘러 MCU의 회로가 타버릴 수 있다. 시리얼 포트에는 7-12v의 전압을 신호로 보내주는데 MCU5v 신호에 맞게 설계되어 있기 때문이다.

 

RS 485Half-Duplex 통신 방식이고, RS 422Full-Duplex 통신 방식이다.

MAX 232 하나를 쓰면 반이중통신, 두 개를 쓰면 전이중통신이 가능하다.

 

//RS 422, 485에 대해 조사해 보자!

LCD에 사용자 지정 문자를 넣어 이름을 출력해보자!


 

못생겼지만 성공했다!

 

/*** 소스 코드 ***/

 

<main.c>

 

#include "SMART.h"
#include "USART.h"
#include "LCD.h"

int main(void)
{
  unsigned int uiNum;
  LCD_Init();
  LCD_INST(0x40); //CG ROM Address Set
  LCD_MYNAME();
  LCD_INST(0x80);
  LCD_Data(0x6f); //O
  LCD_INST(0x83); // 2칸 띄우기 
  LCD_Data(0x01); // ㅎ
  LCD_Data(0x02); // ㅣ 
  LCD_INST(0xC0); // 다음 줄로 이동 
  LCD_Data(0x03); // ㅠㄴ  
  LCD_Data(0xbd); //ㅈ
  LCD_Data(0x04); //ㅐ 
  LCD_Data(0x00); // ㅡ 
  LCD_Data(0x02); // ㅣ 

  
  
    
  while(1)
  {
  ;
    
  }

  
  return 0;

  
            

<SMART.h>

#ifndef __SMART_H__
#define __SMART_H__

/**** General Purpose Register A - L ****/

#define  PORTA (*((volatile unsigned char*)0x22))
#define   DDRA  (*((volatile unsigned char*)0x21))
#define   PINA  (*((volatile unsigned char*)0x20))

#define  PORTB (*((volatile unsigned char*)0x25))
#define   DDRB  (*((volatile unsigned char*)0x24))
#define   PINB  (*((volatile unsigned char*)0x23))

#define  PORTC (*((volatile unsigned char*)0x28))
#define   DDRC  (*((volatile unsigned char*)0x27))
#define   PINC  (*((volatile unsigned char*)0x26))

#define  PORTD (*((volatile unsigned char*)0x2B))
#define   DDRD  (*((volatile unsigned char*)0x2A))
#define   PIND  (*((volatile unsigned char*)0x29))

#define  PORTE (*((volatile unsigned char*)0x2E))
#define   DDRE  (*((volatile unsigned char*)0x2D))
#define   PINE  (*((volatile unsigned char*)0x2C))

#define  PORTF (*((volatile unsigned char*)0x31))
#define   DDRF  (*((volatile unsigned char*)0x30))
#define   PINF  (*((volatile unsigned char*)0x2F))

#define  PORTG (*((volatile unsigned char*)0x34))
#define   DDRG  (*((volatile unsigned char*)0x33))
#define   PING  (*((volatile unsigned char*)0x32))

#define  PORTH (*((volatile unsigned char*)0x102))
#define   DDRH  (*((volatile unsigned char*)0x101))
#define   PINH  (*((volatile unsigned char*)0x100))

#define  PORTJ (*((volatile unsigned char*)0x105))
#define   DDRJ  (*((volatile unsigned char*)0x104))
#define   PINJ  (*((volatile unsigned char*)0x103))

#define  PORTK (*((volatile unsigned char*)0x108))
#define   DDRK  (*((volatile unsigned char*)0x107))
#define   PINK  (*((volatile unsigned char*)0x106))

#define  PORTL (*((volatile unsigned char*)0x10B))
#define   DDRL  (*((volatile unsigned char*)0x10A))
#define   PINL  (*((volatile unsigned char*)0x109))


/* 인터럽트 사용을 위한 레지스터 */

#define EICRA (*((volatile unsigned char*)0x69))
#define EICRB (*((volatile unsigned char*)0x6A))
#define EIMSK (*((volatile unsigned char*)0x3D))
#define EIFR  (*((volatile unsigned char*)0x3C))
#define SREG (*((volatile unsigned char*)0x5F)) 

/* PCINT 사용을 위한 레지스터 */

#define PCICR (*((volatile unsigned char*)0x68))
#define PCIFR (*((volatile unsigned char*)0x3B))
#define PCMSK2 (*((volatile unsigned char*)0x6D))
#define PCMSK1 (*((volatile unsigned char*)0x6C))
#define PCMSK0 (*((volatile unsigned char*)0x6B))

/* 타이머 오버 플로우 */

// General Timer/counter Control Register
#define GTCCR (*((volatile unsigned char*)0x43)) 

// Register for Timer/Counter 0
#define OCR0A   (*((volatile unsigned char*)0x47)) // 타이머 카운터 비교 레지스터
#define OCR0B   (*((volatile unsigned char*)0x48))
#define TCCR0A   (*((volatile unsigned char*)0x44))
#define TCCR0B   (*((volatile unsigned char*)0x45))
#define TCNT0   (*((volatile unsigned char*)0x46))
#define TIFR0   (*((volatile unsigned char*)0x35))
#define TIMSK0   (*((volatile unsigned char*)0x6E))

/* USART */
#define   UCSR0A  (*((volatile unsigned char*)0xC0))
#define   UCSR0B  (*((volatile unsigned char*)0xC1))
#define   UCSR0C  (*((volatile unsigned char*)0xC2))
#define  UCSR1A  (*((volatile unsigned char*)0xC8))
#define  UCSR1B  (*((volatile unsigned char*)0xC9))
#define  UCSR1C  (*((volatile unsigned char*)0xCA))

#define   UBRR0H  (*((volatile unsigned char*)0xC5))
#define   UBRR0L  (*((volatile unsigned char*)0xC4))
#define  UBRR1H  (*((volatile unsigned char*)0xCD))
#define  UBRR1L  (*((volatile unsigned char*)0xCC))

#define   UDR0  (*((volatile unsigned char*)0xC6))
#define  UDR1  (*((volatile unsigned char*)0xCE))


// UCSR0A 레지스터
#define  RXC    7
#define  TXC    6
#define  UDRE  5
#define  FE    4
#define  DOR    3
#define  UPE    2
#define  U2X   1
#define  MPCM   0

// UCSR0B 레지스터
#define  RXCIE  7
#define  TXCIE  6
#define  UDRIE  5
#define  RXEN  4
#define  TXEN  3
#define  UCSZ2  2
#define  RXB8   1
#define  TXB8   0

// UCSR0C 레지스터
#define  UMSEL  6
#define  UPM1  5
#define  UPM0  4
#define  USBS  3
#define  UCSZ1  2
#define  UCSZ0   1
#define  UCPOL   0



/* CPU 동작시간을 맞춰주기 위한 Dealy문과 값 지정 */

#define  Delay(x)    for(uiCnt=0; uiCnt<(dNum1); ++uiCnt)

#define  dNum1 500
#define  dNum2 300000
#define  dNum3 10000000

/* 함수의 원형 */
unsigned char RX0_scan(void);
unsigned char RX0_char(void);
void TX0_char(unsigned char);
void TX0_string(unsigned char *);



#endif //__SMART_H__

 

<LCD.h>

 

#ifndef __LCD_H__
#define __LCD_H__

#include "SMART.H"

#define  LCD_BUS  PORTC
#define  LCD_CTL    PORTG

#define  LCD_BUS_DDR  DDRC
#define  LCD_CTL_DDR  DDRG

#define  LCD_PIN_RS  0 
#define  LCD_PIN_RW  1
#define  LCD_PIN_EN  2

#define  LCD_INST_CLR  0x01 //화면 지우기
#define  LCD_INST_HOME  0x02 //커서 홈
#define  LCD_INST_ENT  0x06 //Increase mode(I/D=1), 쉬프트 ON(S=0)
#define  LCD_INST_DSP  0x0//화면 보이게(1), 커서표시(1),  커서(깜빡 거림)
#define  LCD_INST_CUR  0x14 // 
#define  LCD_INST_FUNC  0x38 




void LCD_AVR_PIN_INIT(void);
void LCD_INST(unsigned char ucInst);
void LCD_Data(unsigned char ucData);
void LCD_Init(void);
void LCD_PRINT(const unsigned char * ucString);
void USART0_INIT(void);
void USART1_INIT(void);
void INIT(void);
void USART0_TX( unsigned char ucData );
void USART1_TX( unsigned char ucData );
void TEST_LCD(void);
void LCD_SetAddr(unsigned char);
void LCD_MYNAME(void);
void LCD_CGRom_Read(unsigned char);
void LCD_CGRom_Write(unsigned char);


#endif //__LCD_H__

<LCD.c>

#include "LCD.h"
#include "USART.h"
#include "SMART.h"

//Wide variable
static unsigned int uiCharCnt;



// LCD driver 프로그램 작성

void LCD_AVR_PIN_INIT(void)
{
  LCD_BUS_DDR = 0xFF;
  LCD_CTL_DDR = (1<<LCD_PIN_RS) |  (1<<LCD_PIN_RW) | (1<< LCD_PIN_EN); // == 0x07
  
  
  return;
}

void LCD_INST(unsigned char ucInst)

{
  volatile unsigned int uiCnt;
  
  LCD_BUS=ucInst;

  LCD_CTL = (0<<LCD_PIN_RS) | (0<<LCD_PIN_RW) | (0<< LCD_PIN_EN); // == 0x00 DC 영역

  Delay(500); //40ns 지연

  LCD_CTL = (0<<LCD_PIN_RS) |  (0<<LCD_PIN_RW) | (1<< LCD_PIN_EN); // == 0x01

  
  Delay(500); //4//Tw(230)- Tsu2(80) = 150ns 지연 


  LCD_CTL = (0<<LCD_PIN_RS) |  (0<<LCD_PIN_RW) | (0<< LCD_PIN_EN); // == 0x00 DC 영역

  Delay(500); //40ns 지연

}


void LCD_Data(unsigned char ucData)

{
  volatile unsigned int uiCnt;

  LCD_BUS=ucData;

  LCD_CTL = (1<<LCD_PIN_RS) |  (0<<LCD_PIN_RW) | (0<< LCD_PIN_EN); // == 0x00 DC 영역

  Delay(500); //40ns 지연

  LCD_CTL = (1<<LCD_PIN_RS) |  (0<<LCD_PIN_RW) | (1<< LCD_PIN_EN); // == 0x01

  
  Delay(500); //4//Tw(230)- Tsu2(80) = 150ns 지연 

  LCD_CTL = (1<<LCD_PIN_RS) |  (0<<LCD_PIN_RW) | (0<< LCD_PIN_EN);

  Delay(500); //4//10ns 지연

}

void LCD_Init(void)
  
{
  
  
  volatile unsigned int uiCnt;

  LCD_AVR_PIN_INIT();

  Delay(500); // ATmega가 LCD보다 구동이 먼저 되는 경우를 대비하여 넣어주는 딜레이 코드  

  LCD_INST(LCD_INST_FUNC);
  LCD_INST(LCD_INST_DSP);
  LCD_INST(LCD_INST_ENT);
  LCD_INST(LCD_INST_CUR);
  LCD_INST(LCD_INST_CLR);
  LCD_INST(LCD_INST_HOME);

  uiCharCnt = 0;
  

  return;
}

void LCD_PRINT(const unsigned char * ucString)
{
  for(;*ucString != 0; ++ucString)
  {
    LCD_Data(*ucString);
    
  }
  
  return
}

void LCD_SetAddr(unsigned char ucAddr)
{
  if(ucAddr>15)
  {
    if(ucAddr<40)
    {
      ucAddr = 40;
    }  
    else if(ucAddr>55)
    {
      ucAddr = 0;

    }
  }
  
  

  LCD_INST(0x80|ucAddr);
  
}

void LCD_CGRom_Write(unsigned char ucInst)

{
  volatile unsigned int uiCnt;
  
  LCD_BUS=ucInst;

  LCD_CTL = (0<<LCD_PIN_RS) | (0<<LCD_PIN_RW) | (0<< LCD_PIN_EN); // == 0x00 DC 영역

  Delay(500); //40ns 지연

  LCD_CTL = (1<<LCD_PIN_RS) |  (0<<LCD_PIN_RW) | (1<< LCD_PIN_EN); // == 0x01

  
  Delay(500); //4//Tw(230)- Tsu2(80) = 150ns 지연 


  LCD_CTL = (0<<LCD_PIN_RS) |  (0<<LCD_PIN_RW) | (0<< LCD_PIN_EN); // == 0x00 DC 영역

  Delay(500); //40ns 지연

}
void LCD_CGRom_Read(unsigned char ucInst)

{
  volatile unsigned int uiCnt;
  
  LCD_BUS=ucInst;

  LCD_CTL = (0<<LCD_PIN_RS) | (0<<LCD_PIN_RW) | (0<< LCD_PIN_EN); // == 0x00 DC 영역

  Delay(500); //40ns 지연

  LCD_CTL = (1<<LCD_PIN_RS) |  (1<<LCD_PIN_RW) | (1<< LCD_PIN_EN); // == 0x01

  
  Delay(500); //4//Tw(230)- Tsu2(80) = 150ns 지연 


  LCD_CTL = (0<<LCD_PIN_RS) |  (0<<LCD_PIN_RW) | (0<< LCD_PIN_EN); // == 0x00 DC 영역

  Delay(500); //40ns 지연
}


void LCD_MYNAME(void)
{
  volatile unsigned int vuiCnt;
  unsigned char font[] =
  {
      0x0A, 0x040x000x000x000x000x1F, 0x00,  // 0.second char ㅡ  
      0x0E, 0x000x1f, 0x000x040x0a, 0x0a, 0x04,  // 1. forth char ㅎ 
      0x100x100x100x100x100x100x100x10,  // 2. fifth char ㅣ
      0x1F, 0x0A, 0x0A, 0x0A, 0x000x100x1F, 0x00,  // 3. sixth char ㅠㄴ 
      0x120x120x1E, 0x120x120x120x000x00,  // 4. eighth char ㅐ
      0x040x0A, 0x110x0A, 0x040x000x1F, 0x00,  // 5. nineth char ㅇ ㅡ
  
  };
  for(vuiCnt=0; vuiCnt<42; ++vuiCnt)
    LCD_Data(font[vuiCnt]);
    
}

 

 

 

 

 

 

반응형
Posted by newind2000