atmega128 time clock and alarm setting

Go To Last Post
4 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

i don't know how do i make a menu and it works.

 

please help me

 

Use Atmel Studio 7.0 and ATMEGA128

 

clock and alarm is working but i can't setting time or alarm time use switch.

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
/*
PORT

a Switch(1 select, 3 up, 4 down, 5 left, 6 right)(select, up,down,left,right)
b Buzzer (5)
c LED 4개 (1,345) 2없음 주의
d LCD date (1~8)
f LCD control(1RS 2RW 3E)
e (none)

*/





// ATmega128의 ë ˆì§€ìŠ¤í„° 등이 ì •ì˜ë˜ì–´ 있음
#include <avr/io.h>
#define F_CPU 1600000UL
#include <util/delay.h>
#include <avr/interrupt.h>
#include <stdio.h>

#define sbi(x, y) (x |= (1 << y))  // x의 y 비트를 ì„¤ì •(1)
#define cbi(x, y) (x &= ~(1 << y)) // x의 y 비트를 클리어(0)

// CON 포트는 포트 F와 연결됨을 ì •ì˜
#define LCD_CON      PORTF
// DATA 포트는 포트 D와 연결됨을 ì •ì˜
#define LCD_DATA     PORTD
// DATA 포트의 ì¶œë ¥ ë°©í–¥ ì„¤ì • 매크로를 ì •ì˜
#define LCD_DATA_DIR DDRD
// DATA 포트의 ìž…ë ¥ ë°©í–¥ ì„¤ì • 매크로를 ì •ì˜
#define LCD_DATA_IN  PIND
// RS ì‹ í˜¸ì˜ 비트 번호 ì •ì˜
#define LCD_RS   0
// RW ì‹ í˜¸ì˜ 비트 번호 ì •ì˜
#define LCD_RW   1
// E ì‹ í˜¸ì˜ 비트 번호 ì •ì˜
#define LCD_E    2

unsigned int count =0, sec=50, min=11,hour=11;
unsigned int ampm =0;
unsigned int cnt=0;

//알람 시간 ì„¤ì • 
unsigned int Alarm_min1=12,Alarm_hour1=11;
unsigned int Alarm_min2=0,Alarm_hour2=0;
unsigned int Alarm_min3=0,Alarm_hour3=0;
unsigned int Alarm_min4=0,Alarm_hour4=0;
unsigned int Alarm_ampm1 = 0, Alarm_ampm2 = 0,Alarm_ampm3 = 0, Alarm_ampm4 = 0;

//알람 on/off ì„¤ì •
unsigned int Alarm_status = 0;

//메뉴
unsigned int mode = 1;

void io_init(void)
{
	MCUCR|=(1<<SRE) | (1<<SRW10);
	XMCRA=(1<<SRL2) | (0<<SRL1) | (0<<SRL0) | (1<<SRW01) | (1<<SRW00) | (1<<SRW11);
	XMCRB |= 0x00;
}

// 텍스트 LCDë¡œ 부터 상태(ëª…ë ¹)를 읽는 함수
unsigned char LCD_rCommand(void){
	unsigned char temp=1;
	
	LCD_DATA_DIR = 0X00;
	
	cbi(LCD_CON, LCD_RS); // 0번 비트 클리어, RS = 0, ëª…ë ¹
	sbi(LCD_CON, LCD_RW); // 1번 비트 ì„¤ì •, RW = 1, 읽기
	sbi(LCD_CON, LCD_E);  // 2번 비트 ì„¤ì •, E = 1
	_delay_us(1);
	
	temp = LCD_DATA_IN;      // ëª…ë ¹ 읽기
	_delay_us(1);
	
	cbi(LCD_CON, LCD_E);  // ëª…ë ¹ 읽기 동작 끝
	
	LCD_DATA_DIR = 0XFF;
	_delay_us(1);
	
	return temp;
}

// 텍스트 LCD의 비지 플래그 상태를 확인하는 함수
char LCD_BusyCheck(unsigned char temp){
	if(temp & 0x80)          return 1;
	else            return 0;
}

// 텍스트 LCD에 ëª…ë ¹ì„ ì¶œë ¥í•˜ëŠ” 함수 - 단, 비지플래그 체크하지 않음
void LCD_wCommand(char cmd){
	cbi(LCD_CON, LCD_RS); // 0번 비트 클리어, RS = 0, ëª…ë ¹
	cbi(LCD_CON, LCD_RW); // 1번 비트 클리어, RW = 0, 쓰기
	sbi(LCD_CON, LCD_E);  // 2번 비트 ì„¤ì •, E = 1
	
	LCD_DATA = cmd;          // ëª…ë ¹ ì¶œë ¥
	_delay_us(1);
	cbi(LCD_CON, LCD_E);  // ëª…ë ¹ 쓰기 동작 끝
	
	_delay_us(1);
}

