NAVER

질문 avr(atmega128) serial통신 (시리얼통신) 부분 코드 질문입니다 ㅠ
비공개 조회수 1,875 작성일2017.11.17

다음 코드는 적외선 센서에 대한 데이터를 입력받아 움직임을 감지하고 움직이지 않은 시간을 카운팅하여 serial 통신을 이용하여 와이파이로 정보를 보내는 코딩입니다.

이 코드에서

먼저, 적외선 센서부분을 단순한 스위치로 바꾸려고 합니다. 적외선센서부분이 어디부터 어디까지인지 혹시 아시나요 ㅠㅠ?

두번째로, 시간 카운팅 부분을 삭제하려고 합니다. 이부분을 그냥 삭제해도 코드에 에러가 안날까요 ㅠㅠ?

하이퍼터미널을 통해 통신하는 부분이 아직 미숙합니다. 파일을 만들어야하는데 그 과정을 설명해주시면 감사하겠습니다 ㅠㅠ


마지막으로 이 코드를 '스위치에 대한 데이터(0과1)을 입력받아 serial 통신을 이용하여 와이파이로 정보를 보내는 코드'로 변경하고자합니다 ㅠㅠ 

고수님들 도와주세요 ㅠㅠ 


#include "system.h"

#include "serial.h"

#include <avr/io.h>

#include <string.h>

#include <avr/interrupt.h>

#define DDR_LED DDRG

#define PORT_LED PORTG

#define DDR_SENSOR DDRD

#define PIN_SENSOR PIND

#define Pull_Up DDRA

//-----------------------------------------------------------------------------

#define F_CPU 16000000UL // Clock Speed

int USART0_putchar(char c, FILE *stream);

int USART0_getchar(FILE *stream);

void initLED(void);

#define TRUE 1

#define FALSE 0

int bTimerCheck = FALSE;

void USART0_Transmit(unsigned char data)

{

//Wait for empty transmit buffer

while(!(UCSR0A & (1<<UDRE)));

//Put data into buffer and send the data

UDR0 = data;

}

//Poll the receive buffer

char USART0_Poll()

{

return (UCSR0A & (1 <<RXC));

}

//Initialize(set baud rate, frame format, enable TX and RX)

void USART0_Init(float baud) //Baud float 선언하지 않고 int 115200쓰면 overflow

{

//Set baud rate

int ubrr = F_CPU/16/baud-1;

float ubrr2 = F_CPU/16/baud-1;

UBRR0H = (unsigned char)(ubrr>>8); //bit shifting, 0000 0000

UBRR0L = (unsigned char)ubrr2; //8, 0000 1000

//Set frame format: 8-bit, 1-Stop bit, no Parity, asynchronous

UCSR0C=0b00000110;

//Enable receiver and transmitter

//able interrupts

UCSR0B=0b10011000;

}

//Receive one byte

unsigned char USART0_Receive()

{

//Wait for data to be received

while(!USART0_Poll());

//Get and return received data from buffer

return UDR0;

}

//송신

int USART0_putchar(char c, FILE *stream)

{

if(c=='\n')

{USART0_putchar('\r', stream);}

while(!(UCSR0A & (1<<UDRE)));

UDR0 = c;

return c;

}

//수신

int USART0_getchar(FILE *stream)

{

char c;

while(!(UCSR0A & (1<<RXC)));

c=UDR0;

if(c=='\r')

{USART0_putchar('\n', stream);}

USART0_putchar(c, stream); // echo

return c;

//backspace 지원하지 않음

}

//전역 변수 선언

int timer=0;

unsigned char rx_data; //UART 통신 수신 데이터 한 문자 저장

unsigned char tmr1_count; // 1초 인터럽트 회수 카운팅하는 전역 변수

int NowSec; // 움직임이 없는 동안 초를 카운팅하는 전역 변수

int NowMin; // 움직임이 없는 동안 카운팅하는 전역 변수

int NowHour; // 움직임이 없는 동안 카운팅하는 전역 변수

int NowDate; // 움직임이 없는 동안 카운팅하는 전역 변수

//인터럽트 서비스 루틴 함수 및 1초 타이머 인터럽트 구동

void Time_Setting()

{

TIMSK = 0b10000000; //Timer2 OCIE enable한다.

TCCR2=0b00001101; //Timer2 CTC모드로, CLK /1024로 한다.

OCR2=125; //Timer2 compare할 값을 125으로 한다.

TCNT2=0; //Timer2의 시작을 0으로 한다.

sei(); //enable global interrupt

}

ISR(TIMER2_COMP_vect) //Timer2 Compare될 때 interrupt가 발생한다.

{

timer++;

if(timer == 125)

{

NowSec++; //초 증가

timer=0;

}

}

//전자 시계를 동작하기 위한 시간, , 초 계산을 위한 함수 코딩

