1) 지식 창고는 본인이 작성한 콘텐츠(팁/노하우/리소스/강좌 등)을 무료 혹은 가상화폐인 납포인트를 통해 공유하는 공간입니다.
2) 본인이 작성한 콘텐츠에 대해서만 지식 창고에 등록할 수 있으며, 저작권에 위배되는 콘텐츠는 사전경고 없이 삭제될 수 있습니다.
3) 콘텐츠 구매 및 첨부파일 다운로드는 회원그룹 '연구원' 이상 가능하오니, 경험치를 쌓아 진급한 후에 이용 부탁드립니다.
4) 무료 콘텐츠의 본문은 구매절차 없이 즉시 이용할 수 있으며, 판매 납포인트가 있는 콘텐츠는 구매 후 이용할 수 있습니다.
5) 콘텐츠 판매에 따른 납포인트 수익은 지정한 비율(50%)에 따라 판매자에게 지급하며, 납포인트 수익을 통해 진급을 빨리할 수 있습니다.
6) 구매 후 평가를 하면 구매 납포인트의 20%를 돌려 드립니다.
판매자 | 바람을본소년 | 판매 납포인트 | 무료 | 평점 | 0점 / 총 0명 참여 |
---|
//-------------------definition---------------------------------------
#define SEG_SEL PORTB //세그먼트 선택 0~6
#define SEG_DATA PORTD //세그먼터에 숫자 출력 데이터
#define ST_LED 0x40 //안정일때 출력할 LED
#define US_LED 0x80 //불안정일때 출력할 LED
#define SEGMENT_CLEAR 0x00
#define SEGMENT_ON 0xFF
#define SEGMENT_A 0x01
#define SEGMENT_B 0x02
#define SEGMENT_C 0x04
#define SEGMENT_D 0x08
#define SEGMENT_E 0x10
#define SEGMENT_F 0x20
#define SEGMENT_G 0x40 //'-'
#define SEGMENT_DP 0x80 //'.'
#define MAXBUF 22 // 전체 패킷수신 버퍼 갯수 stx, status, type, data_length, checksum,etx
#define TRUE 1
#define FALSE 0
#define SYSTEM_CLOCK 16000000 // CLOCK (X-tal frequency)
//------------------variables---------------------------------------------
u08 i,j,k,temp;
u08 rx_buf[MAXBUF]; //전체 수신버퍼
u08 data = 0;
u08 count=0; //수신버퍼에서 배열에 저장하기위한 카운터변수
//u16 tick_count1=0,tick_count2=0,tick_count3=0; //오버플로우 인터럽트 자장 카운터변수
u08 count1=0;
u08 rx_byte; //한문자를 수신받아 저장하기위한 변수
const char SELECT_SEG[]={0x01,0x02,0x04,0x08,0x10,0x20}; //세그먼터 선택용
const char SEG1[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x80}; //아스키코드 변환용
const char SEG[]={0x40,0x80,0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F}; //아스키코드 변환용
const char OVER[]={0x3F,0x3E,0x79,0x77}; //과부하일때 출력 메세지
const char ERROR[]={0x79,0x77,0x77,0x3F,0x77}; //에러 출력 메세지
const char HELLO[]={0x76,0x79,0x38,0x38,0x3F}; //초기화 출력메세지
const char TEST[]={0x63,0x5C}; //세그먼트6개를 검사하는 출력메세지
//통신속도 설정용
unsigned long BAUDRATE1[][4]={{1200},{2400},{4800},{9600}};
//u32 baud[4]={832,415,207,103};
const char DISP_BAUDRATE[][4]={
{0x06,0x5B,0x3F,0x3F}, //1200
{0x5B,0x66,0x3F,0x3F}, //2400
{0x66,0x7F,0x3F,0x3F}, //4800
{0x6F,0x7D,0x3F,0x3F}, //9600
};
//--------------------function prototype -----------------------------------
unsigned char disp_num(u08 NUMBER); //숫자-> 아스키코드로 변환 함수
//void init_serial(void); //시리얼 통신 초기화 함수
//void init_serial(unsigned long BaudRate);
void init_serial(u32 BaudRate);
void serial_port_scan(void); //통신 속도 설정 함수
void no_sig(void); //신호없음메세지를 출력하는 함수
void disp_error(void); //에러메세지를 출력하는 함수
void init_segment(void); //세그먼트 초기화 함수
void display(void); //세그먼트에 디스플레이 해주는 함수
void disp_error(void); //입력이 없을때 error 메세지 출력하는 함수
//-------------시리얼 포트로 들어오는 데이터를 순환 큐에 차곡차곡 저장하는 수신완료 인터럽트--------------------
SIGNAL(SIG_USART0_RECV)
{
rx_byte = UDR0;
rx_buf[count] = rx_byte;
if((rx_buf[0] == 'S')|(rx_buf[0] == 'U')|(rx_buf[0] == 'O'))
{
count++;
if(count == MAXBUF) count = 0;
}
else return;
}
//--------------NUMBER to ASCII Code---------------------------------
//문자에 해당하는 아스키 코드값을 반환한다.
unsigned char disp_num(u08 NUMBER)
{
if((NUMBER == '-') | (NUMBER == '.'))
{
return SEG[NUMBER - 0x2D];
}
else
{
return SEG1[NUMBER - 0x30];
}
}
//---------------------시리얼 통신 초기화 함수------------------------------------------------
//시리얼 통신 인터럽트방법
//void init_serial(void)
//void init_serial(unsigned long BaudRate)
void init_serial(u32 BaudRate)
{
// Setting BaudRate
u16 baud = ((SYSTEM_CLOCK+(BaudRate*8L))/(BaudRate*16L)-1);
UBRR0L= baud;
UBRR0H = baud>>8;
UCSR0A = 0x00;
UCSR0B = 0x98; //interrupt enable, 8data, no parity, 1 stop
UCSR0C = 0x06;
}
//----------------세그먼트 초기화 루틴-------------------------------------------
void init_segment(void)
{
temp = 5;
for(i=0; i < 6; i++)
{
SEG_DATA = TEST[0];
SEG_SEL = SELECT_SEG[temp];
//if(temp == 0) temp = 0;
temp--;
Delay_ms(100);
}
temp = 0;
for(i=0; i < 6; i++)
{
SEG_DATA = TEST[1];
SEG_SEL = SELECT_SEG[temp];
//if(temp == 5) temp = 5 ;
temp++;
Delay_ms(100);
}
for(i=0;i<250;i++) //약 1초 출력
for(j=0,temp = 4;j<5;j++)
{
SEG_DATA = HELLO[j];
SEG_SEL = SELECT_SEG[temp]; //출력될 세그먼트 선택
if(temp == 0) temp = 4;
temp--;
Delay_ms(1);
}
SEG_SEL = SEGMENT_CLEAR;
}
//-----------------------수신 신호가 들어오지 않을때----------------------------------
void no_sig(void)
{
for(i=0;i<250;i++) //약 1초 출력
for(i=0,temp = 0; i < 6; i++)
{
SEG_DATA = 0x49;
SEG_SEL = SELECT_SEG[temp];
//if(temp == 5) temp = 5 ;
temp++;
Delay_ms(1);
}
}
//-----------------데이터 입력이 없거나 정상이 아닌경우 error 출력 ---------------------------
void disp_error(void)
{
//--------------입력데이터가 없을때 출력하는 코드-------------------------
for(i=0;i<250;i++) //약 1초 출력
for(j=0,temp = 4;j<5;j++)
{
SEG_DATA = ERROR[j];
SEG_SEL = SELECT_SEG[temp]; //출력될 세그먼트 선택
if(temp == 0) temp = 4;
temp--;
Delay_ms(1);
}
SEG_SEL = SEGMENT_CLEAR;
}
//-------------------세그먼트에 숫자를 표시해주는 함수---------------------
void display(void)
{
u08 index;
index = 0;
//------------------안정일때 출력-------------------------------
if(rx_buf[index] == 'S')
{
if(rx_buf[index+1] == 'T')
{
for(k=16, temp = 0; k>=9; k--)
{
//-------------여기에 LED 처리코드 추가---------------
//sbi(SEG_SEL,ST_LED); //안정을 나타내는 LED를 켠다.
//공백이 아닐경우만 세그먼트에 나타낸다.
if(rx_buf[k] != 0x20)
{
//소수점 처리부분
//소수점이 나타났을때는 그 다음데이터에서 오른쪽으로 하나쉬프트 한다.
if(rx_buf[k+1] == '.')
{
data = rx_buf[k];
temp--;
}
else
{
data = rx_buf[k];
}
SEG_DATA = disp_num(data);
SEG_SEL = SELECT_SEG[temp]^ST_LED; //출력될 세그먼트 선택
temp++; //세그먼트를 쉬프트 시켜서 각자리마다 다른 숫자가 나타나도록 한다.
Delay_ms(1);
}
}
}
}
//------------------불안정일때 출력 -------------------------------
else if(rx_buf[index] == 'U')
{
if(rx_buf[index+1] == 'S')
{
//-----------불안정일때 출력 설정--------------------------
for(k=16, temp = 0; k>=9; k--)
{
//-------------여기에 LED 처리코드 추가---------------
//sbi(SEG_SEL,US_LED); //안정을 나타내는 LED를 켠다.
//공백이 아닐경우만 세그먼트에 나타낸다.
if(rx_buf[k] != 0x20)
{
//소수점 처리부분
//소수점이 나타났을때는 그 다음데이터에서 오른쪽으로 하나쉬프트 한다.
if(rx_buf[k+1] == '.')
{
data = rx_buf[k];
temp--;
}
else
{
data = rx_buf[k];
}
SEG_DATA = disp_num(data);
SEG_SEL = SELECT_SEG[temp]^US_LED; //출력될 세그먼트 선택
temp++; //세그먼트를 쉬프트 시켜서 각자리마다 다른 숫자가 나타나도록 한다.
Delay_ms(1);
}
}
}
}
//-------------------과부하 일때 출력--------------------------------
else if(rx_buf[index] == 'O')
{
if(rx_buf[index+1] == 'L')
{
//--------------과부하일때 OVER 출력하는 코드-------------------------
for(k=0, temp = 3; k<4; k++)
{
SEG_DATA = OVER[k];
SEG_SEL = SELECT_SEG[temp]; //출력될 세그먼트 선택
if(temp == 0) temp = 3;
temp--;
Delay_ms(1);
}
// index++;
// if(index == MAXBUF) index = 0;
}
}
else if(rx_buf[index] == 0x00)
{
no_sig();
return;
}
else
{
disp_error();
return;
}
}
void serial_port_scan(void)
{
u08 serial_port_scan_ok = 0;
u08 index = 0;
i = j = 0;
while(!serial_port_scan_ok)
{
for(i=0;i<250;i++) //약 1.5초 출력
for(k=0, temp = 3; k<4; k++)
{
cli();
init_serial(BAUDRATE1[j][0]);
//init_serial(baud[j]);
sei();
SEG_DATA = DISP_BAUDRATE[j][k];
SEG_SEL = SELECT_SEG[temp]; //출력될 세그먼트 선택
//------------------속도 설정------------------------------
if((rx_buf[index] == 'S')|(rx_buf[index] == 'U')|(rx_buf[index] == 'O'))
{
if((rx_buf[index+1] =='T')|(rx_buf[index+1] =='S')|(rx_buf[index+1] =='L'))
{
serial_port_scan_ok = TRUE;
}
}
else serial_port_scan_ok = FALSE;
if(temp == 0) temp = 3;
temp--;
Delay_ms(1);
}
j++;
if(j == 4) j = 0;
Delay_ms(1);
}
}
//--------------------메인 함수------------------------------------------------------
int main(void)
{
DDRB = 0xFF;
DDRD = 0xFF;
init_segment(); //세그먼트 초기화
serial_port_scan(); //시리얼포트에 통신속도를 찾아내서 연결함
Delay_ms(10);
while(1)
{
display();
}
}
굿 굿 굿 !!!