Busan IT/공장내 Network2015. 4. 30. 17:39

fclose를 사용한 표준 입출력 연결, feof, fread, fwrite 함수

================================Outline======================================

fclose를 사용한 표준 입출력 연결

feof 함수

fread, fwrite 함수

-----------------------------------------------------------------------------

 

 

출력은 stdoutstderr 두 가지 경로로 가능하다. 때문에 출력을 막기 위해서는 stdoutstderr 둘 다 fclose를 해야 한다.

 


<feof 함수>

 

원형은,

 

#include <stdio.h>

int feof(FILE * stream);

 

0이 아닌 값을 반환 - 파일의 끝

0을 반환 - 파일의 끝이 아님


 

at 모드로 작성하여도 파일의 끝이 아니라 마지막 문자를 가리키고 있음으로 반환 값은 0이다.

 

//버퍼를 사용하여 복사하면 효율적으로 할 수 있다.

<fread 함수>

 

원형은,

 

#include <stdio.h>

size_t fread(void * buffer, size_t size, size_t count, FILE * stream);

 

성공 시 전달인자 count

실패 또는 파일의 끝 도달 시 count보다 작은 값 반환

 

//typedef에서 _t 붙혀 태그임을 표시한다. 여기서 size_tunsigned inttypedef한 것이다.

 

마지막 인자(FILE *stream)를 호출한 후, 첫 번째 인자(void *ptr)가 가리키는 곳으로부터 시작하여,

 

<fwrite 함수>

 

원형은,

 

#include <stdio.h>

size_t fread(const void * buffer, size_t size, size_t count, FILE * stream);

 

중간인자는 내일 이 시간에,

 

p/520 예제 소스를 내일 사용하기 위해 쳐 놓는다.

 

//새로운 함수가 나왔을 때 인자를 분석함으로써 어떻게 함수가 실행되는지 예측하는 능력을 길러야 한다.

반응형
Posted by newind2000
Busan IT/AVR 컨트롤러2015. 4. 30. 11:40