// 텍스트 LCD에 ëª…ë ¹ì„ ì¶œë ¥í•˜ëŠ” 함수 - 단, 비지플래그 체크함
void LCD_wBCommand(char cmd){
	while(LCD_BusyCheck(LCD_rCommand()))
	_delay_us(1);
	cbi(LCD_CON, LCD_RS); // 0번 비트 클리어, RS = 0, ëª…ë ¹
	cbi(LCD_CON, LCD_RW); // 1번 비트 클리어, RW = 0, 쓰기
	sbi(LCD_CON, LCD_E);  // 2번 비트 ì„¤ì •, E = 1
	
	LCD_DATA = cmd;          // ëª…ë ¹ ì¶œë ¥
	_delay_us(1);
	cbi(LCD_CON, LCD_E);  // ëª…ë ¹ 쓰기 동작 끝
	
	_delay_us(1);
}

// 텍스트 LCD를 초기화하는 함수
void LCD_Init(void){
	//_delay_ms(100);
	// 비지 플래그를 체크하지 않는 Function Set
	//LCD_wCommand(0x38);
	//_delay_ms(10);
	// 비지 플래그를 체크하지 않는 Function Set
	//LCD_wCommand(0x38);
	//_delay_us(200);
	// 비지 플래그를 체크하지 않는 Function Set
	//LCD_wCommand(0x38);
	//_delay_us(200);
	
	// 비지 플래그를 체크하는 Function Set
	LCD_wBCommand(0x38);
	// 비지 플래그를 체크하는 Display On/Off Control
	LCD_wBCommand(0x0c);
	// 비지 플래그를 체크하는 Clear Display
	LCD_wBCommand(0x01);
}

// 텍스트 LCD에 1바이트 데이터를 ì¶œë ¥í•˜ëŠ” 함수
void LCD_wData(char dat){
	while(LCD_BusyCheck(LCD_rCommand()))
	_delay_us(1);
	
	sbi(LCD_CON, LCD_RS); // 0번 비트 ì„¤ì •, RS = 1, 데이터
	cbi(LCD_CON, LCD_RW); // 1번 비트 클리어, RW = 0, 쓰기
	sbi(LCD_CON, LCD_E); // 2번 비트 ì„¤ì •, E = 1
	
	LCD_DATA = dat;       // 데이터 ì¶œë ¥
	_delay_us(1);
	cbi(LCD_CON, LCD_E);  // 데이터 쓰기 동작 끝
	
	_delay_us(1);
}

// 텍스트 LCD에 문자열을 ì¶œë ¥í•˜ëŠ” 함수
void LCD_wString(char *str){
	while(*str)
	LCD_wData(*str++);
}

void LCD_Clear(void)
{
		cbi(LCD_CON, LCD_RS); // 0번 비트 클리어, RS = 0, ëª…ë ¹
		cbi(LCD_CON, LCD_RW); // 1번 비트 클리어, RW = 0, 쓰기
		cbi(LCD_CON, LCD_E);  // 2번 비트 클리어, E = 0
		
		PORTD = 0x01;
		_delay_ms(2);
}

