HUD 보다 낫다. 그래픽 LCD 속도계  
드디어 인두기도 디지탈로 교체했어요..  
개발자용 시리통 통신 프로그램 야~그  
▶◀ Your time is Limited  
마데 인 치나.  
똥똥이네 가족  
도트 매트릭스를 이용한 후방 메시지 표시기  
똥은 그냥 똥이다.  
유료 음원 사이트에 가입했습니다.  
카테고리
전체 (528)
궁시렁 궁시렁 (386)
튜닝/자작 (44)
읽을거리(펌) (71)
갤러리 (15)
트랙백 (7)
스크랩(비공개) (0)
이런 사업은.. (4)
방문 흔적을 남기신 분들

튜닝/자작 :: atmega128 + 도트 매트릭스 모듈 전광판 소스.2529

atmega128+LDM+winavr 전광판 소스 입니다.
글자가 좌측으로 흘러갑니다.

다른 도트 매트릭스 소스와 다른 점이 있다면 뷰 영역과 데이터 영역을 분리했습니다.
말이 어려운데 별게 아니고 도트 매트릭스에 나타낼 내용은 ViewArea 라는 배열에, 나타내고 싶은 내용은 DataArea 라는 배열에 저장됩니다.
보통은 보여주는 내용 자체가 데이터 내용이죠.

이렇게 분리하면 유리한 것이 통신 등을 통해 메시지 내용을 변경하거나 다른 조작을 하는데 있어서 편합니다.
예를 들어 내용과 무관하게 테두리를 그리거나 특정 효과를 주거나 하는 경우죠.

그리고 타이머를 이용해서 스크롤이 되도록 했습니다.

제가 사용하는 LDM은 16*32 입니다.
enable 신호와 latch 신호는 모듈별로 다를수 있기 때문에 데이터 쉬트 타이밍 차트를 참고하세요.

아래 영상 첫부분에 스크롤 되다가 다시 시작하는 것은 윈도 무비 메이커로 만들다가 잘못 들어간 겁니다. ^^


/*
표준 C       AVR GCC   byte  etc

char       int8_t    1
unsigned char    uint8_t   1
int        int16_t   2
unsigned int     uint16_t   2
long       int32_t   4
unsigned long    uint32_t   4
long long      int64_t   8
unsigned long long   uint64_t   8
        intptr_1   2   int16_t와 같음
        uintptr_t   2   uint16_t와 같음
float            4
double            8
*/

#include <avr/io.h>
#define F_CPU 16000000UL
//#include <util/delay.h>
#include <avr/interrupt.h>

uint16_t timer_flag = 0;
int8_t MessageIndex = 0;

#ifndef BV
#define BV(bit) (1<<(bit))
#endif

#ifndef cbi
#define cbi(reg,bit) reg &= ~(BV(bit))
#endif

#ifndef sbi
#define sbi(reg,bit) reg |= (BV(bit))
#endif

#define latch_high sbi(PORTB,0)
#define latch_low    cbi(PORTB,0)

#define clock_high   sbi(PORTB,1)
#define clock_low    cbi(PORTB,1)

#define green_on    sbi(PORTB,2)
#define green_off    cbi(PORTB,2)

#define red_on       sbi(PORTB,3)
#define red_off      cbi(PORTB,3)

#define enable_high  sbi(PORTB,4)
#define enable_low   cbi(PORTB,4)

//int s = 0x3d0A;  // 1초 만들기 위한 값

// A0~A3 : PORTD 0 ~ PORTD 3

int16_t DataAreaIndex, Column = 0;
int16_t MaxColumn = 320;

//unsigned int array[0][16] =
uint16_t ViewArea[2][16] =  // 16*16*2 화면에 보여지는 영역
{
   { 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000 }, // 0
   { 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000 }  // 1
};