시리얼 통신을 활용한 LED 전구 켜기(C#)

 

================================= Outline ===================================

Visual Basic C#을 활용한 시리얼 통신 LED 전구 켜기

 

 

-----------------------------------------------------------------------------

Serial 통신을 사용하여 연결 장치들을 끄고 켜는 코팅을 해보자.

 

HMI(Human Machine Interface)란 사용자가 원하는 목표를 달성할 수 있도록 제품의 작동 상태를 표시하고, 적절한 조작이 가능 하도록 해주는 물리적인 기구나 장치를 의미하며, 인간과 기계 사이의 정보의 전달이 초점이다.

 

Visual Studio에서,

 

New Project -> C# -> Windows application을 선택하고 이름을 입력하면

이러한 창이 뜬다.

 

시리얼 포트를 사용을 위한 설정을 해주어야 한다.

 

시리얼 포트를 선택하고 좌클릭으로 끌어다가 Form1창 안에 끌어 넣는다.3

우측하단의 속성에서 통신하고자하는 기계의 규약과 일치하게 속성을 맞춰주면 된다.

 

Toolbox에서 button을 추가한 후 적절히 배치해 준다.

 

배경화면을 더블클릭하면 소스가 뜬다. 소스 코드에서,

여자저차 하여 코딩을 해주자.


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace _20150430
{
    public partial class Frm_Main : Form
    {
        public Frm_Main()
        {
            InitializeComponent();
        }

        private void Frm_Main_Load(object sender, EventArgs e)
        {
            PORT_CLOSE.Enabled = false;
            timer1.Enabled = true;
            ON.Enabled = false;
            OFF.Enabled = false;

        }


        private void PORT_OPEN_Click(object sender, EventArgs e)
        {
            serialPort1.Open();
            PORT_OPEN.Enabled = false;  // 포트가 열리면 해당 버튼은 사용하지 못하게 된다.
            PORT_CLOSE.Enabled = true;  // 포트가 열리면 PORT_CLOSE는 활성화 된다.
            ON.Enabled = true;
            OFF.Enabled = true;

        }

        private void PORT_CLOSE_Click(object sender, EventArgs e)
        {
            serialPort1.Close();
            PORT_CLOSE.Enabled = false// 포트가 열리면 해당 버튼은 사용하지 못하게 된다.
            PORT_OPEN.Enabled = true;   // 포트가 열리면 PORT_OPEN는 활성화 된다.
            ON.Enabled = false;
            OFF.Enabled = false;
            

        }

        private void ON_Click(object sender, EventArgs e)
        {
            serialPort1.WriteLine("o");
        }

        private void OFF_Click(object sender, EventArgs e)
        {
            serialPort1.WriteLine("f");
        }
    }
}




반응형
Posted by newind2000
Busan IT/공장내 Network2015. 4. 29. 17:37

파일과 스트림, 기본적인 파일의 입출력, 파일의 개방모드

 

 

====================================Outline==================================

파일과 스트림, 기본적인 파일의 입출력

파일의 개방 모드

-----------------------------------------------------------------------------

 

<파일과 스트림(Stream), 그리고 기본적인 파일의 입출력>

 

어떠한 파일이 있다고 치면 다음의 세 가지가 존재한다.

 

- HDD에 저장된 파일의 내용

- OS에서 해당 파일과 관련하여 HDD에 있는 내용을 불러들여 메모리에 저장된 내용

- 해당 파일의 메모리 주소(descriptor)

 

fopen의 명령어가 실행되어 파일을 열게되면 file 구조체 변수의 주소 값을 변환시켜 주고, 실패 시 NULL() 반환한다.

 

FILE * fp = fopen("data.txt.", "wt");

 

=> data.txt(text)파일에 작성(write)하라.

 

파일은 크게 두 종류로 나눌 수 있다.

 

1. text file: 사람이 인지할 수 있는 문자 형태로 출력되는 파일

 

2. binary file: 2진법으로 되어 있는 파일

//리눅스 환경에서는 파일생성을 위해서 fopen란 명령어를 사용하는데 window에서는 create 명령어를 사용한다.

 

fclose의 매뉴얼

파일을 사용하고 fclose로 스트림을 닫아주지 않으면 파일이 저장되지 않을 수가 있다.

 

fputc의 매뉴얼,



 

윈도우 운영체제에서 따옴표(“”)속 역슬레쉬(\) 쓰이면 다음에 오는 입력어와 결합하여 특수한 명령어로 인식하게 된다. 때문에 단순히 역슬레쉬를 사용하고자하면 역슬레쉬를 두 번 적어주어야 한다.

ex) \\..

 

리눅스에서는 슬레쉬(/) 하나를 사용하여 가능하다.

 

//윈도우를 제외한 대부분 운영체제에서는 상위 디렉토리와의 경로차이를 나타내는 기호는 //슬레쉬(/) 이다.

 

<파일의 개방 모드>

w모드로 열게 되면 파일의 처음부터 데이터를 입력하게 되고 a모드로 열게 되면 기존에 있던 자료에 추가로 데이터를 입력하게 된다.

 

//개행 명령어는 운영체제마다 다르기 때문에 구분하여 사용할 필요가 있다.

 

fprintf 매뉴얼,


 

반응형
Posted by newind2000
Busan IT/AVR 컨트롤러2015. 4. 29. 13:46

AVR 컨트롤러 - USART를 이용한 데이터 송/수신

 

 

===================================Outline===================================

USART를 이용한 데이터 송/수신

-polling 방식

-interrupt 방식

 

-----------------------------------------------------------------------------

기존에 사용하던 hyperTerminal대신에 ComportMaster를 다운로드하여 데이터를 송수신해보자!

두 글자 이상을 입력하게 되면 데이터가 깨지는 것을 확인할 수 있다.

<Interrupt 방식을 통한 USART 통신>

 

데이터 소실을 막기 위해 데이터 수신은 interrupt 방식으로 권장한다.

 

interrupt활성화를 위해 UCSRnB 레지스터의 세팅에서,

 

UCSR1B=(1<<RXCIE)|(1<<RXEN) | (1<<TXEN) | (0<<UCSZ2); //RXCIE bit 활성 (interrupt enable)

 

그리고 global interrupt활성화를 위해,

 

SREG |= 0x80; //Global interrupt 활성화

 

그리고 interrupt를 위한 함수를 만들어 준다.

void __Vector_25(void) //interrupt TX

