본문 바로가기
임베디드시스템/AVR

[AVR] DS1302 clock settime 예외처리

by KHJ_940803 2021. 11. 3.

목표 : DS1302 clock settime 예외처리

 

개발 툴 : atmel studio

 

개발 보드 : ATMEGA128A

 

PC Uart 통신 툴 : Comport master

 

개발 기간 : 2021년 8월 20일

 

예외처리는 총 7개의 상황에 대하여 구현했다.

1. help, gettime, settimeyymmddhhmmss 를 제외한 다른 문자를 입력 했을때 프로그램 사용법을 안내하는 메세지를 출력한다.

2번 부터는 settime 의 yymmddhhmmss 를 입력 할 때를 가정한다.

2. 숫자 외 다른 것을 입력할 경우 숫자를 해당 위치에 입력하라는 메세지 출력한다.

3. 시, 분 ,초 에 각각 00~23, 00~59, 00~59 범위밖의 숫자를 입력한 경우 범위의 숫자를 입력하라는 메세지 출력한다.

4. 1,3,5,7,8,10,12 월에는 1일 부터 31일까지 입력할수 있고 범위를 넘을시 범위의 숫자를 입력하라는 메세지 출력한다.

5. 4,6,9,11 월에는 1일 부터 30일까지 입력할수 있고 범위를 넘을시 범위의 숫자를 입력하라는 메세지 출력한다.

6. 2 월에는 1일 부터 28일까지 입력할수 있고 범위를 넘을시 범위의 숫자를 입력하라는 메세지 출력한다.

7. 윤년에는 2월에 29일 까지 입력할 수 있고 범위를 넘을시 범위의 숫자를 입력하라는 메세지 출력, 그리고 윤년임을 알려준다.

 

(yymmddhhmmss 은 년도, 월, 일, 시간, 분, 초 를 2자리로 표현한 것이다.)

 

menu.c

/*
* menu.c
*
* Created: 2021-08-20 오후 3:06:51
*  Author: KHJ
*/
#include "menu.h"


void show_menu(void)
{
	printf("----- MENU ------\n");
	printf("1. show Time\n");   // 시 분 초
	printf("2. show Date\n");   // 년 월 일
	printf("3. update Date_time\n");
	printf("Select : ");
}