// C 언어의 주 실행 함수
int main(void)
{
	//포트 ìž…ì¶œë ¥  ìž…ë ¥ : 1 / ì¶œë ¥ : 0
	// 포트 B의 ë°©í–¥ ì„¤ì •(LCD 컨트롤 1~3번) : ìž…ë ¥
	DDRF = 0xff;
	
	// 포트 D의 ë°©í–¥ ì„¤ì •(LCD 데이터 1~8번) : ìž…ë ¥
	DDRD = 0xff;
	
	//포트 A의 ë°©í–¥ ì„¤ì •(스위치 1,3456번/2번없음 주의) : ì¶œë ¥
	DDRA = 0b00111101;
	
	//포트 B의 ë°©í–¥ ì„¤ì •(ë¶€ì € on / 5번) : ìž…ë ¥
	DDRB = 0xff;
	
	//포트 C의 ë°©í–¥ ì„¤ì •(LED1 ,345번/2번없음 주의) : ìž…ë ¥
	DDRC = 0xff;
	
	unsigned char time[16];
	unsigned char Alarm_time[16];
	unsigned char mode_name1[16];
	unsigned char mode_name2[16];
	unsigned char Alarm_onoff[16];
	
	// int button = ((PINA & 0xff)); //버튼
	unsigned int fill_box = 1; //약통번호
	
	io_init();
	LCD_Init();         // 텍스트 LCD 초기화 - 함수 호출
	
	TIMSK = 0x01; // R/W ì„ íƒ TIMER 0 사용
	TCCR0 =0x04; // 분주비 64
	TCNT0 =6; // 6에서 시작 255가되어 256이 되면 OVF가 되어 인터럽트 구문을 실행한다.
	sei();
	
	if(mode>4)
	mode = 1;
	else if(mode<1)
	mode = 4;
	
	if(fill_box>4)
	fill_box = 1;
	else if(fill_box<1)
	fill_box = 4;
	
	
	
/*while 문 시작(기본화면)*************************************************************************************************************************/

	while(1)
	{
		Alarm_set();//알람 ì„¤ì •
		
		
		// LCD 화면
		LCD_wBCommand(0x80 | 0x00);  // DDRAM Address = 0 ì„¤ì •
		sprintf(mode_name1,"Smart Fill Box");
		LCD_wString(mode_name1);
	
		LCD_wBCommand(0x80 | 0x40);  // DDRAM Address = 0x40 ì„¤ì •
		sprintf(time,"TIME %2d:%2d:%2d %2s" ,hour,min,sec,(ampm==1)?"AM":"PM");
		LCD_wString(time);     // 텍스트 LCD 문자열 ì¶œë ¥
		
		
		
		/*기본화면에서 확인버튼이 ëˆŒë ¸ì„ë–„**********************************************************************************************************************/
		
		
		if(PINA0 == 0)
		{
			cnt++;
			_delay_ms(10);
			/*ì‹œê°„ì„¤ì •******************************************************************************************************************************/
			if( cnt = 150)
			{
				LCD_Clear();
				LCD_wBCommand(0x80 | 0x00);
				sprintf(mode_name1,"1. Time Set");
				LCD_wString(mode_name1);
				
				_delay_ms(100);//ë”œë ˆì´ 
		
				if((PINA & 0xff) == 0x04)
				mode++;
				else if((PINA & 0xff) == 0x08)
				mode--;
		
				if((PINA & 0xff)== 0x01)
				{
					LCD_Clear();
					LCD_wBCommand(0x80 | 0x00);
					LCD_wString(mode_name1);
					LCD_wBCommand(0x80 | 0x40);
					sprintf(time,"Time %2d:%2d:%2d",hour,min,sec,(ampm==0)?"AM":"PM");
					
					unsigned int num = 1;
					if(num >3)
					num = 1;
					else if(num<1)
					num = 3;
					
					switch((PINA & 0xff))
					{
						case 0x01: //확인버튼
						break;
		
						case 0x04: //상
						switch(num)
						{
							case 1:
							hour++;
							break;
							
							case 2:
							min++;
							break;
							
							case 3:
							sec = 0;
							break;
						}
						break;
		
						case 0x08: //하
						switch(num)
						{
							case 1:
							hour--;
							break;
							
							case 2:
							min--;
							break;
							
							case 3:
							sec = 0;
							break;
						}
						break;
		
						case 0x10: //좌
						num--;
						break;
		
						case 0x20: //ìš°
						num++;
						break;
					}
				}
			}
		
			/*알람 시간 ì„¤ì •******************************************************************************************************************************/

			else if(mode = 2)
			{
				LCD_Clear();
				LCD_wBCommand(0x80 | 0x00);
				sprintf(mode_name1,"2. Alarm Set");
				LCD_wString(mode_name1);
				
				if((PINA & 0xff) == 0x04)
				mode++;
				else if((PINA & 0xff) == 0x08)
				mode--;
				
				if((PINA & 0xff)== 0x01)
				{
					if((PINA & 0xff) == 0x04)
					fill_box++;
					else if((PINA & 0xff) == 0x08)
					fill_box--;
					
					LCD_Clear();
					
					LCD_wBCommand(0x80 | 0x00);
					LCD_wString(mode_name1);
					
					LCD_wBCommand(0x80 | 0x40);
					sprintf(mode_name2,"Select Box : %2d",fill_box);
					LCD_wString(mode_name2);
					
					if ((PINA & 0xff) == 0x01)
					{
						unsigned int num = 1;
						if(num >2)
						num = 1;
						else if(num<1)
						num = 2;
		
						switch(fill_box)
						{
							/*1번 박스***************************************************************/
							case 1:
							LCD_Clear();
		
							lcd_wbcommand(0x80 | 0x00);
							LCD_wString(mode_name1);
		
							lcd_wbcommand(0x80 | 0x40);
							sprintf(Alarm_time,"%2d:%2d",Alarm_hour1,Alarm_min1);
							LCD_wString(Alarm_time);
		
							switch((PINA & 0xff))
							{
								case 0x01: //확인버튼
								break;
		
								case 0x04: //상
								switch(num)
								{
									case 1:
									Alarm_hour1++;
									break;
								
									case 2:
									Alarm_min1++;
									break;
								}
								break;
		
								case 0x08: //하
								switch(num)
								{
									case 1:
									Alarm_hour1++;
									break;
							
									case 2:
									Alarm_min1++;
									break;
								}
								break;
		
								case 0x10: //좌
								num--;
								break;
		
								case 0x20: //ìš°
								num++;
								break;
							}
							break;
		
							/*2번 박스***************************************************************/
							case 2:
							LCD_Clear();
					
							lcd_wbcommand(0x80 | 0x00);
							LCD_wString(mode_name1);
					
							lcd_wbcommand(0x80 | 0x40);
							sprintf(Alarm_time,"%2d:%2d",Alarm_hour2,Alarm_min2);
							LCD_wString(Alarm_time);
					
							switch((PINA & 0xff))
							{
								case 0x01: //확인버튼
								break;
	
								case 0x04: //상
								switch(num)
								{
									case 1:
									Alarm_hour2++;
									break;
							
									case 2:
									Alarm_min2++;
									break;
								}
								break;
	
								case 0x08: //하
								switch(num)
								{
									case 1:
									Alarm_hour2++;
									break;
							
									case 2:
									Alarm_min2++;
									break;
								}
								break;

								case 0x10: //좌
								num--;
								break;
	
								case 0x20: //ìš°
								num++;
								break;
							}
							break;
		
							/*3번 박스***************************************************************/
							case 3:
							LCD_Clear();
	
							lcd_wbcommand(0x80 | 0x00);
							LCD_wString(mode_name1);
	
							lcd_wbcommand(0x80 | 0x40);
							sprintf(Alarm_time,"%2d:%2d",Alarm_hour3,Alarm_min3);
							LCD_wString(Alarm_time);
	
							switch((PINA & 0xff))
							{
								case 0x01: //확인버튼
								break;
		
								case 0x04: //상
								switch(num)
								{
									case 1:
									Alarm_hour3++;
									break;
							
									case 2:
									Alarm_min3++;
									break;
								}
								break;
		
								case 0x08: //하
								switch(num)
								{
									case 1:
									Alarm_hour3++;
									break;
									
									case 2:
									Alarm_min3++;
									break;
								}
								break;
		
								case 0x10: //좌
								num--;
								break;
	
								case 0x20: //ìš°
								num++;
								break;
							}
							break;
		
					/*4번 박스***************************************************************/
							case 4:
							LCD_Clear();
							
							lcd_wbcommand(0x80 | 0x00);
							LCD_wString(mode_name1);
							
							lcd_wbcommand(0x80 | 0x40);
							sprintf(Alarm_time,"%2d:%2d",Alarm_hour4,Alarm_min4);
							LCD_wString(Alarm_time);
							
							switch((PINA & 0xff))
							{
								case 0x01: //확인버튼
								break;
		
								case 0x04: //상
								switch(num)
								{
									case 1:
									Alarm_hour4++;
									break;
							
									case 2:
									Alarm_min4++;
									break;
								}
								break;
		
								case 0x08: //하
								switch(num)
								{
									case 1:
									Alarm_hour4++;
									break;
									
									case 2:
									Alarm_min4++;
									break;
								}
								break;
		
								case 0x10: //좌
								num--;
								break;
		
								case 0x20: //ìš°
								num++;
								break;
							}
							break;	
						}
					}
				}
			}
			/*alarm알람 on / off ì„¤ì •******************************************************************************************************************************/
			else if(mode = 3)
			{
				if((PINA & 0xff) == 0x01) //확인 버튼
				{
					if (Alarm_status = 0)
					{
						Alarm_status =1;
						sprintf(mode_name2,"ON",Alarm_onoff);
					}
						
					else if(Alarm_status = 1)
					{
						Alarm_status = 0;
						sprintf(mode_name2,"OFF",Alarm_onoff);
					}	
				}		
				LCD_Clear();
				lcd_wbcommand(0x80 | 0x00);
				sprintf(mode_name1,"3. Alarm on/off");
				
				LCD_wString(mode_name1);
				lcd_wbcommand(0x80 | 0x40);
				LCD_wString(mode_name2);
				
				if((PINA & 0xff) == 0x04)
				mode++;
				else if((PINA & 0xff) == 0x08)
				mode--;
			}
			/*나가기******************************************************************************************************************************/
			else if(mode = 4)//나가기
			{
				LCD_Clear();
				lcd_wbcommand(0x80 | 0x00);
				sprintf(mode_name1,"4. Exit");
				LCD_wString(mode_name1);
		
				if((PINA & 0xff) == 0x04)
				mode++;
				else if((PINA & 0xff) == 0x08)
				mode--;
		
				else if((PINA & 0xff) == 0x01) //확인 버튼
				break;
			}
		}
	}
			/*******************************************************************************************************************************/
			/*******************************************************************************************************************************/
		
	// 함수의 형태와 같이 ì •ìˆ˜í˜•(int)의 값을 반환함
	return 0; 
}