{

USART0_TX(UDR0);

}

void __vector_25(void)__attribute__((signal,used,externally_visible)); //헤더파일에 추가

 

이상 없이 작동한다.

 

/*** 코드 ***/

<main.c>

#include "SMART.h"
#include "USART.h"
 
int main(void)
{
  /* 변수 설정 */
  unsigned char A;

  /* PORT 설정 */
  DDRE = 0xFE;

  /* USART 레지스터 설정 */
  USART0_INIT();

  
  while(1)
  {
    A = USART0_RX();
    USART0_TX(A);        
        
  }
  
            
    
  
  return 0;
}

 

<USART.h>

#ifndef __USART_H__
#define __USART_H__

#include "SMART.h"
#define  f_osc  ((unsigned long)(F_CPU)) //F_CPU는 makefile에 지정되어 있다.
#define  BAUD  115200 //BAUD(bps)
#define  UBRR_H  ((unsigned long)((f_osc/(16.0*BAUD))-0.5)>>8//연산자는 괄호로 감싸준다.
#define  UBRR_L  ((f_osc/(16.0*BAUD))-0.5)


void USART0_INIT(void);
void USART0_TX(unsigned char);
void USART0_TX_string(unsigned char *);
unsigned char USART0_RX(void);


#endif //__USART_H__

 

<USART.c>

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


void USART0_INIT(void)
{
  //UBRR 12 bit 특성에 따른 자리 값 설정
  UBRR0H=UBRR_H;
  UBRR0L=UBRR_L;


  //UCSRnA 레지스터의 세팅 
  UCSR0A=(0<<U2X) | (0<<MPCM);
  
  //UCSRnB 레지스터의 세팅
  UCSR0B=(1<<RXEN) | (1<<TXEN) | (0<<UCSZ2);

  //UCSRnC 레지스터의 세팅
  UCSR0C  =(0<<UMSEL)|(1<<UPM1)|(0<<UPM0)|(0<<USBS)|
        (1<<UCSZ1)|(1<<UCSZ0)|(0<<UCPOL);//Asynchronous mode, Even Parity, 1-stop bit, 8-bit size

  return;
}

void USART1_INIT(void)
{
  //UBRR 12 bit 특성에 따른 자리 값 설정
  UBRR1H=UBRR_H;
  UBRR1L=UBRR_L;


  //UCSRnA 레지스터의 세팅 
  UCSR1A=(0<<U2X) | (0<<MPCM);
  
  //UCSRnB 레지스터의 세팅
  UCSR1B=(1<<RXEN) | (1<<TXEN) | (0<<UCSZ2);

  //UCSRnC 레지스터의 세팅
  UCSR1C  =(0<<UMSEL)|(1<<UPM1)|(0<<UPM0)|(0<<USBS)|
        (1<<UCSZ1)|(1<<UCSZ0)|(0<<UCPOL);//Asynchronous mode, Even Parity, 1-stop bit, 8-bit size

  return;
}

void USART0_TX_string(unsigned char * ucString)
{
  while(*ucString != 0)
  {
    USART0_TX(* ucString);
    ++ucString;
  }
  return;
}


void USART0_TX(unsigned char ucData )
{
  // Wait for empty transmit buffer 
  while ( 0==( UCSR0A & (1<<UDRE)) );
  
  // Put data into buffer, sends the data
  UDR0= ucData;
  return;
}

void USART1_TX(unsigned char ucData )
{
  // Wait for empty transmit buffer 
  while ( 0==( UCSR1A & (1<<UDRE)) );
  
  // Put data into buffer, sends the data
  UDR1= ucData;
  return;
}

unsigned char USART0_RX( void)
{
  // Wait for data to be received
  while ( 0==(UCSR0A & (1<<RXC)) );  //datasheet p/184
  
  // Get and return received data from buffer 
  
  return UDR0;
}

unsigned char USART1_RX( void)
{
  // Wait for data to be received
  while ( 0==(UCSR1A & (1<<RXC)) );  //datasheet p/184, polling method
  
  // Get and return received data from buffer 
  
  return UDR1;
}



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

입력한 문자를 활용하여 특정 문자가 일치하면 LED 불이 들어오고 꺼지게 하는 코딩을 해보자.

 