void menu_exec()
{
	char *rxData;
	char yy[4], mm[4], dd[4], hh[4], min[4], ss[4];
	int success_flag=0;
	int	second_success =0, min_success =0, hour_success =0, date_success =0, month_success =0, year_success=0;
	struct _ds1302 updateData;
	
	//gettime
	//settimeyymmddhhmmss
	//led0on
	//led0off
	//ledallon
	//ledalloff
	if (isRxString())
	{
		rxData = getRxString();   // Message를 읽어 온다.
		
		if (strncmp(rxData, "help", sizeof("help")) == 0)
		{
			printf("\n-- help --\n");
			printf("gettime\n");
			printf("settimeyymmddhhmmss\n");
		}
		
		else if (strncmp(rxData, "gettime", sizeof("gettime")) == 0)
		{
			DS1302_GetTime(&stTime);
			DS1302_GetDate(&stTime);
			
			printf("date %04d:%02d:%02d\n", 2000+stTime.year, stTime.month, stTime.date);
			printf("time %02d:%02d:%02d\n", stTime.hour, stTime.minutes, stTime.seconds);
		}
		// 0123456789012345678
		// settimeyymmddhhmmss
		else if (strncmp(rxData, "settime", 7) == 0)
		{
			strncpy(yy,rxData+7,2); // strncpy(yy,&rxData[7],2); --> yy[2] = 0;
			strncpy(mm,rxData+9,2);
			strncpy(dd,rxData+11,2);
			strncpy(hh,rxData+13,2);
			strncpy(min,rxData+15,2);
			strncpy(ss,rxData+17,2);
			
// 			updateData.year = atoi(yy);
// 			updateData.month = atoi(mm);
// 			updateData.date = atoi(dd);
// 			updateData.hour = atoi(hh);
// 			updateData.minutes = atoi(min);
// 			updateData.seconds = atoi(ss);

// strncpy를 하면 문자열이 들어가는 배열의 마지막에 null 값이 들어간다.
// 이때 atoi(yy)를 하는경우 문자와 null을 정수로 바꾸기 떄문에 쓰래기 값이 생성 될 수 있다 
// 이를 해결하기 위해 아래와 같은 코드를 사용한다. 문자'0'의 2진 값 0b0110000를 빼서 정수 0을 만든다. 
// 0부터 9까지는 순차적으로 2진 값이 증가 하기 떄문에 0b110000를 빼면 atoi를 사용하지 않고 원하는 정수 값을 구조체에 넣을 수 있다.
			updateData.year =(yy[0]-0b0110000)*10+(yy[1]-0b0110000);
			updateData.month =(mm[0]-0b0110000)*10+(mm[1]-0b0110000);
			updateData.date =(dd[0]-0b0110000)*10+(dd[1]-0b0110000);
			updateData.hour =(hh[0]-0b0110000)*10+(hh[1]-0b0110000);
			updateData.minutes =(min[0]-0b0110000)*10+(min[1]-0b0110000);
			updateData.seconds =(ss[0]-0b0110000)*10+(ss[1]-0b0110000);

			
			if(ss[0]>0x2f&&ss[0]<0x3a&&ss[1]>0x2f&&ss[1]<0x3a)	 // 초단위에 숫자를 입력했는지 확인 //입력값이 알맞으면 if문에 들어간다.
			{
				if(updateData.seconds>59||updateData.seconds<0)	// 00초 부터 59 초 까지 입력 했는지 확인
				{
					printf("Please Set seconds between 00 to 59!!\n");
					second_success =0;
				}
				else
				{
					second_success =1;
					//printf("sec : %d\n",updateData.seconds);
				}
			}
			else
			{
				printf("Please Enter NUMBER in second!!\n");
			} // 초단위 체크 끝
			
			if(min[0]>0x2f&&min[0]<0x3a&&min[1]>0x2f&&min[1]<0x3a)	 // 분단위에 숫자를 입력했는지 확인  //입력값이 알맞으면 if문에 들어간다.
			{
				if(updateData.minutes>59||updateData.minutes<0)	 // 00분 부터 59 분 까지 입력 했는지 확인
				{
					printf("Please Set minutes between 00 to 59!!\n");
					second_success =0;
				}
				else
				{
					min_success =1;
					//printf("min : %d\n",updateData.minutes);
				}
			}
			else
			{
				printf("Please Enter NUMBER in minute!!\n");
			}  // 분단위 체크 끝
			
			if(hh[0]>0x2f&&hh[0]<0x3a&&hh[1]>0x2f&&hh[1]<0x3a)	 // 시단위에 숫자를 입력했는지 확인  //입력값이 알맞으면 if문에 들어간다.
			{
				if(updateData.hour>23||updateData.hour<0)	// 00시 부터  23시 까지 입력 했는지 확인
				{
					printf("Please Set hours between 00 to 23!!\n");
					second_success =0;
				}
				else
				{
					hour_success =1;
					//printf("hour : %d\n",updateData.hour);
				}
			}
			else
			{
				printf("Please Enter NUMBER in hour!!\n");
			}// 시단위 체크 끝
			
			if(mm[0]>0x2f&&mm[0]<0x3a&&mm[1]>0x2f&&mm[1]<0x3a)	 // 월단위에 숫자를 입력했는지 확인  //입력값이 알맞으면 if문에 들어간다.
			{
				if(updateData.month==1||updateData.month==3||updateData.month==5||updateData.month==7||updateData.month==8||updateData.month==10||updateData.month==12)	// 1,3,5,7,8,10,12 월 인 경우
				{
					month_success=1;
					//printf("month : %d\n",updateData.month);
					if(mm[0]>0x2f&&mm[0]<0x3a&&mm[1]>0x2f&&mm[1]<0x3a)	 // 일단위에 숫자를 입력했는지 확인 //입력값이 알맞으면 if문에 들어간다.
					{
					if(updateData.date>31||updateData.date<1)	// 	1일부터  31일까지 입력했는지 확인
					{
						printf("Please set day between 01 to 31\n");
						date_success=0;
					}
					else
					{
						date_success=1;
						//printf("date : %d\n",updateData.date);
					}
					}
					else
					{
						printf("Please Enter NUMBER in day!!\n");
					}// 일단위 체크 끝
					
				}
				else if(updateData.month==4||updateData.month==6||updateData.month==9||updateData.month==11)  // 4, 6, 9, 11 월 인 경우
				{
					month_success=1;
					//printf("month : %d\n",updateData.month);
					if(mm[0]>0x2f&&mm[0]<0x3a&&mm[1]>0x2f&&mm[1]<0x3a)	 // 일단위에 숫자를 입력했는지 확인	//입력값이 알맞으면 if문에 들어간다.
					{
					if(updateData.date>30||updateData.date<1)		// 1일 부터 30일 까지 입력했는지 확인
					{
						printf("Please Set date between 01 to 30\n");
						date_success=0;
					}else
					{
						date_success=1;
						//printf("date : %d\n",updateData.date);
					}
				}
			
				else
				{
					printf("Please Enter NUMBER in day!!\n");
				}// 일단위 체크 끝
				
				}
				else if(updateData.month==2)   // 2월 인 경우
				{
					month_success=1;
					//printf("month : %d\n",updateData.month);
					if(mm[0]>0x2f&&mm[0]<0x3a&&mm[1]>0x2f&&mm[1]<0x3a)	 // 일단위에 숫자를 입력했는지 확인	//입력값이 알맞으면 if문에 들어간다.
					{
						if(updateData.year==0||updateData.year==4||updateData.year==8||updateData.year==12||updateData.year==16||updateData.year==20||updateData.year==24||updateData.year==28||updateData.year==32||updateData.year==36||updateData.year==40||updateData.year==44||updateData.year==48||updateData.year==52||updateData.year==56||updateData.year==60||updateData.year==64||updateData.year==68||updateData.year==72||updateData.year==76||updateData.year==80||updateData.year==84||updateData.year==88||updateData.year==92||updateData.year==96)
						{
							if(updateData.month==2)
							{
								if(updateData.date>29||updateData.date<1)
								{
									printf("Leap year's February day must be in 01 to 29\n");	//2월에는 29일 까지 있습니다.
									date_success=0;
									month_success=0;
								}
								else
								{
									date_success=1;
									month_success=1;
								}
							}
						}
						else if(updateData.date>28||updateData.date<1)		// 1일 부터 28일 까지 입력했는지 확인
						{
							printf("Please Set date between 01 to 28\n");
							date_success=0;
						}
						else
						{
							date_success=1;
							//printf("date : %d\n",updateData.date);
						}
					}
					
					else
					{
						printf("Please Enter NUMBER in day!!\n");
					}// 일단위 체크 끝
				}
				else
				{
					printf("Please Set month between 01 to 12!!\n");
					printf("Days follow the months!!\n");
					month_success=0;
				}
			}
			else
			{
				if(mm[0]>0x2f&&mm[0]<0x3a&&mm[1]>0x2f&&mm[1]<0x3a)
				{
					 printf("Please Enter NUMBER in Day!!\n");
				}
				printf("Please Enter NUMBER in month!!\n");
			}// 월단위 체크 끝
			
			if(yy[0]>0x2f&&yy[0]<0x3a&&yy[1]>0x2f&&yy[1]<0x3a)	 // 년단위에 숫자를 입력했는지 확인  //입력값이 알맞으면 if문에 들어간다.
			{	 year_success=1;
				//윤년의 2월달 일을 판단하는 if문
			
			}
			else
			{
				printf("Please Enter NUMBER in year!!\n");
				year_success==0;
				
			}// 년단위 체크 끝
			
			if(second_success==1&&min_success==1&&hour_success==1&&date_success==1&&month_success==1&&year_success==1)//	모든 입력 값이 올바를때 updateData 가 값을 stTime에 넘겨준다.
			{
				success_flag=1;
				DS1302_SetTimeDates(updateData);
			}
			
			if(success_flag==1){	// 실제로 프린트가 시작되는 부분
				printf("\n\ntime update success!!!!\n");
				DS1302_GetTime(&stTime);
				DS1302_GetDate(&stTime);
				printf("date %04d:%02d:%02d\n", 2000+stTime.year, stTime.month, stTime.date);
				printf("time %02d:%02d:%02d\n", stTime.hour, stTime.minutes, stTime.seconds);
				success_flag=0;
			}
			
		}
		else	 // 3가지 커멘드이 이외에 것을 입력했을 경우 생기는 안내 문구
		{
			printf("Please enter 'help' to use this device\n");
		}
		
	}
}

