BASIC4MCU | 2017년 128강좌 | [BK-AVR128] KEY 매트릭스 추가
페이지 정보
작성자 키트 작성일2017-09-12 15:08 조회1,779회 댓글0건본문
아래에 있는 4개의 키 때문에 코드를 작성하는데 시간이 좀 걸렸습니다.이런(그지같은)설계는 하지 않는 것이 좋습니다. --- ■ 경고 24x5로 4개 추가하고 싶으면 포트를 한개 더 할당하는 것이 좋습니다.^^PD4~PD7 출력은 PORTx를 0으로 두고서키 스캔 시에 해당 비트만 DDRx=1로 출력으로 설정해서 오픈드레인으로 작용하므로어느 키를 누르든, 몇개를 동시에 누르든 전기적인 데미지가 생기지 않습니다.소스전류는 PD0~PD3 입력핀의 내부 풀업저항 수십K옴 밖에 없습니다.아래 소스 분석하려면 머리좀 아프겠습니다.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211 #include#include//#define U08 unsigned char#define U16 unsigned int#define FU08 flash unsigned char//#define LCD_PORT PORTA#define LCD_C_WR PORTB=(PORTB&0x1F)|0x80#define LCD_D_WR PORTB=(PORTB&0x1F)|0xA0//#define LCD_EN_1 PORTB|=0x80#define LCD_EN_0 PORTB&=~0x80////#define LCD_RW_1 PORTB|=0x40//#define LCD_RW_0 PORTB&=~0x40////#define LCD_RS_1 PORTB|=0x20//#define LCD_RS_0 PORTB&=~0x20//#define SEC 0x80#define MIN 0x82#define HOUR 0x84#define DATE 0x86#define MONTH 0x88#define YEAR 0x8c//#define RTC_SCL PORTE.2 // PE2#define RTC_D_WR PORTE.3 // PE3#define RTC_D_RD PINE.3 // PE3#define RTC_D_DDR DDRE.3 // PE3#define RTC_RST PORTE.4 // PE4//U08 rtc_Init[8]={0x17,1,2,3,4,5,6,7}; // 시간초기값 년월일시분초U08 time[8]; // 년월일시분초U08 fnd[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E,0xFF}; //애노드U08 led_buf=0,fnd_buf[8]={0,},digit=5;U08 old_key=0,new_key,key_buf=0;//void LCD_DATA(U08 d){ LCD_PORT=d; LCD_D_WR; delay_us(1); LCD_EN_0; delay_us(50); }void LCD_CMD (U08 c){ LCD_PORT=c; LCD_C_WR; delay_us(1); LCD_EN_0; delay_ms( 3); }void LCD_POS(U08 c,U08 r){ LCD_CMD(0x80|(c+r*0x40)); }void LCD_CLR(void){ LCD_CMD(1); }void LCD_STR (U08 *s){ while(*s)LCD_DATA(*s++); }void LCD_STRf(FU08 *s){ while(*s)LCD_DATA(*s++); }//void LCD_INIT(void){delay_ms(50);LCD_CMD(0x38); LCD_CMD(0x38); LCD_CMD(0x38);LCD_CMD(0x0E); LCD_CMD(0x06); LCD_CLR();}//void write_ds1302(U08 addr, U08 data){U08 i;RTC_SCL=0; RTC_RST=1; delay_us(2);for(i=0;i<8;i++){if((addr>>i)&1)RTC_D_WR=1; else RTC_D_WR=0;delay_us(2); RTC_SCL=1; delay_us(1); RTC_SCL=0; delay_us(1);}for(i=0;i<8;i++){if((data>>i)&0x01)RTC_D_WR=1; else RTC_D_WR=0;delay_us(2); RTC_SCL=1; delay_us(1); RTC_SCL=0; delay_us(1);}RTC_RST=0;}//U08 read_ds1302(U08 addr){U08 i, data=0;RTC_RST=1; delay_us(2);//writefor(i=0;i<8;i++){if((addr>>i)&1)RTC_D_WR=1; else RTC_D_WR=0;delay_us(2); RTC_SCL=1; delay_us(1); RTC_SCL=0; delay_us(1);}// readRTC_D_DDR=0; RTC_D_WR=1;for(i=0;i<8;i++){data>>= 1;if(RTC_D_RD)data|=0x80;delay_us(1); RTC_SCL=1; delay_us(2); RTC_SCL=0; delay_us(1);}RTC_D_DDR=1; RTC_SCL=0; delay_us(1); RTC_RST=0;return data;}//void save_time(void){write_ds1302(YEAR,time[0]); write_ds1302(MONTH,time[1]);write_ds1302(DATE,time[2]); write_ds1302(HOUR, time[3]);write_ds1302(MIN, time[4]); write_ds1302(SEC, time[5]);}//void init_time(void){U08 i;for(i=0;i<8;i++)time[i]=rtc_Init[i];save_time();}//void get_time(void){time[0]=read_ds1302(YEAR +1); if(time[0]>0x99)init_time();time[1]=read_ds1302(MONTH+1); if(time[1]>0x12)init_time();time[2]=read_ds1302(DATE +1); if(time[2]>0x31)init_time();time[3]=read_ds1302(HOUR +1); if(time[3]>0x23)init_time();time[4]=read_ds1302(MIN +1); if(time[4]>0x59)init_time();time[5]=read_ds1302(SEC +1); if(time[5]>0x59)init_time();}//void disp_ymd(){fnd_buf[0]=2; fnd_buf[1]=0; //20fnd_buf[2]=time[0]>>4; fnd_buf[3]=time[0]&0x0F; //yyfnd_buf[4]=time[1]>>4; fnd_buf[5]=time[1]&0x0F; //mmfnd_buf[6]=time[2]>>4; fnd_buf[7]=time[2]&0x0F; //dddigit=8; //offled_buf=1; LCD_POS(0,0); LCD_STRf("1");}void disp_hms(){fnd_buf[0]=16; fnd_buf[1]=16; //offfnd_buf[2]=time[3]>>4; fnd_buf[3]=time[3]&0x0F; //hfnd_buf[4]=time[4]>>4; fnd_buf[5]=time[4]&0x0F; //mfnd_buf[6]=time[5]>>4; fnd_buf[7]=time[5]&0x0F; //sdigit=5; //onled_buf=0; LCD_POS(0,0); LCD_STRf("0");}//interrupt [TIM2_COMP] void timer2_comp_isr(void){ //100usstatic U08 cnt2=0,fnd_cnt=0,key_cnt1=0,key_cnt2=0;switch(cnt2){case 0: PORTA=~led_buf; PORTF|=8; PORTF&=~8; break; // led outcase 1: // fnd outPORTA=0; PORTF|=4; PORTF&=~4; // common offPORTC=fnd[fnd_buf[fnd_cnt]]; // segment dataif(fnd_cnt==digit)PORTC&=~0x80; // digit outPORTF|=2;PORTF&=~2; // 573 segment outPORTA=1<// common outif(++fnd_cnt>7)fnd_cnt=0;break;case 2:if(++key_cnt1>49){ key_cnt1=0; //50msswitch(key_cnt2){case 0:if((PIND&0x0F)!=0x0F)new_key=0;if(!PIND.0)new_key=17; if(!PIND.1)new_key=18; if(!PIND.2)new_key=19; if(!PIND.3)new_key=20;break;case 1:if((PIND&0x0F)==0x0F){new_key=0; DDRD.4=1; delay_us(1);if(!PIND.0)new_key=1; if(!PIND.1)new_key=5; if(!PIND.2)new_key=9; if(!PIND.3)new_key=13;DDRD.4=0; DDRD.5=1; delay_us(1);if(!PIND.0)new_key=2; if(!PIND.1)new_key=6; if(!PIND.2)new_key=10; if(!PIND.3)new_key=14;DDRD.5=0; DDRD.6=1; delay_us(1);if(!PIND.0)new_key=3; if(!PIND.1)new_key=7; if(!PIND.2)new_key=11; if(!PIND.3)new_key=15;DDRD.6=0; DDRD.7=1; delay_us(1);if(!PIND.0)new_key=4; if(!PIND.1)new_key=8; if(!PIND.2)new_key=12; if(!PIND.3)new_key=16;DDRD.7=0;}break;}if(++key_cnt2>1)key_cnt2=0;if(old_key!=new_key){ old_key=new_key; if(new_key)key_buf=new_key; }}break;case 3: case 4: case 5: case 6: case 7: case 8: case 9: break;}if(++cnt2>9)cnt2=0;}//void main(void){U08 tp;U16 i=0;DDRA=0xFF; // FND_COMMON & LED & lcd dataDDRC=0xFF; // FND_SEGMENTDDRF=0x0E; // LED & FND 573_selDDRB=0xE0; // LCD controlPORTD=0x0F; // KEY in:PD0~PD3, out:pd4~pd7led_buf=0; // led offRTC_RST=0; RTC_D_WR=0; RTC_SCL=0;DDRE=0x1C; // rtc PE2~PE4 outwrite_ds1302(0x8E,0); write_ds1302(0x90,0xA4);TCCR2=0x0B; OCR2= 24; TIMSK=0x80; //16000000/64/(1+ 24),100usLCD_INIT();SREG=0x80;while(1){delay_ms(1);if(++i>999){ get_time(); i=0; disp_ymd(); }if(i==500){ disp_hms(); }//if(key_buf){switch(key_buf){case 1: // yy증가tp=(time[0]>>4)*10+(time[0]&0x0F); // BCD to Binaryif(tp<99)tp++; // 증가tp=((tp/10)<<4)+(tp%10); // Binary to BCDwrite_ds1302(YEAR,tp);break;case 2: tp=(time[1]>>4)*10+(time[1]&0x0F); if(tp<12)tp++; tp=((tp/10)<<4)+(tp%10); write_ds1302(MONTH,tp); break; //mm증가case 3: tp=(time[2]>>4)*10+(time[2]&0x0F); if(tp<31)tp++; tp=((tp/10)<<4)+(tp%10); write_ds1302(DATE ,tp); break; //dd증가case 5: tp=(time[0]>>4)*10+(time[0]&0x0F); if(tp)tp--; tp=((tp/10)<<4)+(tp%10); write_ds1302(YEAR ,tp); break; //yy감소case 6: tp=(time[1]>>4)*10+(time[1]&0x0F); if(tp)tp--; tp=((tp/10)<<4)+(tp%10); write_ds1302(MONTH,tp); break; //mm감소case 7: tp=(time[2]>>4)*10+(time[2]&0x0F); if(tp)tp--; tp=((tp/10)<<4)+(tp%10); write_ds1302(DATE ,tp); break; //dd감소case 9: tp=(time[3]>>4)*10+(time[3]&0x0F); if(tp<23)tp++; tp=((tp/10)<<4)+(tp%10); write_ds1302(HOUR ,tp); break; //h증가case 10: tp=(time[4]>>4)*10+(time[4]&0x0F); if(tp<59)tp++; tp=((tp/10)<<4)+(tp%10); write_ds1302(MIN ,tp); break; //m증가case 11: tp=(time[5]>>4)*10+(time[5]&0x0F); if(tp<59)tp++; tp=((tp/10)<<4)+(tp%10); write_ds1302(SEC ,tp); break; //s증가case 13: tp=(time[3]>>4)*10+(time[3]&0x0F); if(tp)tp--; tp=((tp/10)<<4)+(tp%10); write_ds1302(HOUR ,tp); break; //h감소case 14: tp=(time[4]>>4)*10+(time[4]&0x0F); if(tp)tp--; tp=((tp/10)<<4)+(tp%10); write_ds1302(MIN ,tp); break; //m감소case 15: tp=(time[5]>>4)*10+(time[5]&0x0F); if(tp)tp--; tp=((tp/10)<<4)+(tp%10); write_ds1302(SEC ,tp); break; //s감소case 20: init_time(); break; //시간 초기화}key_buf=0;}}}동작시켜본 분은 답글로 인증샷 또는 동영상 남겨주세요^^
댓글 0
조회수 1,779등록된 댓글이 없습니다.