to be continued tomorrow...







 

 

 

 

 

반응형
Posted by newind2000
Busan IT/공장내 Network2015. 4. 28. 17:45

main함수로의 인자전달, 함수의 매뉴얼, 기본적인 파일의 입출력(fopen)

=================================outline=================================

main 함수로의 인자전달

PE 구조

함수의 메뉴얼

파일과 스트림(Stream), 그리고 기본적인 파일의 입출력

------------------------------------------------------------------------

<main 함수로의 인자전달>

문자열을 만들어 지속적으로 출력할 경우에는 포인터를 만들어서 사용하면 code영역에 있는 배열을 stack 영역으로 복사하지 않고 주소로 통해 해당 문자열을 출력할 수 있다.

 

printf 원형의 첫 번째 인자는 const char *인데 이것은 주소를 가리킨다. 따옴표(“”)를 사용하여 문자를 넣으면 문자열을 나타내고 문자열 자체는 주소임으로 입력된 글자를 인자의 형(const char *)과 일치한다.

실행 파일에는 stack영역이 존재하지 않는다. stack영역은 실행파일이 동작할 때 메모리에 구현된다.

 

compilecode, data, bss영역에 메모리가 할당되고, 실행 시 heapstack영역에 메모리에 할당되게 된다.

<PE 구조>

 

// text == code

// padding: 구역을 맞추기 위해 남기는 공간

 

산딸기 시간!

 

<함수의 메뉴얼>

man printf를 입력하면,

 

// man manual의 약자이다.

 

man strcmp를 입력하면,

 

//mannual을 업데이트하는 명령어, apt-get install manpages-posix-dev

명령어에 대해서 의문점이 있을 경우 매뉴얼을 참조한다.

 

 

 

대략적인 C언어의 문법수업은 끝났다. 앞으로의 수업은 함수를 어떻게 사용하느냐에 치중할 것이다.

 

p/502 Ch. 24. 파일과 스트림(Stream), 그리고 기본적인 파일의 입출력

 

// database를 관리하는 시스템을 DBMS(Data Base Management System)라고 부른다.

// DBA(Data Base Agent)

파일을 열기 위한 명령어 fopen,

 

File * fopen(const char * filename, const char * mode);

 

<stdio.h> 헤더를 사용하고 첫 번째 인자에는 파일의 경로를 포함한 이름을 적는다.

// 동일 폴더에 있을 시 이름만 적으면 된다.

 

fopen명령어를 사용하여 파일을 열게 되면 운영체제에서는 해당 파일에 대한 기록을 남긴다.

그리고 해당 내용에 대한 파일의 주소 값을 전달해준다.

반응형
Posted by newind2000
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
Busan IT/공장내 Network2015. 4. 28. 09:01

함수 포인터 심화

 

test 함수는 smart 함수를 리턴하고 print 함수를 인자로 받는다.

 

int smart(printf);

 