void updateDateTime()
{
	uint8_t rxdata=0;
	struct _ds1302 updateData;
	
	// year:
	// month:
	// date:
	// hour:
	// minute:
	// sec:
	for (int i=0; i < 6; i++)
	{
		switch (i)
		{
			case 0:  // 년
			printf("year(00~99): ");
			rxdata = get_number();
			updateData.year = rxdata;
			printf("set year: %d\n", updateData.year);
			break;
			case 1:  // 월
			printf("month: ");
			rxdata = get_number();
			updateData.month = rxdata;
			printf("set month: %d\n", updateData.month);
			break;
			case 2:   // 일
			printf("date: ");
			rxdata = get_number();
			updateData.date = rxdata;
			printf("set date: %d\n", updateData.date);
			break;
			case 3:   // 시
			printf("hour: ");
			rxdata = get_number();
			updateData.hour = rxdata;
			printf("set hour: %d\n", updateData.hour);
			break;
			case 4:   // 분
			printf("minutes: ");
			rxdata = get_number();
			updateData.minutes = rxdata;
			printf("set minutes: %d\n", updateData.minutes);
			break;
			case 5:   // 초
			printf("sec: ");
			rxdata = get_number();
			updateData.seconds = rxdata;
			printf("set sec: %d\n", updateData.seconds);
			break;
			break;
		}
	}
	DS1302_SetTimeDates(updateData);
	return 0;
}