uint16_t DataArea[20][16] =  // 16*16*20(320) 데이터 영역
{
   { 0x0000,0x3F08,0x0088,0x0088,0x008E,0x0108,0x0608,0x7808,0x0008,0x0000,0x1FF8,0x1008,0x1008,0x1008,0x0FF0,0x0000 }, // 0
   { 0x0000,0x0408,0x0408,0x0408,0x0408,0x0408,0x040E,0x0A08,0x0A08,0x1108,0x1108,0x2088,0x4048,0x4048,0x0008,0x0000 }, // 1

   { 0x0000,0x0008,0x3FE8,0x0208,0x0208,0x0508,0x0888,0x1048,0x6228,0x0208,0x0208,0x0208,0x7FE8,0x0008,0x0008,0x0000 }, // 2
   { 0x0000,0x0080,0x0140,0x0630,0x380E,0x0080,0x0080,0x3FFE,0x0000,0x03E0,0x0C18,0x1004,0x1004,0x0C18,0x03E0,0x0000 }, //

   { 0x0000,0x07F0,0x0808,0x1004,0x1004,0x1004,0x1004,0x1004,0x1004,0x1004,0x1004,0x1004,0x7C04,0x3804,0x1004,0x0000 }, //
   { 0x0000,0x1F88,0x2008,0x2008,0x3EF8,0x2008,0x2008,0x2008,0x1FC8,0x0008,0x0008,0x1000,0x1000,0x1000,0x0FF8,0x0000 }, //

   { 0x0000,0x1000,0x3000,0x7FF8,0x3004,0x1004,0x0004,0x0004,0x0004,0x0004,0x0004,0x0004,0x0004,0x0004,0x0004,0x0000 }, //
   { 0x0000,0x1000,0x3000,0x7FF8,0x3004,0x1004,0x0004,0x0004,0x0004,0x0004,0x0004,0x0004,0x0004,0x0004,0x0004,0x0000 }, //

   { 0x0000,0x0008,0x000C,0x1FFE,0x200C,0x2008,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x0000 }, //
   { 0x0000,0x0008,0x000C,0x1FFE,0x200C,0x2008,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x0000 }, //

   { 0x0000,0x0008,0x2088,0x2088,0x2088,0x2088,0x3F88,0x2088,0x2088,0x2088,0x2088,0x2088,0x1F08,0x0008,0x0008,0x0000 }, //
   { 0x0000,0x0408,0x0408,0x0408,0x0A0E,0x1108,0x2088,0x4048,0x0008,0x03C0,0x0C30,0x1008,0x1008,0x0C30,0x03C0,0x0000 }, //

   { 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000 }, // 18
   { 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000 }, // 19

   { 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000 }, // 18
   { 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000 } // 19
};

/* time delay for us */
void DelayUs(unsigned char time_us)
{
   register unsigned char i;

   for(i = 0; i < time_us; i++)   // 4 cycle +
      {
         asm volatile(" PUSH  R0 "); // 2 cycle +
         asm volatile(" POP   R0 "); // 2 cycle +

         asm volatile(" PUSH  R0 "); // 2 cycle +
         asm volatile(" POP   R0 "); // 2 cycle +

         asm volatile(" PUSH  R0 "); // 2 cycle +
         asm volatile(" POP   R0 "); // 2 cycle = 16 cycle = 1 us for 16MHz
      }
}

/* time delay for ms */
void DelayMs(unsigned int time_ms)
{
   register unsigned int i;

   for(i = 0; i < time_ms; i++)
      {
         DelayUs(250);
         DelayUs(250);
         DelayUs(250);
         DelayUs(250);
      }
}

/* time delay for s */
void DelayS(unsigned int time_s)
{
   register unsigned int i;

   for(i = 0; i < time_s; i++)
      {
         DelayMs(250);
         DelayMs(250);
         DelayMs(250);
         DelayMs(250);
      }
}

void LDM_ChangeRow(int Row)
{
   latch_low;  // 래치 출력 , 한행 display 완료.
   enable_high;
   clock_low;
   PORTD = Row;
   clock_high;
   enable_low;
}

//void LDM_print(unsigned int temp_data[9][16], int mat, int color)
void LDM_print(void)
{
   unsigned int ROW = 0;
 uint32_t font;
   int COL;

   red_off;
 green_off;

// PORTD = 0;

   //ViewArea[0][0] = Column;
   //ViewArea[0][1] = DataAreaIndex;

   // ViewArea[0][0] = PORTC;

 for (ROW = 0; ROW < 16; ROW++)
   {
      font = ViewArea[0][ROW];

      for (COL = 0; COL < 16; COL ++)
      {
         if (font & 0x8000)
         {
            green_on;
         }
         else
         {
            green_off;
         }

         font = font << 1; // 다음 도트의 데이터를 검출하기 위해 한 비트 shift

         clock_high;
         clock_low;
      }

      font = ViewArea[1][ROW];

      for (COL = 0; COL < 16; COL ++)
      {
         if (font & 0x8000)
         {
            green_on;
         }
         else
         {
            green_off;
         }

         font = font << 1; // 다음 도트의 데이터를 검출하기 위해 한 비트 shift

         clock_high;
         clock_low;
      }

      enable_high;
      latch_high;
      latch_low;
      enable_low;

      PORTD = ROW;
   }
}

void ChangeDotMatrixArray(void)
{
   int Row;

/*
   switch(MessageIndex)
   {
      case 0:
         for (Row=0;Row<16;Row++)
         {
            DotMatrix[Row]=Default[Row];
         }
         break;
      case 1:
         for (Row=0;Row<16;Row++)
         {
            DotMatrix[Row]=ThankYou[Row];
         }
         break;
      case 2:
         for (Row=0;Row<16;Row++)
         {
            DotMatrix[Row]=Sorry[Row];
         }
         break;
      case 3:
         for (Row=0;Row<16;Row++)
         {
            DotMatrix[Row]=UTurn[Row];
         }
         break;
      case 4:
         for (Row=0;Row<16;Row++)
         {
            DotMatrix[Row]=LeftTurn[Row];
         }
         break;
      case 5:
         for (Row=0;Row<16;Row++)
         {
            DotMatrix[Row]=RightTurn[Row];
         }
         break;
      case 6:
         for (Row=0;Row<16;Row++)
         {
            DotMatrix[Row]=Emergency[Row];
         }
         break;
   }
   timer_flag = 0;
*/
}