int (* test(int (* T)(const char *,...))(char *)

{

return mart;

}

 

ptest함수를 가리킬 수 있는 함수 포인터

 

int (*(*p)(int(*)(const char *,...))(char *)

 

//포인터 모양이 이상하다 싶으면 함수 포인터가 아닌지 의심해 봐야 한다.

 

연습

 

1. 반환형 int 이름 smart 인자가 float *k인 함수를 선언한다.

2. 인자가 printf인 함수 testsmart를 반환하게 하게 선언한다.

3. test함수에서 printf를 사용하여 함수가 호출 됨을 선언한다.

4. main 함수에서 함수 포인터 p를 선언하고 ptest를 가리키게 한다.




#include <stdio.h>

int smart(float * k)
{
  
  return 0;
}



int (*  test(int (*T)(const char *, ...)  )  )(float * k)
{
  printf("test함수가 호출됨\n");
  return smart;

}





int main(void)
{

  int (*  (*p)(int (*T)(const char *,...)))(float *k);
  p = test;
  p(printf);


  return 0;

}





 

 

 

반응형
Posted by newind2000
Busan IT/AVR 컨트롤러2015. 4. 27. 15:25

USART - 스위치를 활용한 데이터 전송

 

=================================OUTLINE=================================

GPIOAFIO

USART의 정의

USB to Serial PORT 물리적인 연결 설정

통신규약과 결과 값

(실습)시리얼 통신을 활용한 글자 출력: 스위치를 활용하여 데이터 전송

--------------------------------------------------------------------------

LED를 켜기 위한 포트의 입출력은 GPIO를 통해 하였다.

 

GPIO(General Purpose Input/Output) <-> AFIO(Alternative Function Input/Output)

 

AFIO의 종류는,

 

ADC

DAC

USART

SPI

TWI

PWM

 

등이 있다. 그 중에는 가장 먼저 USART를 배워보자.

 

USART(UART),

 

Universal Synchronous/Asynchronous Receiver Transmitter의 약자로써, 범용 동기/비동기 송수신 방식이다.

 

 

USB to Serial PORT를 활용한 통신







데이터가 깨지는 것을 알 수 있으나 어떠한 방식으로 깨지는 지는 알 수 없다.

 

위의 설정 중 하나라도 통신 대상인 컴퓨터와 일치하지 않으면 데이터가 제대로 전달 되지 않음을 확인할 수 있다.

가장 흔히 쓰이는 통신규약은,

 

BAUD Rate: 9600bps

Parity: 없음

Stop Bit: 1

Hardware Control: None

 

9600-N-1-None

 

9600bps1bit를 전송하는데 걸리는 시간이,

104.17us에 한 bit이고 data1.04ms이다.

 

//milli - micro - nano



 

19200bps에서는,

 

1bit52.08us, 데이터당 520.8us이다. 속도가 빠를수록 안정성이 떨어진다는 단점이 있다.

 

Baud Rate를 산정하기 위해서,

우리는 주로 UBRR을 사용한다.

 

Atmega2560에서,

 

(16000000/16*9600) - 1 = 103


 

//비동기 2배속 모드는 비동기 일반모드보다 Baud Rate 선택 폭이 넓다.

 

지난 시간에 완성하지 못했던 스위치를 활용한 글자 전송을 해보자.

 



/*** 코드 ***/

<main.c>

#include "SMART.h"
#include "USART.h"
 
int main(void)
{
  /* 변수 설정 */
  unsigned char ucNum;

  /* PORT 설정 */
  DDRA = 0x00;
  DDRB = 0xFF;

  
  


  /* USART 레지스터 설정 */
  USART0_INIT();

  
  while(1)
  {
    while(1)
    {
      switch(ucNum = 0x0& PINA)
      {
        case 1 : 
          USART0_TX_string("  Mr. Sushi 문현점은   ");
          while(0x0& PINA == 0x01);
          break;

        case 2 :
          USART0_TX_string("  5월 1일에 ");
          while(0x0& PINA == 0x02);
          break;
        
        
        case 4 :
          USART0_TX_string("  반드시   ");
          while(0x0& PINA== 0x02);
          break;

  

        case 8 :
          USART0_TX_string("  쉬어야 한다!  ");
          while(0x0& PINA == 0x02);
          break;

        default :
          break;
      }
        
    }
  
            
    
  }
  return 0;
}

<USART.h> 

#ifndef __USART_H__
#define __USART_H__

#include "SMART.h"
#define  f_osc  ((unsigned long)(F_CPU)) //F_CPU는 makefile에 지정되어 있다.
#define  BAUD  115200 //BAUD(bps)
#define  UBRR_H  ((unsigned long)((f_osc/(16.0*BAUD))-0.5)>>8//연산자는 괄호로 감싸준다.
#define  UBRR_L  ((f_osc/(16.0*BAUD))-0.5)


void USART0_INIT(void);
void USART0_TX(unsigned char);
void USART0_TX_string(unsigned char *);


#endif //__USART_H__

 

<USART.c>

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


void USART0_INIT(void)
{
  //UBRR 12 bit 특성에 따른 자리 값 설정
  UBRR0H=UBRR_H;
  UBRR0L=UBRR_L;


  //UCSRnA 레지스터의 세팅 
  UCSR0A=(0<<U2X) | (0<<MPCM);
  
  //UCSRnB 레지스터의 세팅
  UCSR0B=(1<<RXEN) | (1<<TXEN) | (0<<UCSZ2);

  //UCSRnC 레지스터의 세팅
  UCSR0C  =(0<<UMSEL)|(1<<UPM1)|(0<<UPM0)|(0<<USBS)|
        (1<<UCSZ1)|(1<<UCSZ0)|(0<<UCPOL);//Asynchronous mode, Even Parity, 1-stop bit, 8-bit size

  return;
}

void USART1_INIT(void)
{
  //UBRR 12 bit 특성에 따른 자리 값 설정
  UBRR1H=UBRR_H;
  UBRR1L=UBRR_L;


  //UCSRnA 레지스터의 세팅 
  UCSR1A=(0<<U2X) | (0<<MPCM);
  
  //UCSRnB 레지스터의 세팅
  UCSR1B=(1<<RXEN) | (1<<TXEN) | (0<<UCSZ2);

  //UCSRnC 레지스터의 세팅
  UCSR1C  =(0<<UMSEL)|(1<<UPM1)|(0<<UPM0)|(0<<USBS)|
        (1<<UCSZ1)|(1<<UCSZ0)|(0<<UCPOL);//Asynchronous mode, Even Parity, 1-stop bit, 8-bit size

  return;
}

void USART0_TX_string(unsigned char * ucString)
{
  while(*ucString != 0)
  {
    USART0_TX(* ucString);
    ++ucString;
  }
  return;
}


void USART0_TX(unsigned char ucData )
{
  // Wait for empty transmit buffer 
  while ( 0==( UCSR0A & (1<<UDRE)) );
  
  // Put data into buffer, sends the data
  UDR0= ucData;
  return;
}

void USART1_TX(unsigned char ucData )
{
  // Wait for empty transmit buffer 
  while ( 0==( UCSR1A & (1<<UDRE)) );
  
  // Put data into buffer, sends the data
  UDR1= ucData;
  return;
}

unsigned char USART0_RX( void)
{
  // Wait for data to be received
  while ( 0==(UCSR0A & (1<<RXC)) );  //datasheet p/184
  
  // Get and return received data from buffer 
  
  return UDR0;
}

unsigned char USART1_RX( void)
{
  // Wait for data to be received
  while ( 0==(UCSR1A & (1<<RXC)) );  //datasheet p/184, polling method
  
  // Get and return received data from buffer 
  
  return UDR1;
}



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

 

 

반응형
Posted by newind2000
Busan IT/공장내 Network2015. 4. 24. 17:13

함수 주소를 사용한 호출, 함수의 반환형

 

===========================outline===========================

- 함수 주소를 사용한 함수의 호출

- 함수가 return 값일 경우의 반환형

------------------------------------------------------------

 

<함수의 주소를 사용한 함수의 호출>

 

메인함수의 주소를 출력해 보자.

계속 바뀐다....

 

visual studio에서 메모리 주소 보안 옵션을 끄고 메인 함수의 주소를 추출하자.


 

// 메모리 주소 보완 옵션 끄는 명령어 - cl a.c /link /DYNAMICBASE:NO

// smart의 주소: 0x00401000

<함수가 return 값일 경우의 반환형>

 

함수의 원형은,

 

반환형_함수의 이름(인자)의 형식을 띈다.

ex) int main(void)

 

만약 함수가 함수를 return 값으로 반환할 경우 함수의 인자를 어떻게 나타내 주어야 할까?

 

Q) return 값이 printf 함수인 smart함수를 만들어 보자.

 