/*Buzzer ë¶€ì € 알림 ì„¤ì •**************************************************************************************************************************/
void Alarm_set(void)
{
	if((hour == Alarm_hour1 & min == Alarm_min1 & Alarm_status == 1) | (hour == Alarm_hour2 & min == Alarm_min2 & Alarm_status == 1) | (hour == Alarm_hour3 & min == Alarm_min3 & Alarm_status == 1) | (hour == Alarm_hour4 & min == Alarm_min4 & Alarm_status == 1) )
	{
		int i,j;
		
		for(i=0;i<20;i++)
		{
			for(j=0;j<12;j++)
			{
				PORTB=0x10;
				_delay_ms(1.04);
				PORTB=0x00;
				_delay_ms(1.04);
			}
			for(j=0;j<8;j++)
			{
				PORTB=0x10;
				_delay_ms(1.56);
				PORTB=0x00;
				_delay_ms(1.56);
			}
		}
		_delay_ms(2000); // 2000*(1.56+1.04) = 6000(1분)
	}
}


//timer
ISR(TIMER0_OVF_vect)
{
	TCNT0 =6;
	count++;
	if (count >1000){
		sec++; count=0;
		if(sec>=60){
			min++; sec=0;
			if (min>=60){
				hour++; min=0;
				if(hour>12){
					hour=0;
					if(ampm == 0) ampm =1;
					else if(ampm ==1) ampm=0;
					count =0;
				}
			}
		}
	}
}