uint8_t get_number()
{
	uint8_t rxdata=0, *rxstring;
	
	while(isRxString()==0)
	;
	rxstring = getRxString();
	rxdata = atoi(rxstring);
	
	return rxdata;
}

 

DS1302.c

/*
 * DS1302.c
 *
 * Created: 2019-07-11 오후 2:09:16
 */ 
#include "DS1302.h"


struct _ds1302 stTime;

char *dayofweek[7] = {"SUN", "MON", "TUE", "WED",
	"THU", "FRI", "SAT"};

void DS1302_Init(void)
{
	DS1302_CLK_DDR |= (1<<DS1302_CLK);
	DS1302_DAT_DDR |= (1<<DS1302_DAT);
	DS1302_RST_DDR |= (1<<DS1302_RST);
}

void DS1302_Selected(void)
{
	DS1302_RST_PORT |= (1<<DS1302_RST); // CE High
}

void DS1302_Deselected(void)
{
	DS1302_RST_PORT &= ~(1<<DS1302_RST); // CE High
}

void DS1302_Clock(void)
{
	DS1302_CLK_PORT &= ~(1<<DS1302_CLK); // clk l->h->l
	DS1302_CLK_PORT |= (1<<DS1302_CLK);
	DS1302_CLK_PORT &= ~(1<<DS1302_CLK);

}

void DS1302_DataBitSet(void)
{
	DS1302_DAT_PORT |= (1<<DS1302_DAT); // data bit high
}

void DS1302_DataBitReset(void)
{
	DS1302_DAT_PORT &= ~(1<<DS1302_DAT); // data bit low
}


uint8_t DS1302_Read_DataPin(void)
{
	return (DS1302_DAT_PIN & (1<<DS1302_DAT));
}

void DS1302_Change_ReadMode(void)
{
	DS1302_DAT_DDR &= ~(1<<DS1302_DAT); // read mode
}

void DS1302_Change_WriteMode(void)
{
	DS1302_DAT_DDR |= (1<<DS1302_DAT); // write mode
}

uint8_t decimal_to_bcd(uint8_t decimal)
{
	return ( ((decimal/10)<<4) | (decimal%10) );
}

uint8_t bcd_to_decimal(uint8_t bcd)
{
	return ( ((bcd>>4) * 10) + (bcd & 0x0f) );
}

void DS1302_TxData(uint8_t txData)
{
	DS1302_Change_WriteMode();
	for (int i=0; i<8; i++)
	{
		if (txData & (1<<i))
		DS1302_DataBitSet();
		else
		DS1302_DataBitReset();
		
		DS1302_Clock();
	}
}

uint8_t DS1302_RxData(void)
{
	uint8_t rxData = 0;
	DS1302_Change_ReadMode();
	for (int i=0; i<8; i++)
	{
		rxData |= DS1302_Read_DataPin() ? (1<<i) : 0;
		// data = A ? b : c;  A가 참이면 b 반환, A가 거짓이면 c 반환
		DS1302_Clock();
	}
	return rxData;
}

void DS1302_WriteData(uint8_t address, uint8_t data)
{
	DS1302_Selected();
	DS1302_TxData(address);
	DS1302_TxData(decimal_to_bcd(data));
	DS1302_Deselected();
}

uint8_t DS1302_ReadData(uint8_t address)
{
	uint8_t rxData = 0;
	DS1302_Selected();
	DS1302_TxData(address+1);
	rxData = DS1302_RxData();
	DS1302_Deselected();
	
	return bcd_to_decimal(rxData);
}



