Microprocessor/ARM7 ARM7 자료 ( ADC 컨버터 / 광센서 / 캐릭터 LCD / LED / Thread )
  • 728x90
    반응형

     

     

     ADC 컨버터 를 이용하여 캐릭터 LCD에 값 출력

     

     

     


    광센서를 AD7에 연결하고 반대쪽은 그라운드에 연결하였다. 


    LED는 14핀에 그라운드를 연결하고 반대쪽은 3.3v 에 연결

     

    광센서의 최대값은 1023으로 설정 


    캐릭터 LCD 는 실시간으로 광센서의 빛의 밝기를 출력한다. 


    밝은 빛을 비추면 최대값인 1023을 출력한다. 


    LED는 광센서값이 700이하이면 꺼지도록 하였다. (어두우면 꺼짐) 


     

    Ex) main.c

    #include "arm.h"
    #include "led.h"
    #include "aic.h"
    #include "ultra.h"
    #include "lcd.h"
    #include "dbgu.h"
    #include "adc.h"

    void Init(void);    

    int main()
    {
      
    volatile unsigned int dly;
      
    unsigned char buff[] = "[1023]";
      
    unsigned int UI_val;
      
      Init();  

      
    while(1)
      {
        UI_val = ADC_Run();
        
        buff[1= '0' + (UI_val/1000);      // 1023 
     1 추출 
        buff[2= '0' + ((UI_val%1000)/100);    // 1023 
     0 추출 
        buff[3= '0' + ((UI_val%100)/10);    // 1023 
     2 추출
        buff[4= '0' + (UI_val%10);        // 1023 
     3 추출

        LCD_Position(00);
        LCD_String(buff);
        EMB_delay(100000);

        
    if(UI_val > 700)
        {
          PIO_CODR = 1 <<  LED_Pin;
        
        }
        
    else
        {
          PIO_SODR = 1 <<  LED_Pin;
        }  
      }

      
    while(1);
      
    return 0;
    }


    void Init(void)
    {    
      Init_LED();
      init_LCD();
      Init_ADC();
      
      
    return ;
    }

     

      

    Ex) LED

     

    #define LED_Pin    14  // LED Pin Number

     

    void Init_LED(void)
    {
      PMC_PCER = 1 << PIOA;      
      PIO_OWER = 1 << LED_Pin;
      PIO_PER  = 1 << LED_Pin;
      PIO_OER   = 1 << LED_Pin;
      PIO_SODR = 1 <<  LED_Pin;
      
      
    return ;
    }

     

     

    Ex) LCD

     

    #define    LCD_RS    (1<<29)
    #define    LCD_RW    (1<<30)
    #define    LCD_EN    (1<<31)
    #define    LCD_BS    0x00FF0000
    #define    LCD_ALL    (LCD_RS | LCD_RW | LCD_EN | LCD_BS)
    #define    RETURN_Home  0x02
    /*    LCD 
    데이터 버스 메크로    */
    #define    LCD_DB(x)  ((x)<<(16))

     

    #define    LCD_Delay1      510
    #define    LCD_Delay2      510
    #define    LCD_Delay3      510

    #define    Function_set    0x38    //   Function set
    #define    Entry_Mode      0x06    //  Entry Mode  
    #define    Cursor_Dis      0x1C    //  Cursor or display shift  
    #define    Display_on_off    0x0C    //   Display on/off  
    #define    Clear_Dis      0x01    //  Clear  


    void init_LCD(void)
    {
      PMC_PCER = 1 << PIOA;     
      PIO_OWER = LCD_ALL;    // I/O 
    기능 선택
      PIO_PER  = LCD_ALL;    // pin 
    활성화
      PIO_OER  =  LCD_ALL;    // IO 
    출력 기능 활성화

      LCD_Init();

      
    return ;
    }

     

    void LCD_Init(void)
    {
      LCD_inst(Function_set);
      LCD_inst(Entry_Mode);
      LCD_inst(Cursor_Dis);
      LCD_inst(Display_on_off);
      LCD_inst(Clear_Dis);
      LCD_inst(RETURN_Home);

      
    return;
    }

     

    void LCD_inst(unsigned char UC_inst)
    {
      
    volatile unsigned int dly;
      PIO_CODR = LCD_ALL;        // LCD_ALL 
     Low  변환 한다.
      PIO_SODR = LCD_EN;        // LCD_EN(E)
     Hight 엣지상태로 만든다.
      EMB_delay(LCD_Delay1);
      PIO_SODR = LCD_DB(UC_inst);    

      EMB_delay(LCD_Delay2);        // t_AS : 40 ns min 정도의 시간을 번다.
      PIO_CODR = LCD_EN;        // LCD_ALL 
     Low  변환 한다.

      EMB_delay(LCD_Delay3);

      
    return ;
    }

     


    Ex) ADC

     

    #define ADC_CR      *((volatile unsigned int *)0xFFFD8000)
    #define ADC_MR      *((volatile unsigned int *)0xFFFD8004)
    #define ADC_CHER    *((volatile unsigned int *)0xFFFD8010)
    #define ADC_CHDR    *((volatile unsigned int *)0xFFFD8014)
    #define ADC_CHSR    *((volatile unsigned int *)0xFFFD8018)
    #define ADC_SR      *((volatile unsigned int *)0xFFFD801C)
    #define ADC_LCDR    *((volatile unsigned int *)0xFFFD8020)
    #define ADC_IER      *((volatile unsigned int *)0xFFFD8024)
    #define ADC_IDR      *((volatile unsigned int *)0xFFFD8028)
    #define ADC_IMR      *((volatile unsigned int *)0xFFFD802C)
    #define ADC_CDR0    *((volatile unsigned int *)0xFFFD8030)
    #define ADC_CDR1    *((volatile unsigned int *)0xFFFD8034)
    #define ADC_CDR2    *((volatile unsigned int *)0xFFFD8038)
    #define ADC_CDR3    *((volatile unsigned int *)0xFFFD803C)
    #define ADC_CDR4    *((volatile unsigned int *)0xFFFD8040)
    #define ADC_CDR5    *((volatile unsigned int *)0xFFFD8044)
    #define ADC_CDR6    *((volatile unsigned int *)0xFFFD8048)
    #define ADC_CDR7    *((volatile unsigned int *)0xFFFD804C)
    //=================================================================
    #define  ADC_ID    4  // ADC 
    활성 ID ( 기본적으로 켜져있다. )
    #define SWRST    0  // Software  Reset
    #define  START    1  // Start Conversion( 
    변환 >
    #define CH7      7  // 7
     체널 

    //[ ADC Mode Register ]============================================
    #define TRGEN    0
    #define TRGSEL    0
    #define LOWRES    4
    #define SLEEP    5
    #define PRESCAL    8
    #define STARTUP    16
    #define SHTIM    24
    //[ ADC_SR ]=======================================================
    #define EOC7    7
    #define DRDY    16
    //[ ADC_LCDR ]=====================================================
    #define LDATA    0

     

     

    void Init_ADC(void)
    {  
      PMC_PCER = 1 << ADC_ID;        // PIOA ON : by PMC
      ADC_CR = 0x01;        
      ADC_CHER = 1 << CH7;         // 7
     체널 Enable
      ADC_MR = (5 << PRESCAL)|(LOWRES);  // 4MHz : 10bit reg
      
    return ;
    }

    //< ADC_CR Start >=================================================
    unsigned int ADC_Run(void)
    {
      ADC_CR = 1 << START;
      
    while(0 == (ADC_SR & (1<<DRDY)));    // DRDY 
     1 추출 
    //  while(0 == ADC_SR & (1<<EOC7));    // EOC7 
     1 추출

      
      
    return (ADC_LCDR&0x000003FF);    // 10bit 
    이외의 미정값추출 
    //  return (ADC_CDR7&0x000003FF);    // 10bit 
    이외의 미정값추출 
    }

     


     

    < 실행 결과 동영상 참고 >




    ★ DOS 에서 하이퍼터미널 대체 프로그램 만들기  

     

    Ex) main.c

    #include "arm.h"
    #include "led.h"
    #include "aic.h"
    #include "ultra.h"
    #include "lcd.h"
    #include "dbgu.h"
    #include "adc.h"

    void Init(void);    

    int main()
    {
      unsigned char UC_char;

      
      Init();
      while(1)
      {
        UC_char = DBGU_Rchar ();  
        LCD_data(UC_char);
      }
      
      while(1);
      return 0;
    }


    void Init(void)
    {    
      init_LCD();
      Init_DBGU();
      
      return ;
    }

     

     

    Ex) Dos에서 만든 하이퍼 터미널

    #include <windows.h>
    #include <stdio.h>

    int main()
    {
      HANDLE hComm;
      char CA_string[] = "Hello";
      DWORD DW_write;
      DCB sPS;      // 
    씨리얼 포트 상태 저장
      COMMTIMEOUTS cTime;
      volatile unsigned int dly = 0;
      volatile unsigned int cnt = 0;

      // CreateFile = File open 
    함수와 같다. COM1 컴포트1 열린다.
      hComm = CreateFile("COM1", GENERIC_READ | GENERIC_WRITE, 0, NULL,
              OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
      
      if(INVALID_HANDLE_VALUE == hComm)
      {
        printf("Com port open Error !\n");
        return 0;
      }

      
      // 
    버퍼 설정
      if0 == SetupComm(hComm, 40964096))
      {
        printf("Buffer setting Error !\n");
        CloseHandle(hComm);  
        return 0;
      }

      /* 
       * 
    포트 초기화
       * DCB 
    구조체 사용
       * 
    길이
       * 
    속도
       */

      if0 == PurgeComm(hComm, PURGE_TXABORT | PURGE_TXCLEAR))
      {
        printf("Buffer initialization Error !\n");
        CloseHandle(hComm);  
        return 0;
      }

      sPS.DCBlength = sizeof(sPS);

      if0 == GetCommState(hComm, &sPS))
      {
        printf("Port status read Error !\n");
        CloseHandle(hComm);  
        return 0;
      }

      sPS.BaudRate = CBR_115200;  // 
    비트,
      sPS.ByteSize = 8;      // 
    데이터 비트 전송
      sPS.Parity   = EVENPARITY;  // 
    짝수
      sPS.StopBits = ONESTOPBIT;  // 
    정지 비트
      

      // 
     세팅값을 핸들에 넣어준다.
      if0 == SetCommState(hComm, &sPS))
      {
        printf("Port status write Error !\n");
        CloseHandle(hComm);  
        return 0;
      }

      while(1)
      {
        for(dly =0; dly < 10000000 ; dly++);
      
        WriteFile(hComm, &CA_string[cnt], sizeof(CA_string[cnt]), &DW_write, 0);
        cnt++;
        if(cnt == 5)
        {
          break;
        }
      }

      

      printf("Com port open Success !\n");
      CloseHandle(hComm);      // 
    터미널은 닫아주어야한다.

      return 0;
    }

     

     딜레이를 꼭 해줘야함 !!!

     


     

    ★ Thread 

     


    Thread 는 정보와 Stack 영역만 존재한다.

     

    시분할 시스템 :: P1(0.01) -> P2(0.01) -> T1(0.01) 다시 P1으로 돌아가서 계속 반복 


    Thread 는 Procces 에 종속된다.

     

    Thread를 사용하면 멀티태스킹이 가능한 프로그램을 만들 수 있다. 


    Thread 를 만들어주는 함수는 다음과 같다.


        CreateThread( );    

     

    하이퍼터미널은 COM2 포트를 사용하였고 프로그램에서는 COM5 포트를 사용하였다.


     

    Ex) Thread 를 이용한 하이퍼 터미널 송/수신

     

    #include <windows.h>
    #include <stdio.h>

    DWORD WINAPI Thread_Read(LPVOID);



    HANDLE hComm;

    int main()
    {
      HANDLE hThread;
      
    char CA_string[] = "Hello";
      DWORD DW_write;
      DWORD Thread_ID;
      DCB sPS;      // 
    씨리얼 포트 상태 저장
      COMMTIMEOUTS cTime;
      
    volatile unsigned int dly = 0;


      // CreateFile = File open 
    함수와 같다. COM1 컴포트1 열린다.
      hComm = CreateFile("COM5", GENERIC_READ | GENERIC_WRITE, 0, NULL,
              OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
      
      
    if(INVALID_HANDLE_VALUE == hComm)
      {
        printf("Com port open Error !\n");
        
    return 0;
      }

      
      // 
    버퍼 설정
      
    if0 == SetupComm(hComm, 40964096))
      {
        printf("Buffer setting Error !\n");
        CloseHandle(hComm);  
        
    return 0;
      }

      /* 
       * 
    포트 초기화
       * DCB 
    구조체 사용
       * 
    길이
       * 
    속도
       */

      
    if0 == PurgeComm(hComm, PURGE_TXABORT | PURGE_TXCLEAR))
      {
        printf("Buffer initialization Error !\n");
        CloseHandle(hComm);  
        
    return 0;
      }

      sPS.DCBlength = 
    sizeof(sPS);

      
    if0 == GetCommState(hComm, &sPS))
      {
        printf("Port status read Error !\n");
        CloseHandle(hComm);  
        
    return 0;
      }

      sPS.BaudRate = CBR_115200;  // 
    비트,
      sPS.ByteSize = 8;      // 
    데이터 비트 전송
      sPS.Parity   = EVENPARITY;  // 
    짝수
      sPS.StopBits = ONESTOPBIT;  // 
    정지 비트

      
      memset(&cTime, 0x00
    sizeof(cTime));
      cTime.ReadIntervalTimeout = MAXDWORD;  // 
    블럭킹
      SetCommTimeouts(hComm, &cTime);

      // 
     세팅값을 핸들에 넣어준다.

      
    if0 == SetCommState(hComm, &sPS))
      {
        printf("Port status write Error !\n");
        CloseHandle(hComm);  
        
    return 0;
      }
      
      hThread = CreateThread(NULL, 0, Thread_Read, NULL, 0&Thread_ID);  // 
    쓰레드 생성

      
    while(1)
      {
        CA_string[0= getche();
        WriteFile(hComm, CA_string, 1&DW_write, 0);
        
    if( CA_string[0== '*')
        {
          
    break;
        }
      }
      
      printf("Com port open Success !\n");
      CloseHandle(hComm);      // 
    터미널은 닫아주어야한다.

      
    return 0;
    }

    //< Thread 
    함수 호출 >
    DWORD WINAPI Thread_Read(LPVOID temp)
    {
      
    char cText;
      DWORD DW_read;
      
    volatile unsigned int cnt = 0;
      
    while(1)
      {
        Sleep(50);  // CPU 
    점유율을 줄이기 위함
        ReadFile(hComm, &cText, 1&DW_read, 0);
        
    if(DW_read == 1)
        {
          putchar('[');
          putchar(cText);
          putchar(']');
        }
      }

      
    return 0;

    }

      

    < 실행 결과 > 

     

    입력(COM5)은 도스창에서 이루어지고 수신은 하이퍼터미널에서 이루어짐(COM2)




     

    [ 송신 ]



     

      


    [ 수신 ]



     

    위와 반대로 입력은 하이퍼터미널(COM2)에서 이루어지고 수신은

       Thread 를 통해 DOS창에서 출력.



     


    [ 송신 ]






    [ 수신 ]



     


     

     

     





    728x90
    반응형
상단으로