Is the chip a mega128 or mega1281?? Big difference.

 

 

How do you make a menu?  Divide and conquer.

 

First up, write a function that reads the switches, debounces them and returns a keycode or a code that says button not pressed. eg: 0 = no button pressed, 1 = up, 2 = down and so on.

Then you think carefully about how the menu is to work. Write a set of rules.

Usually a technique called 'finite state machine' is used. This is usually a switch() statement. Each menu is a switch case. Write functions to do the increment/decrement of values. 

 

Or just Google. There must be a number of solutions out there - your application is hardly new.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

chip is mega 128

 

i try this first

hit switch1 > show menu on lcd

but it's not working

 

it sometime change so fast 'smart fill box' and '1.time set' (im not hit switch but it change)

while(1)
	{
		Alarm_set();//알람 ì„¤ì •
		
		
		// LCD 화면
		LCD_wBCommand(0x80 | 0x00);  // DDRAM Address = 0 ì„¤ì •
		sprintf(mode_name1,"Smart Fill Box");
		LCD_wString(mode_name1);
	
		LCD_wBCommand(0x80 | 0x40);  // DDRAM Address = 0x40 ì„¤ì •
		sprintf(time,"TIME %2d:%2d:%2d %2s" ,hour,min,sec,(ampm==1)?"AM":"PM");
		LCD_wString(time);     // 텍스트 LCD 문자열 ì¶œë ¥
		
		
		
		/*기본화면에서 확인버튼이 ëˆŒë ¸ì„ë–„**********************************************************************************************************************/
		
		
		if(PINA0 == 0)
		{
			cnt++;
			_delay_ms(10);
			/*ì‹œê°„ì„¤ì •******************************************************************************************************************************/
			if( cnt = 150)
			{
				LCD_Clear();
				LCD_wBCommand(0x80 | 0x00);
				sprintf(mode_name1,"1. Time Set");
				LCD_wString(mode_name1);

 

i will try just this first, throw it all behind.

thanks for your help :)

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You may want to google the words "cyclomatic complexity" then consider refactoring your code ;-)