void DS1302_GetTime(DS1302 *timeData)
{
	timeData->seconds = DS1302_ReadData(ADDRESS_SECONDS); // sec
	timeData->minutes = DS1302_ReadData(ADDRESS_MINUTES);
	timeData->hour = DS1302_ReadData(ADDRESS_HOUR);
}

void DS1302_GetDate(DS1302 *dateData)
{
	dateData->date = DS1302_ReadData(ADDRESS_DATE);
	dateData->month = DS1302_ReadData(ADDRESS_MONTH);
	dateData->dayofweek = DS1302_ReadData(ADDRESS_DAYOFWEEK);
	dateData->year = DS1302_ReadData(ADDRESS_YEAR);
}

void DS1302_SetTimeDates(DS1302 timeDate)
{
	DS1302_WriteData(ADDRESS_SECONDS, timeDate.seconds);
	DS1302_WriteData(ADDRESS_MINUTES, timeDate.minutes);
	DS1302_WriteData(ADDRESS_HOUR, timeDate.hour);
	DS1302_WriteData(ADDRESS_DATE, timeDate.date);
	DS1302_WriteData(ADDRESS_MONTH, timeDate.month);
	DS1302_WriteData(ADDRESS_DAYOFWEEK, timeDate.dayofweek);
	DS1302_WriteData(ADDRESS_YEAR, timeDate.year);
}

 

 DS1302.h

/*
 * DS1302.h
 *
 * Created: 2019-07-11 오후 2:09:32
 */ 


#ifndef DS1302_H_
#define DS1302_H_

#include <avr/io.h>

#define DS1302_CLK_DDR		DDRG
#define DS1302_CLK_PORT		PORTG
#define DS1302_DAT_DDR		DDRG
#define DS1302_DAT_PORT		PORTG
#define DS1302_DAT_PIN		PING
#define DS1302_RST_DDR		DDRG
#define DS1302_RST_PORT		PORTG
#define DS1302_CLK			0
#define DS1302_DAT			1
#define DS1302_RST			2

#define ADDRESS_SECONDS		0x80
#define ADDRESS_MINUTES		0x82
#define ADDRESS_HOUR		0x84
#define ADDRESS_DATE		0x86
#define ADDRESS_MONTH		0x88
#define ADDRESS_DAYOFWEEK	0x8a
#define ADDRESS_YEAR		0x8c

typedef struct _ds1302
{
	uint8_t seconds;
	uint8_t minutes;
	uint8_t hour;
	uint8_t date;
	uint8_t month;
	uint8_t dayofweek; //sun=1, mon=2... sat=7
	uint8_t year;
	uint8_t ampm; // 0:pm, 1:am
	uint8_t hourMode; // 0:24, 1:12
	//char *paDayofweek[7];
}DS1302;

extern struct _ds1302 stTime;
extern char *dayofweek[7];

void DS1302_Init(void);
void DS1302_Selected(void);
void DS1302_Deselected(void);
void DS1302_Clock(void);
void DS1302_DataBitSet(void);
void DS1302_DataBitReset(void);
uint8_t DS1302_Read_DataPin(void);
void DS1302_Change_ReadMode(void);
void DS1302_Change_WriteMode(void);
uint8_t decimal_to_bcd(uint8_t decimal);
uint8_t bcd_to_decimal(uint8_t bcd);
void DS1302_TxData(uint8_t txData);
uint8_t DS1302_RxData(void);
void DS1302_WriteData(uint8_t address, uint8_t data);
uint8_t DS1302_ReadData(uint8_t address);
void DS1302_GetTime(DS1302 *timeData);
void DS1302_GetDate(DS1302 *dateData);
void DS1302_SetTimeDates(DS1302 timeDate);



#endif /* DS1302_H_ */

 

uart0.c

/*
 * uart0.c
 *
 * Created: 2021-08-17 오전 10:26:57
 */ 
#define F_CPU 16000000UL

#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>   // interrupt 관련 lib가 들어 있다. 
#include "uart0.h"

volatile uint8_t rxString[100]={0};   
volatile uint8_t rxReadyFlag=0;   // \n detect flag 
volatile int rxindex=0;

// UART0로 부터 1byte가 들어 오면 이것을 자동 실행
// RX interrupt 서비스 루틴
ISR(USART0_RX_vect)
{
	volatile uint8_t data;
	
	data = UDR0;    // UART 하드웨어 버퍼 UDR0를 읽어서 data에 저장 
	
	if (data == '\n' || data == '\r')   // led1on\n
	{                                   // 
		rxString[rxindex] = '\0';
		rxindex=0;
		rxReadyFlag=1;      // 완전한 msg를 받았다는 신호를 알려준다. 
	}
	else
	{
		rxString[rxindex++] = data;   //  rxString[rxindex] = data;   rxindex++;
	}
}