? smart(void)

{

return printf;

}

 

에서,

 

우선 반환형 값에 int를 넣어 printf의 함수 원형이 뭔지 알아보자.

printf의 함수 원형은,

 

int (__cdecl *)(const char *,...)

 

임을 알 수 있다. __cdecl의 내용은 모르지만 우선 무시하고 삭제해주면,

 

int (*)(const char *,...)

 

이다.

 

이것을 넣고 다시 컴파일 해보면,

여전히 문법 에러가 뜬다.

 

아래에 답이 있으니 이해할 생각 하지 말고 외우자...

 

int (*)(const char *,...) smart(void)

해당 형태에서 smart(void)(*)*우측에 삽입한다.

 

int (* smart(void))(const char *,...)

 

저장하고 컴파일하면,

슬프도록 아름답게 잘된다.

 

 

 

 

 

 

 

 

반응형
Posted by newind2000
Busan IT/AVR 컨트롤러2015. 4. 24. 17:11

USART 통신의 기초와 기본 코딩

 

===============Outline=============================

 <타이머/카운터>

- PWM 주파수 구하는 방법

 

<USART 통신>

- 직렬 통신이란

- 병렬 통신이란

- 직렬/병렬 통신 비교

- 직렬 통신 전송 방식에 따른 구분

- 직렬 통신 전송 방향에 따른 구분