ISR(TIMER0_OVF_vect)
{
   unsigned int ROW = 0;

   //16.384msec 주기
   timer_flag++;

   if(timer_flag > 3) //16.384msec * 61 = 1초
   {
      timer_flag=0;
      // -------------------------------------------------------------------------

      DataAreaIndex =  Column / 16;
     
      if (DataAreaIndex > 21)
      {
         DataAreaIndex = 0;  
      }

      for (ROW = 0; ROW < 16; ROW++)
      {
         ViewArea[0][ROW] = ViewArea[0][ROW] << 1;

         if (ViewArea[1][ROW] & 0x8000)
         {
            ViewArea[0][ROW] = ViewArea[0][ROW] | 0x0001;
         }
        
         ViewArea[1][ROW] = ViewArea[1][ROW] << 1;

         if (DataArea[DataAreaIndex][ROW] << (Column % 16) & 0x8000)
         {
            ViewArea[1][ROW] = ViewArea[1][ROW] | 0x0001;
         }
      }

      Column ++;

      if (Column > MaxColumn)
      {
         Column = 0;  
      }

      // -------------------------------------------------------------------------
   }
}

int main(void)
{
   unsigned int ROW, temp=0;

   int scroll, color=0;

   DelayS(1);

   DDRB   = 0xFF;  // B 포트 출력
   PORTB  = 0x00;  // B 포트 출력 OFF

   DDRD   = 0xFF;  // D 포트 출력
   PORTD  = 0x00;  // D 포트 출력 OFF

   TCCR0 = 0x07;
   TIMSK = 0x01; // 16 MHz/1024/256 = 16.384msec

 SREG |= 0x80;  //전체 인터럽트 이네이블.

   DDRC   = 0x00;
   PORTC  = 0x01;

   DataAreaIndex =  0;
   Column = 0;

   while(1)
   {

      LDM_print();
   }
}

2010/12/29 19:12 2010/12/29 19:12
태그 :: , , , , ,
[ATmega128,자작,도트 매트릭스,dot matrix,avr,전광판,]와 관련된 글
트랙백 0, 댓글 4개가 달렸습니다.


받은 트랙백 트랙백 주소 :: http://www.dudals.net/trackback/3017 - 주소를 클릭하시면 자동으로 복사가 됩니다.
트랙백 RSS :: http://www.dudals.net/rss/trackback/3017
트랙백 ATOM :: http://www.dudals.net/atom/trackback/3017
달린 댓글
  1. 2011/04/12 11:53 김정원  댓글주소  수정/삭제  댓글쓰기
    전광판 제작 하면서 여기저기 다니다가 오게되었습니다..

    제가 전공이 아니라 힘들게 독학했는데요..ㅠㅠ

    실례가 안된다면 도움을 구하고 싶습니다 ㅠㅠ
    • 2011/04/14 23:44 dudals  댓글주소  수정/삭제
      네.. 궁금하신게 어떤건가요?
      저도 삽질하며 만든거라 도움이 될지 모르겠네요. ^^
  2. 2011/05/23 23:53 정병수  댓글주소  수정/삭제  댓글쓰기
    저도 도트매트릭스를 이용해서 전광판을

    만들어 보고 싶어서 글을 달아봅니다

    16x32 ldm은 시중에서 팔더군요

    궁금한건 ldm을 구동시키기 위해서

    따로 회로판을 만들어야 하는지

    그리고 atmega128과는 어떻게 연결해야 하는지

    궁금합니다 도와주세요
    • 2011/05/25 13:37 dudals  댓글주소  수정/삭제
      안녕하세요.
      ldm 이 있다면 atmega128에 별도의 회로가 추가될 것은 없습니다.
      다만 ldm이 전류 소모가 많으니 충분히 넉넉한 파워를 사용해야 합니다.
      보통 모듈당 5v 짜리 2a 정도 되니까요.
      배선은 컨트롤 라인과 어드레스 라인이 있는데 컨트롤 라인은 portb, 어드레스 라인은 portd 를 사용했습니다.
      소스 첫 부분에 보면 정의가 되어있습니다.
      이 외에 별도의 배선은 필요없습니다.
      보통 단색 ldm이면 8핀 한개의 포트만 가지고도 됩니다만 2색 이상의 ldm 은 8개핀으로는 모자랍니다.
[로그인][오픈아이디란?]








최근 트랙백

최근 댓글

최근 읽힌 게시물

태그


copyright(c) 2001-2008 www.dudals.net all rights reserved.
Designed by dudals at 2008.10.17.31.138.908756    Powered by Textcube 1.7.6 :Staccato
free counters