void calculate_timer(void)

{

if(NowSec == 60) //60초 되면

{

NowSec=0;

NowMin++; //분 증가

}

if(NowMin == 60) //한시간 되면

{

NowMin=0;

NowHour++; //시간 증가

}

if(NowHour == 24) //하루 되면

{

NowDate++; //날짜 증가

NowHour=0;

}

}

int main(void)

{

Pull_Up =0x01;

void Delay(unsigned int Time);

SystemInit();

Led1Init();

Led1On();

//UART Init

U0_Init(BAUD_115200);

printf("움직임 감지 시스템\r\n");

Time_Setting(); //타이머1 인터럽트 동작 초기화 함수 실행

//전역 변수

rx_data=0; //UART 통신 수신 데이터 한 문자 저장 초기화

tmr1_count=0; // 1초 인터럽트 회수 카운팅하는 전역 변수 초기화

NowSec=0; // 움직임이 없는 동안 초를 카운팅하는 전역 변수 초기화

NowMin=0; // 움직임이 없는 동안 분을 카운팅하는 전역 변수 초기화

NowHour=0; // 움직임이 없는 동안 시간을 카운팅하는 전역 변수 초기화

NowDate=0; // 움직임이 없는 동안 날짜를 카운팅하는 전역 변수 초기화

volatile unsigned char a = 0;

DDR_SENSOR = 0x00;

initLED();

for(;;)

{

a = PIN_SENSOR;

a = a>>6; //센서를 두개 이용할 경우

if(a != 0)

{

printf("Move</br>");

PORT_LED = 0x02;

NowSec=0; // 움직임이 없는 동안 초를 카운팅하는 전역 변수 초기화

NowMin=0; // 움직임이 없는 동안 분을 카운팅하는 전역 변수 초기화

NowHour=0; // 움직임이 없는 동안 시간을 카운팅하는 전역 변수 초기화

NowDate=0; // 움직임이 없는 동안 날짜를 카운팅하는 전역 변수 초기화

_delay_ms(1000);

}

else

{

PORT_LED = 0x00;

if(bTimerCheck == FALSE)

{

PORT_LED = 0x00;

bTimerCheck = TRUE;

}

calculate_timer(); //, , 초 계산 함수 실행

_delay_ms(1000);

if(NowSec>10|NowMin>0|NowHour>0|NowDate>0)

{printf("위험");} //10초가 지났을 경우 위험이라 알림 (시연을 위해 10초로 지정 실제로는 6시간이나 12시간을 기준으로 한다.

printf("움직이지 않은 시간 %2d : %2d : %2d : %2d</br>", NowDate, NowHour, NowMin, NowSec); //움직이지 않는 시간을 서버에 띄워줌

}

}

return;

}

void initLED(void)

{

DDR_LED = 0xFF;

PORT_LED = 0xFF;

}

//-----------------------------------------------------------------------------

#include "system.h"

//-----------------------------------------------------------------------------

void Delay(unsigned int Time)

{

while(Time){

_delay_ms(0.96);

Time--;

}

}

void Delay_us(unsigned int Time)

{

while(Time){

_delay_us(0.96);

Time--;

}

}

void SystemInit(void)

{

}

//-----------------------------------------------------------------------------

#include "serial.h"

#ifdef _UART0_ENABLE

//-----------------------------------------------------------------------------

// Serial Prot0 Utility Fuction Routine

void U0_Init(unsigned char baud)

{

U0R_CSRA |= UART_DB_BAUDRATE;

U0_SetBaud(baud);

// enable serial uart & receiver

u0_EnableTx();

u0_EnableRx();

fdevopen(U0_PutByte, U0_GetByte);

}

void U0_SetBaud(unsigned char baud)

{

unsigned char baud_rate = 0;

switch (baud)

{

case BAUD_9600:

baud_rate = BAUDRATE_VAL_9600;

break;

case BAUD_14400:

baud_rate = BAUDRATE_VAL_14400;

break;

case BAUD_19200:

baud_rate = BAUDRATE_VAL_19200;

break;

case BAUD_28800:

baud_rate = BAUDRATE_VAL_28800;

break;

case BAUD_38400:

baud_rate = BAUDRATE_VAL_38400;

break;

case BAUD_57600:

baud_rate = BAUDRATE_VAL_57600;

break;

case BAUD_76800:

baud_rate = BAUDRATE_VAL_76800;

break;

case BAUD_115200:

baud_rate = BAUDRATE_VAL_115200;

break;

default :

baud_rate = BAUDRATE_VAL_DEFAULT;

break;

}

U0R_UBRRL = baud_rate;

}

unsigned char U0_GetByte(void)

{

u0_WaitForReceive();

return u0_RxData();

}

void U0_PutByte(unsigned char Data)