uint8_t isRxString()
{
	return rxReadyFlag;
}

uint8_t *getRxString()
{
	rxReadyFlag=0;
	return rxString;
}
// uart0를 초기화 하는 함수
#define BAUD 9600
#define BAUD_9600  ( (F_CPU / (BAUD * 8)) -1)   // 207
void UART0_init(void)
{
	UBRR0H = 0x00;
	UBRR0L = 207;   // 9600으로 설정
	
	UCSR0A |= ( 1 << U2X0);   // 2배속 sampling속도를 8로 
	UCSR0C |= 0x06;   // 비동기, data길이: 8bit/nonpairty/1stopbit
	// UART0를 송신.수신이 가능 하도록 enable
	// RXEN0 : 수신이 가능 하도록 enable 
	// TXEN0  : 송신이 가능 하도록 
	// RXCIE0  : UART0로 부터 1byte가 들어 오면 interrupt가 뜨도록 설정 
	UCSR0B = ( (1 << RXEN0) | (1 << TXEN0) | (1 << RXCIE0));
}
// UART0로 1byte를 전송하는 함수
void UART0_transmit(char data)
{
	while ( !(UCSR0A & (1 << UDRE0)))   // UDRE0의 bit가 1이 되는순간 exit
		;
	UDR0 = data;   // UDR(Uart Data Register)에 값을 넣는다. 
}
// UART0로 부터 1byte를 읽어 오는 함수
unsigned char UART0_receive(void)
{
	// 76543210
	// 1   ===> RXC0 bit (RX complet)
	while ( !(UCSR0A & (1 << RXC0)))   // RXC0의 bit가 1이 되는순간 exit
		;      // nop : no operation
	
	return UDR0;   // 수신된 1byte를 return 	
}
/*
*  UART0로 string(문자열: 끝은 \0)을 출력 하는 함수 
*/
void UART0_print_string(char *str)
{
	for (int i=0; str[i] != '\0'; i++)
	{
		UART0_transmit(str[i]);
	}
}

 

uart0.h

/*
 * uart0.h
 *
 * Created: 2021-08-17 오전 10:26:36
 *  Author: kcci
 */ 


#ifndef UART0_H_
#define UART0_H_

void UART0_init(void);
void UART0_transmit(char data);
unsigned char UART0_receive(void);
void UART0_print_string(char *str);
void UART0_tx_rx_test(void);
uint8_t isRxString();
uint8_t *getRxString();

#endif /* UART0_H_ */

 

main.c

/*
 * UART0.c
 *
 * Created: 2021-08-20 오전 10:20:19
 * Author : KHJ
 */ 
#define F_CPU 16000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <string.h>
#include <stdio.h>  
#include <avr/interrupt.h>   // interrupt 관련 lib가 들어 있다. 
#include "uart0.h"
#include "ds1302.h"

// printf를 동작 시키위한 mapping작업 
FILE OUTPUT = FDEV_SETUP_STREAM(UART0_transmit, NULL, _FDEV_SETUP_WRITE);

int main(void)
{
	// printf 초기화
	stdout = &OUTPUT;   // FILE : 1(stdout) 0: stdin 2:stderr
	
	DS1302_Init();
	UART0_init();
	sei();	

	uint8_t prevSec;    // 1초 1번씩 시간을 출력 하기 위한 변수 
	
	printf("\n-- help --\n");
	printf("gettime\n");
	printf("settimeyymmddhhmmss\n");
    //gettime
	//settimeyymmddhhmmss
    while (1) 
    {
		menu_exec();
    }
}

void UART0_tx_rx_test(void)
{
	unsigned char data;
	
	UART0_init();   // UART0 setup or 초기화
	
	UART0_print_string("UART0 loop back test !!!!\n");
	
    while (1)
    {
#if 1
		UART0_transmit(UART0_receive());  
#else 
		data = UART0_receive(); 
	    UART0_transmit(data);
#endif 
    }	
}

 

동작 동영상 

https://youtu.be/nKaxJhoYdiM

https://youtu.be/j7eEnlmHnps

https://youtu.be/BEEbnxPkO40

https://youtu.be/sHxykv9S5mQ

https://youtu.be/hxc8qqCxXn8

https://youtu.be/7-_rPI-ftwI

https://youtu.be/nNFYbShMsGA

 

댓글