- USART

- USART의 방식

-----------------------------------------------------

 

Timer/Counter RegisterTCCRnA에서 TCNTOCCR 일반 모드/CTC모드/PC PWM로 구분할 수 있다.

 

<PWM 주파수 구하는 방법>

 

AVR 교재 p/185 - 186을 통해서 확인.

 

p/217. 2.3 USART 직렬통신 포트

 

직렬 통신이란,

 

하나의 데이터선을 통해 한 번에 한 비트를 전송하는 통신 방식이다.

한번에 한비트씩 통신함으로 속도가 느리지만 인프라 구축 시 비용이 적게 든다는 장점이 있다. 마이크로 프로세서와 컴퓨터 외부장치가 통신할 때 주로 사용한다.

양단 간 통신 거리가 먼 경우에 사용

ex) PCCOM Port, USB(Universal Serial Bus), IEEE1394, PCI Express

// IEEE1394: 영상 분야에서 많이 사용

 

병렬 통신이란,

 

한 번의 많은 정보를 전달하는 방식이다.

대량의 정보를 빠른 시간에 전송하다보니 속도가 빠르다는 장점이 있으나 인프라 구축 시 비용이 많이 든다는 단점이 있다.

마이크로 프로세서와 컴퓨터 내에 주변 장치간의 통신에 주로 사용된다.

ex) HDD

 

**직렬 통신과 병렬 통신 비교

 

직렬 통신의 전송 방식에 따른 구분,

 

동기식(Synchronous): 마스터(master)에서 슬레이브(slave)쪽으로 특정 신호를 이용하여 그 신호에 맞춰 데이터를 송수신하는 방식이다. 데이터 속도가 빠르나 clock 신호 선이 필요하다는 단점이 있다.

 

비동기식(Asyncronous): 데이터를 보낼 때 특정 약속에 따라 데이터를 송수신하는 방식이다.

 

 

전송 방향에 따른 구분,

 

- 단 방향 통신: 한 방향으로만 데이터를 전송하는 방식 ex)라디오, TV

- 반 이중 통신: 양방향 데이터 송수신이 가능하지만 한 쪽이 송신일 때 다른 방향은 반드시 수신인 형태를 취한다. ex) 무전기, 모뎀

- 전 이중 통신: 양쪽이 자유롭게 송수신이 가능하게 데이터를 전송하는 방식. ex) 전화기

 

USART(Universal Asyncronous Receiver and Transmitter)이란,

 

- 범용 비 동기식 Serial 통신 controller

- 비동기식 serial 통신에 필요한 제어 신호를 생성

// 한 때 유행했던 PC통신(모뎀)을 가능하게 한 장치

 

???

//CRC-8, CRC-16 통신 알고리즘?

오실레이터(oscillator) 값을 조정하면 baud rate가 바뀐다.

 

USART 방식은 크게 두 가지로 나뉜다.

 

1. Polling

- mainwhile(1)문 안에서 지속적으로 작동하며 송수신한다.

 

2. Interrupt

- UDR(수신 버퍼)에 데이터가 들어오면 인터럽트가 발생하여 데이터 전송.

- 특히 수신 부분에서 polling 방식을 취하면 데이터가 유실될 경우가 발생함으로 인터럽트를 권장한다.

/*** 실습 ***/

p/801에 있는 USART관련 코드를 쳐보자.

 

I. 서술

 

polling방식의 시리얼 통신 코드를 작성하는데 이에 필요한 레지스터 값을 넣어주자.

일단 코드를 작성하고 작성한 후 분석을 해보자.

 

II. 작업 나누기

1. 현재 헤더파일에 저장되어 있지 않은 register 값들을 define해준다.

2. 보고 친다=_=

 

III. 코딩

 

다음 시간에...

반응형
Posted by newind2000