{

u0_WaitForSend();

u0_TxData(Data);

}

void U0_PutBuf(unsigned char *str, unsigned char len)

{

unsigned char i =0;

for(i=0;i<len;i++)

{

U0_PutByte(*(str+i));

}

}

void U0_PutStr(unsigned char *str)

{

while(*str != 0)

{

U0_PutByte(*str);

str++;

}

}

unsigned char U0_IsGetByte(void)

{

return u0_IsReceiveData();

}

//------------------------------------------------------------------------------

#endif //end UART0 ENABLE

프로필 사진

답변자님,

정보를 공유해 주세요.

1 개 답변
1번째 답변
프로필 사진
키트 박옥현
우주신
전기, 전자 공학 6위, 프로그래머 1위, 프로그래밍 22위 분야에서 활동
본인 입력 포함 정보

1

#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdio.h>
//
#define LED_ON     PORTG=2
#define LED_OFF    PORTG=0
#define SENSOR     ((~PIND)&0xC0) // 센서,PD6,PD7
//
volatile unsigned char rx=0,flag=0,stat=0,str[50];
volatile unsigned char ms=0,Sec=0,Min=0,Hour=0,Date=0;
volatile unsigned long timer=0;
//
void TX0_char(char c){ while(!(UCSR0A&0x20)); UDR0=c; }
void TX0_STR(char *s){ while(*s)TX0_char(*s++); }
//
ISR(TIMER2_COMP_vect){
  if(SENSOR){ LED_ON;
    if(++ms>999){ ms=0;
      timer++;
      if(++Sec==60){ Sec=0; 
        if(++Min==60){ Min=0;
          if(++Hour==24){ Hour=0; if(Date<255)Date++; }
        }
      }
    }
    if(timer>10)flag=1; //시연을 위해 10초로,실제로는 6시간이나 12시간
  }
  else{ LED_OFF; flag=0; ms=Sec=Min=Hour=Date=0; }
}
//
ISR(USART0_RX_vect){ rx=UDR0; }
//
int main(void){
  DDRA=1;
  DDRG=2;     LED_OFF;
  TCCR2=0x0B; OCR2=249;  TIMSK=0x80; //16000000/64/(1+249),1ms
  UBRR0L=8;   UCSR0B=0x98;           //BAUD_115200
  TX0_STR("움직임 감지 시스템\r\n");
  sei();
  for(;;){
    if(stat!=flag){ stat=flag;
      if(flag){ sprintf(str,"위험!! 시간경과 %03d %02d:%02d:%02d\r\n",Date,Hour,Min,Sec); TX0_STR(str); } //움직이지 않는 시간을 서버에 띄워줌
      else    { TX0_STR("동작중\r\n"); }
    }
    //
    if(rx=='g'){ rx=0; // 서버에서 시간을 요구하면
      sprintf(str,"시간경과 %03d %02d:%02d:%02d\r\n",Date,Hour,Min,Sec); TX0_STR(str); } //시간을 서버에 띄워줌
    }
  }
}

//---------------


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <avr/io.h>
#include <avr/interrupt.h>
#define  F_CPU 16000000UL
#include <util/delay.h>
#include <stdio.h>
//
volatile char rx0=0,rx1=0,stat=2,sw;
//
void TX0_char(char c){ while(!(UCSR0A&0x20)); UDR0=c; } //문자 송신
void TX1_char(char c){ while(!(UCSR1A&0x20)); UDR1=c; }
void TX0_STR(char *s){ while(*s)TX0_char(*s++); }       //문자열 송신
void TX1_STR(char *s){ while(*s)TX1_char(*s++); }
//
ISR(USART0_RX_vect){  //수신 인터럽트
  rx0=UDR0;
  if(rx0=='g')stat=2; // 송신을 위해서 엉뚱한 값을 입력
}
ISR(USART1_RX_vect){
  rx1=UDR1;
}
//
int main(void){
//UBRR0L=8;   UCSR0B=0x98;  //115200
  UBRR0L=103; UCSR0B=0x98;  //9600
//UBRR1L=103; UCSR1B=0x98;  //9600
  TX0_STR("스위치 체크\r\n");
  sei();
  while(1){
    sw=((~PINA)&1); //PA0 스위치
    //
    if(stat!=sw){ stat=sw; //저장한 값과 다르면
      if(sw)TX0_STR("스위치 ON\r\n");
      else  TX0_STR("스위치 OFF\r\n");
    }
  }
}

채택율이 낮으면 좋은 답변이 달리지 않습니다.
이전 글들 모두 채택하세요 (마감하면 안됩니다.)


2017.11.18.

  • 채택

    질문자가 채택한 답변입니다.

도움이 되었다면 UP 눌러주세요!
UP이 많은 답변일수록 사용자들에게 더 많이 노출됩니다.