AVR 인공호흡 하기 - ATmega128 로 ATmega128 살리기


ATmega128을 가지고 놀다보면.. 전혀 예상치 못한 이유로 ATmega128이 죽어버릴때가 있습니다.
갑작스런 정전기나, 전원을 잘못연결했다거나... 아니면 아무것도 안했는데 동작을 안할때....

이럴땐 보통 오실레이터로 인공호흡을 해주면 살아나는 경우가 있습니다. 
하지만 인공호흡하려고 없는 오실레이터 사다가 인공호흡할수도 없는것이고...
옆에 있는건 아직 목숨이 붙어있는 ATmega128. 이녀석으로 어떻게 살려볼수 없을까 찾아보다 좋은 방법을 찾았습니다.
포트의 핀 출력을 High -> Low -> High -> Low .............  를 반복하면 클럭뛰는 효과를 낼수 있다는.....

일단 오실레이터를 연결해서 클럭이 어떻게 뛰나 확인해 보았습니다.
사용자 삽입 이미지

오실로스코프 회로.. 참 쉽죠잉??


사용자 삽입 이미지

4Mhz 오실레이터의 파형을 오실로스코프로 찍은 모습.



파형이 이쁘게 곡선을 그리며 올라가다가 절벽으로 떨어지는 파형을 보여주고 있습니다.
주기가 4.00114MHz 가 나오네요. 주기가 딱 4MHz가 나오진 않습니다.... 당연한건가요;;;;;;

이젠 살아있는 AVR로 펄스를 만들어 보겠습니다.. 아래의 소스를 컴파일해 살아있는 AVR에 Write해줍니다.

사용자 삽입 이미지

이놈의 파형이 어찌 나오는지 오실로 스코프로 찍어봅니다...
사용자 삽입 이미지
포트F에 설정해놨으니 포트F에 오실로스코프를 연결해야겠지요? ㅎㅎ 파형은 아래와 같습니다.


사용자 삽입 이미지
아까보단 깔끔하진 않네요... 울퉁불퉁... 모양이 산모양 같습니다..ㅎㅎ
주기는 약 2.66749MHz가 나오네요.. 이정도로도 충분히 인공호흡용 클럭이 될수 있을것 같습니다.


인제 준비는 모두 끝났습니다... 실제 AVR을 살해(?)후 인공호흡으로 살려 보겠습니다...
ATmega128은 비싸서 이런 실험 용도로는 부적합하다고 판정! 하나남은 ATmega8을 실험대상으로 삼았습니다
실험용 회로를 아래와 같이 구성하였습니다... (불쌍한 ATmega8....;;)
사용자 삽입 이미지
전원과 ISP만 구성하였습니다... 참 쉽죠잉??

AVR Studio 에서 연결 퓨즈비트와 Signature를 읽어보니 제대로 나오는군요..
사용자 삽입 이미지


이제 ATmega8을 살해하기 위해 퓨즈비트 설정에서 SUT_CKSEL 부분을 Ext. Crystal/Resonator High Freq.; Start-up Time : 16K CK + 64... 라고 써있는걸 선택후  Program 버튼을 지그시 눌러줍니다...
공부를 위한 안락사라고 생각하고 눈물을 머금고 누릅니다........ 클릭~


사용자 삽입 이미지
역시 한방에 가셨습니다.... Signature부분엔 WARNING이 뜨고... 퓨즈비트도 이상하게 읽혀집니다..


이제 아까 제작한 인공 클럭으로 살려보겠습니다... ATmega8의 XTAL1 핀은 9번핀 입니다.
9번핀에 아까 만든 인공호흡용 클럭을 연결시켜줍니다... 아래와 같이요....

사용자 삽입 이미지
이렇게 연결하고 다시 퓨즈비트와 Signature를 읽어 봅니다...


허허 신기합니다. 멀쩡하게 다시 동작을 하는군요!!!!!!
이렇게 멀쩡하게 동작할때 후딱 잘못 설정된 퓨즈비트의 클럭설정용 퓨즈비트를 제대로 설정해줍니다.
사용자 삽입 이미지
위 화면과 같이 SUT_CKSEL을 위와 같이 내부클럭 8MHz로 설정해주고 Program 버튼을 클릭합니다.

휴우~ 다시는 못볼줄 알았던 ATmega8이 살아났군요...ㅎㅎ

다음에도 혹시나 이런 불상사가 생기면 이런 방법으로 살려내면 되겠습니다...~
이 방법으로도 살아나지 않는다면..... 글쎄요... 저도 잘 모르겠습니다...ㅎㅎㅎㅎㅎㅎㅎ;;
2009/11/15 05:46 2009/11/15 05:46


ㄹㅔㅈㅕ
하드웨어/AVR 2009/11/15 05:46

댓글을 달아 주세요

  1. 김형원 2009/12/17 12:22  수정/삭제  댓글쓰기

    그런데요. 설정값을 변경했는데 ic가 죽었다고 하기엔 좀 그런거같아보여요. 다시 설정값만 해주면 되는거 아닌가요 ^^; 대부분 타거나 열받아서 죽는게 아닌가요? 그런건 복귀 가능한가요?

    • ㄹㅔㅈㅕ 2009/12/18 00:52  수정/삭제

      물론 설정값을 바꿨다고 IC가 죽는것은 아니지요.

      위에서 제가 설정을 한 것은 외부 크리스탈이 창작되어있지 않은 상태에서 퓨즈비트를 외부 크리스탈로 설정한 것입니다.
      이 경우 실제로 ATmega128이나 같은 atmega 계열 ic들은 동작을 하지 않게 됩니다.
      이런경우 AVR Studio 에서 hex파일을 write하려고 하면
      device missing or unknown device [-24] 라는 메시지가 뜨게 되지요.

      실제로 물리적으로 부셔졌거나, 과전류로 인해 IC가 타버린 경우가 아니라면 atmega계열의 mcu가 동작하지 않는 이유는 사용자나 또는 다른 이유로(EMI 영향 등..) 퓨즈비트 셋팅이 잘못되어 장치인식을 못하게 되는 경우가 대부분입니다.

      이런경우 강제로 외부 클럭을 넣어주면 ic를 다시 동작하게 할수 있는데요, 이를 인공호흡이라 합니다. 보통의 크리스탈로는 인공호흡을 하지 못하고, 오실레이터나 펑션 제너레이터같이 펄스를 만들어주는 장치로 인공호흡용 클럭을 만듭니다. 위 예제는 avr을 이용해 펄스를 만들어 인공호흡을 한 예제 입니다.

      쉽게말해 퓨즈비트 이상으로 동작하지 않는 avr칩을 인공적으로 클럭을 만들어 강제로 넣어주지 않게되면 못쓰게 되서 죽었다고 표현하는 것이죠. 물론 설정값만 다시 정상값으로 변경해주면 됩니다.

      하지만, 저런 과정 없이 설정값을 다시 셋팅할수 있을까요? 인식조차 되지 않을것입니다.

  2. 와우 2010/01/04 00:57  수정/삭제  댓글쓰기

    인공호흡이 이런의미였네요

    • ㄹㅔㅈㅕ 2010/01/07 23:19  수정/삭제

      ㅎㅎ저도 AVR을 처음 시작할때 인공호흡을 한다는말이 이해가 가지 않았었습니다.ㅋㅋ

ATmega8과 DS1307로 만든 시계 두번째 버전!!


  요전에 만든 시계(http://seoltang.com/389) 는 제 자취방에 시계가 없어서 하나 만들어 갖다놓을까? 하는 생각과 이번에 만들 시계의 연습용(?) 버전이었습니다..

하지만 이번엔 우리 엄니의 열화와 같은 성원으로(실은 시계 왜 안만들어오냐고 자꾸 그러셔서) 아주 이쁘게 만들었습니다^^ 다른분들이 보시기엔 별로 안이뻐보일수도 있습니다..  울엄마도 충분히 그러실수 있습니다....;;
하지만 제눈엔 무진장 이뻐보입니다.ㅋㅋ 제 자취방 갖다놓고 싶습니다...ㅋㅋㅋㅋㅋ


사용자 삽입 이미지

사진기가 꼬져서 이상하게 나오는군요.ㅜ.ㅜ

왼쪽에 홀로 켜져 있는 LED는 오후를 뜻하는 아래쪽 LED구요, 오전이되면 위에 LED가 켜집니다... 저거 녹색 LED인데 노란색으로 보이는군요..ㅡㅡ; 아크릴 색이랑 짬뽕됐나봅니다..

왼쪽 아래는 5볼트 전원입력단자가 있고 그 바로위에 ISP커넥터가 존재합니다..
제가 천재는 아니기 때문에 분명 시간이 잘 가다가 심하면 거꾸로 시간이 갈수도 있는 상황이 올지도 몰라 빼놨습니다... 시간 수정할때도 사용합니다ㅎㅎㅎ 버튼같은거 없습니다. 프로그램하기만 귀찮아집니다..

아.. 그리고 아크릴을 본드로 붙이면 하얗게되는 저 가생이(?)부분;; 저거 어떻게 처리해야 하나요?
다른분들은 깔끔하게 이쁘게 티안나게 붙이던데.. 본드가 다른건가? 내 본드는 Alaska601이라 써있는데...
그러고보니 용도가 고무,가죽,금속,유리 군요... 유리도 붙이나?ㅡㅡ;  뭐 암튼..

이번 주말에 집에가서 티비위에 떡하니 올려놔야겠습니다..ㅋㅋ

시계 버전2 소스 : http://seoltang.com/391 [비공개]
2009/10/15 23:33 2009/10/15 23:33


ㄹㅔㅈㅕ
하드웨어/AVR 2009/10/15 23:33

댓글을 달아 주세요

  1. Jason Jang 2009/10/19 19:40  수정/삭제  댓글쓰기

    본드가 다른 것이 분명합니다.

    "알라스카601"본드를 만든 나라, 용도, 성분 그리고 설명서 표시등은 잘 모르겠지만...
    아크릴 전용 본드가 따로 있습니다. 보통 맹물과 같이 투명하고 맹물과 같은 점도 입니다.
    보통은, 주사기에 넣고 바늘부분으로 흘려가면서 붙이더군요.
    접합부분의 가장자리도 당연히 변색이나 변형이 없습니다.
    문방구보다는 아마도 공구상가쯤에 가야 구할 수 있을 것 같네요.

    블로그 잘 봤습니다.

    • ㄹㅔㅈㅕ 2009/10/19 21:11  수정/삭제

      아.. 아크릴용 본드가 따로 있는것이군요.. 아무거나 붙이는게 아니고.ㅋㅋ 주사기도 있어야되고..ㅎㅎ 유용한정보 감사합니다^^

DS1307과 FND, 그리고 ATmega8로 시계 만들기.


제가 사는 자취방엔 시계가 없습니다...
그래서 시간을 보려면 꼭 핸드폰을 찾아서 열어보거나 컴퓨터 오른쪽 아래 구석탱이에 시간을 봐야 했지요.
그래서 벽시계가 하나 있으면 좋겠다 생각을 했지만 이제 졸업이 얼마 안남아서 사기도 돈아깝고,,
어디서 업어올 시계도 없고.. 해서 하나 만들기로 작정했습니다... 공부겸 겸사겸사...ㅎㅎ

일단 MCU는 동아리방에 하나 남은 ATmega8을 사용하기로 했습니다.
시계 IC는 옆동아리 상문이형한테 빌려온 DS1307과 32.768 크리스탈을 사용했습니다.
그리고 나머지 부품들은 모두 동아리방에 있었습니다.ㅎㅎ

이렇게 모아진 부품들을 납땜하고 배선하고 프로그램해서 시계가 동작될때까지 무려 6시간이 걸렸습니다.ㅡㅡ;
FND도 4개가 붙어있는건 캐소드형, 각각 하나씩 있는건 anode형이라서 연결하는것도 한참 생각했습니다..ㅎㅎ;;
그래도 다 연결하니 작동은 정상적으로 되네요..^^

사용자 삽입 이미지

좀 지저분 합니다..ㅋ FND 여러개, ATmega8, ULN2803, DS1307, 7805, 등등등등등등등,,,,
저래놓고 검은색 불투명 아크릴로 덮으면 깔끔해질것같아서.ㅎㅎ 하지만 아크릴이 없다는.... ;;
그래도 날짜랑 시간만 잘 나오면 되니 걱정 없습니다.ㅋㅋ


사용자 삽입 이미지

  뒷부분의 모습입니다... 왜 6시간이나 걸렸는지 아실겁니다.ㅡㅡ;; 0.5mm짜리 전선은 웬만한 스트리퍼로도 피복이 벗겨지지 않습니다.. 그래서 핀셋으로 일일히 하나하나 피복을 벗겨야 하는데 이게 생각만큼 쉽지가 않더군요.ㅎㅎ  지금 왼손 집게손가락이 아픕니다.ㅜ.ㅜ

이제 저 뒷부분은 글루건으로 도배를 해서 선이 끊어지지 않게 보호를 해야겠습니다...ㅎㅎ
혹시나 어디가 끊어져서 작동이 안되면 끊어진데가 어딘지 못찾을수도 있을것같아서...미리 예방을..ㅎㅎ

그럼 이 시계가 동작하는 모습을 보시겠습니다...




소스코드 위치 : http://seoltang.com/388 (비공개)

2009/10/12 07:24 2009/10/12 07:24


ㄹㅔㅈㅕ
하드웨어/AVR 2009/10/12 07:24

댓글을 달아 주세요

  1. Jason Jang 2009/10/27 19:35  수정/삭제  댓글쓰기

    제가 잘 몰라서 묻는데, ATmega8 이 맞아요? ATmega128이 맞습니까? 제목과 본문에 각각 달리 표시되어 있어서요.

    • ㄹㅔㅈㅕ 2009/10/27 20:36  수정/삭제

      ATmega8 이 맞습니다... 제가 오타를 냈네요..ㅎㅎ
      ATmega128은 저렇게 DIP 타입 소자가 없지요.. 핀수가 64개나 되는지라..ㅎㅎ 지적 감사합니다.

당근보드의 FND를 이용해 시계 만들기(DS1307 이용)


당근보드의 디스플레이 보드에는 4개의 FND와 8개의 LED(8개중 동시에 사용가능한 LED는 4개)가 있습니다.
또한 메인보드에는 DS1307과 32.768khz의 크리스탈이 달려 있습니다.
이제 이 소자들을 활용하여 당근보드를 시계로 사용해 보겠습니다.

사용자 삽입 이미지

당근보드 디스플레이부의 모습.

당근보드에는 위와 같은 디스플레이부가 있습니다. 보시다시피 8개의 LED가 있으며 4개의 점퍼 설정으로 시계처럼 LED를 사용할것인지, 아니면 밑에 4개의 LED가 일렬로 있는 부분을 사용할 것인지 정할수 있습니다.
저는 점퍼를 모두 위에 연결하여 시계부분에 있는 녹색1개, 노란색1개, 빨간색2개를 사용하겠습니다.
그리고 당연히 4개의 FND를 사용해야겠지요.

제가 쓰는 당근보드는 보드 색이 녹색입니다.(위 사진은 당근이의AVR갖고놀기 카페에서 가져왔습니다) 그리고 LED를 고휘도 LED로 달아놓았지요.. 볼땐 멋있었는데 시계로 해놓으니 눈아파서 못보겠네요.ㅡㅡ;
아무튼 녹색 LED를 '오전'을 표시하는 LED로, 노란색 LED를 '오후'를 표시하는 LED로 사용하겠습니다.
또한 중간의 빨간색 2개의 LED는 약 0.5초 간격으로 깜빡이는 용도로 사용합니다.

시계IC인 DS1307은 32.768Khz 크리스탈과 함께 사용하며, 년, 월, 일, 요일, 시, 분, 초 를 나타낼 수 있습니다.
통신 방식은 I2C(TWI) 이며, DATASHEET는 아래에서 다운 받을수 있습니다.


I2C는 따로 열심히 공부하셔야 하구요, 저는 대충만 공부하고 소스를 구해다가 입맞에 맞게 고쳐 쓴 것입니다...ㅎ
제가 사용한 소스를 공개합니다. 이 소스는 엄청나게 큰 문제점이 있는데요.
시간 설정이 안된다는 겁니다. 그래서 소스를 넣을때 한번은 시간을 설정한 소스를 한번 넣어주고, 그담에 시간설정 부분이 없는 소스를 넣어줘 사용하면 됩니다. ㅎㅎ 시간 설정하는건 귀찮아서 넣지 않았습니다.ㅡㅡ;

그리고 이상하게 전원을 끊었다가 넣어주면 I2C 통신이 안되는가 봅니다. FND에 이상한 값이 출력됩니다.
이럴땐 백업 배터리 입력핀인 3번핀을 GND에 연결시켜준 후 리셋버튼을 누르면 또 잘 동작 하더군요...;;
왜이런지 아직 원인을 모르겠습니다. 데이터시트엔 백업배터리를 사용하지 않으면 Vbat 를 GND에 연결하라고 돼있길래 그리 해보니 되긴 하는데 전 백업배터리도 있고,, 배터리가 다 닳았나...ㅡㅡ;;;;;

아무튼 소스를 공개합니다~ 자자자잔!

#include <avr/io.h>
#include <stdio.h>
#include <carroty/delay.h>
#include <carroty/fnd.h>

unsigned char number_array[16]= { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, };
unsigned char fnd_sel_array[4]= { 0,0,0,0,};
unsigned char hour, min;
int n1000, n100, n10, n, time;

void rtc_write(unsigned char address, unsigned char byte) {
 delay_us(6);
 TWCR = 0xA4;      // START condition
 while(((TWCR & 0x80) == 0x00) || (TWSR & 0xF8) != 0x08);
 
 TWDR = 0xD0;
 TWCR = 0x84;      // MT_SLA_ACK
 while(((TWCR & 0x80) == 0x00) || (TWSR & 0xF8) != 0x18);
 
 TWDR = address;
 TWCR = 0x84;      // MT_DATA_ACK
 while(((TWCR & 0x80) == 0x00) || (TWSR & 0xF8) != 0x28);
 
 TWDR = byte;
 TWCR = 0x84;      // MT_DATA_ACK
 while(((TWCR & 0x80) == 0x00) || (TWSR & 0xF8) != 0x28);
 
 TWCR = 0x94;      // STOP condition
}

unsigned char rtc_read(unsigned char address) {
 delay_us(6);
 unsigned char byte;
 
 TWCR = 0xA4;      // START condition
 while(((TWCR & 0x80) == 0x00) || (TWSR & 0xF8) != 0x08);
 
 TWDR = 0xD0;
 TWCR = 0x84;      // MT_SLA_ACK
 while(((TWCR & 0x80) == 0x00) || (TWSR & 0xF8) != 0x18);
 
 TWDR = address;
 TWCR = 0x84;      // MT_DATA_ACK
 while(((TWCR & 0x80) == 0x00) || (TWSR & 0xF8) != 0x28);
 
 TWCR = 0xA4;      // RESTART condition
 while(((TWCR & 0x80) == 0x00) || (TWSR & 0xF8) != 0x10);
 
 TWDR = 0xD1;
 TWCR = 0x84;      // MR_SLA_ACK
 while(((TWCR & 0x80) == 0x00) || (TWSR & 0xF8) != 0x40);
 
 TWCR = 0x84;      // MR_DATA_NOACK
 while(((TWCR & 0x80) == 0x00) || (TWSR & 0xF8) != 0x58);
 byte = TWDR;
 
 TWCR = 0x94;      // STOP condition
 return byte;
}

void display_fnd(unsigned char number, unsigned char fnd_select) {
 PORTB= number;
 PORTC= fnd_select;
}

void time_print(unsigned int value) {
 
 n1000=value/1000;
 n100=(value-(value/1000*1000))/100;
 n10=(value-(value/100*100))/10;
 n=value-(value/10*10);
 int g;
 for(g=0;g<10;g++){
  display_fnd(number_array[n1000], fnd_sel_array[0]); delay_ms(3);
  display_fnd(number_array[n100], fnd_sel_array[1]);  delay_ms(3);
  display_fnd(number_array[n10], fnd_sel_array[2]); delay_ms(3);
  display_fnd(number_array[n], fnd_sel_array[3]);  delay_ms(3);
 }
}

void led_init(void) {
 DDRB= 0xFF;
 DDRC= 0xF0;
 DDRA= 0xF0;
}

int main(void) {
 TWBR= 72;  
 TWSR= 0x00;
 TWCR= 0x04;      
 number_array[0]=  NUMBER_0;
 number_array[1]=  NUMBER_1;
 number_array[2]=  NUMBER_2;
 number_array[3]=  NUMBER_3;
 number_array[4]=  NUMBER_4;
 number_array[5]=  NUMBER_5;
 number_array[6]=  NUMBER_6;
 number_array[7]=  NUMBER_7;
 number_array[8]=  NUMBER_8;
 number_array[9]=  NUMBER_9;
 
 fnd_sel_array[0]= FND_SEL_1;
 fnd_sel_array[1]= FND_SEL_2;
 fnd_sel_array[2]= FND_SEL_3;
 fnd_sel_array[3]= FND_SEL_4;
 led_init();  

 /*  시간 설정 부분.
 rtc_write(0x06,0x09);
 rtc_write(0x05,0x09);
 rtc_write(0x04,0x25);
 rtc_write(0x03,0x05); 
 rtc_write(0x02,0x02);
 rtc_write(0x01,0x17);  
 rtc_write(0x00,0x00);   */
 
 PORTA=0xF0;
 int h=0;
 while(1) {
 
  hour=   rtc_read(0x02);
  hour=   ((hour >>4) & 0x07)*10 + (hour & 0x0f);
 
  min=    rtc_read(0x01);
  min=    ((min >>4) & 0x07)*10 + (min & 0x0f);
 
  if(hour>12){
   //hour=hour-12;
   PORTA=PORTA&0b11011111;
   PORTA=PORTA|0b00010000;
  }
  else {
   PORTA=PORTA&0b11101111;
   PORTA=PORTA|0b00100000;
  }
 
  time=hour*100+min;
  time_print(time);
  h++;
  if(h>4) {
   h=0;
   PORTA^=0xC0;
  }
 }
}


ㅎㅎㅎ 코딩실력이 부족해 소스가 난잡합니다.ㅡㅡ; 이해하시길;;;ㅎㅎ
그럼 동작 하는 모습을 보시죠~

현재 새벽이므로 오전이라는 표시인 노란색 LED가 들어와있습니다.
그리고 빨간색 LED 2개가 깜빡이는데 0.5초마다 깜빡이는건 아니고 그냥 대충 깜빡이는것입니다...;;
하지만 시계는 정확하지요.ㅎㅎㅎ


2009/09/25 02:53 2009/09/25 02:53


ㄹㅔㅈㅕ
하드웨어/AVR 2009/09/25 02:53

댓글을 달아 주세요

  1. 비밀방문자 2009/11/03 15:04  수정/삭제  댓글쓰기

    관리자만 볼 수 있는 댓글입니다.

    • ㄹㅔㅈㅕ 2009/11/04 02:49  수정/삭제

      위 시계는 '당근이의 AVR갖구놀기' 라는 네이버 카페에서 공동구매를 통해 판매하는 일종의 AVR 실습 KIT 입니다. 제가 만든게 아니구 구입한 것이지요...

      회로도와 재료등은 모두 위 카페에 가시면 있습니다^^

  2. simulz 2010/03/14 01:45  수정/삭제  댓글쓰기

    당근보드
    RTC 시계 및 설정 완성 소스 있나요??

    보드를 제대로 갖고 놀지도 못하고 있어요 ㅠㅠ

    • ㄹㅔㅈㅕ 2010/03/15 01:49  수정/삭제

      시계 소스는 위에 포스팅에 올려놨구요..ㅎㅎ 설정하는 부분은 따로 구현하지 않았습니다..
      공부하시는겸 해서 한번 작성해 보시는것도 도움이 될것같습니다^^
      인터럽트를 이용하면 쉽게 가능할것도 같네요..ㅎㅎ;;;

[당근보드] 온도센서인 TCN75의 값을 읽어 LCD에 표시하기.


당근보드엔 온도센서 TCN75가 달려있지요...
시계IC인 DS1307도 있는데 이건 왜인지 작동이 안됩니다....; 그래서 온도센서만 해봅니다..

온도센서는 I2C (아이스퀘어씨) 통신방식을 사용해 데이터를 전송합니다. AVR에서는 TWI 라고 써있더군요..

별거 없고 어디서 주워온 소스에 제 입맛대로 바꿔서 썼습니다.ㅎㅎ 소스 보시죠~

사용자 삽입 이미지

당근보드가 좀 커졌죠?? 만능기판에 이것저것 부가기능(10P 박스헤더, JTAG포트, ISP포트, USB전원포트, 포트B의 LED, 전면 20X4 CLCD 등..)을 붙이느라 커졌습니다..ㅎㅎ
LCD엔 우리 동아리 이름과 제 이름, 그리고 온도가 나옵니다...
동아리방에 온도계가 3개가 있는데 알콜 온도계는 30.5도, 제쪽 연필꽂이 온도계는 28.3도, 옆 친구 연필꽂이 온도계는 26.1도,  그리고 당근보드의 현재 온도는 31.5도 입니다... 제 자리가 좀 뜨겁나 봅니다;;;;
2009/08/26 03:42 2009/08/26 03:42


ㄹㅔㅈㅕ
하드웨어/AVR 2009/08/26 03:42

댓글을 달아 주세요

ATmega128을 이용해 가속도값을 ADC로 읽어 CLCD에 출력하기.


이번엔 ATmega의 ADC기능을 이용하여 가속도센서의 값을 읽어내어 LCD에 출력해보겠습니다.
사용된 가속도센서 모듈은 NTC社의 AM-3AXIS 로서 X축과 Y축, 그리고 Z축의 가속도를 센싱할수 있습니다.
그 값은 아날로그로 출력되며 AVR의 ADC기능을 이용해 숫자화 해야 합니다.

차례로 X, Y, Z 값을 읽어 변수에 저장한 후 sprintf를 이용해 ASCII 값으로 변환 후 LCD에 뿌려주면 끝입니다^^
아래에 소스 나갑니다~ ㅋ


지금까지 ADC는 많이 다루어 보았으므로 다른 설명하지 않겠습니다...
LCD 사용 헤더파일은 네이버 카페인 '아두이노 스토리'에서 가져왔습니다^^

그럼 작동되는 모습을 보시겠습니다.

2009/08/17 15:33 2009/08/17 15:33


ㄹㅔㅈㅕ
하드웨어/AVR 2009/08/17 15:33

댓글을 달아 주세요

당근보드(ATmega32)를 이용한 시계 만들기 - 타이머 이용.


  당근보드 자체에는 DS1307이라는 RTC (Real Time Clock)이 있어서 이를 I2C 통신을 이용해 시간을 얻을 수 있습니다. 하지만 아직 I2C 를 공부하지 않았기 때문에..;; 타이머로 동작을 시켜 볼 것입니다.

어떤분께서 ATmega128과 8MHz 클럭을 이용해 1초를 만드는 방법을 올려놓은것을 보았습니다.
전 ATmega32와 16Mhz를 쓰니깐 그분이 만든 1초는 저에겐 0.5초이니 두배 뻥튀기 하면 1초가되는것을 생각하여 만들게 되었습니다... 그러고보니 제가 타이머를 건드린것은 없군요.ㅡㅡ;;
하지만 ATmega128과 ATmega32, 또는 그외의 AVR칩들은 각각 TCCR0로 설정한 클럭 분주비가 다를수 있다고 합니다. 실제로 128은 TCCR0=0x06; 이면 분주비가 256이지만, 32에서는 0x04로 설정해야 분주비가 256이 됩니다.
이는 반드시 데이터시트를 참조하시기 바랍니다.

시계는 잘 갑니다만 오차가 있을수도 있습니다... 아직 오차 테스트는 해보지 않았습니다...ㅡㅡ;
암튼 소스 나갑니다~

#include <avr/io.h>
#include <avr/interrupt.h>
#include <carroty/delay.h>
#include <carroty/fnd.h>

int count = 0; //인터럽트 횟수를 카운트
int sec = 0, min = 0, hour = 0;

unsigned char number_array[16]= { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, };
unsigned char fnd_sel_array[4]= { 0,0,0,0,};
int n1000, n100, n10, n;

void display_fnd(unsigned char number, unsigned char fnd_select) {
  PORTB= number;
  PORTC= fnd_select;
}

void adc2fnd(unsigned int value1,unsigned int value2) {
 n1000=(value1-(value1/100*100))/10;
 n100=value1-(value1/10*10);
 n10=(value2-(value2/100*100))/10;
 n=value2-(value2/10*10);

 for(int g=0;g<10;g++){
  display_fnd(number_array[n1000], fnd_sel_array[0]); delay_ms(3);
  display_fnd(0x11111111, fnd_sel_array[0]);    delay_us(10);
  display_fnd(number_array[n100], fnd_sel_array[1]);  delay_ms(3);
  display_fnd(0x11111111, fnd_sel_array[1]);    delay_us(10);
  display_fnd(number_array[n10], fnd_sel_array[2]); delay_ms(3);
  display_fnd(0x11111111, fnd_sel_array[2]);    delay_us(10);
  display_fnd(number_array[n], fnd_sel_array[3]);  delay_ms(3);
  display_fnd(0x11111111, fnd_sel_array[3]);    delay_us(10);
 }
}

SIGNAL(SIG_OVERFLOW0)
{
 TCNT0 = 206; //TCNT0 초기화
 count ++;
 if ( count < 625 ) PORTA=0xF0;
 else PORTA=0x30;

 if ( count == 1250 )
 { //드디어 1초가 됨
  count = 0;
  sec++; //1초 증가
  if ( sec == 60 ){ sec = 0; min++;}//60초 되면 0으로, 뭐 여기에 분을 추가하시던 알아서...
  if ( min == 60 ){ min = 0; hour++;}
 }
}

int main()
{
 DDRB= 0xFF;
 DDRC= 0xF0;
 DDRD= 0x00;
 number_array[0]=  NUMBER_0;  //각 배열값에 FND에 표시될 수를 입력.
 number_array[1]=  NUMBER_1;
 number_array[2]=  NUMBER_2;
 number_array[3]=  NUMBER_3;
 number_array[4]=  NUMBER_4;
 number_array[5]=  NUMBER_5;
 number_array[6]=  NUMBER_6;
 number_array[7]=  NUMBER_7;
 number_array[8]=  NUMBER_8;
 number_array[9]=  NUMBER_9;

 fnd_sel_array[0]= FND_SEL_1;
 fnd_sel_array[1]= FND_SEL_2;
 fnd_sel_array[2]= FND_SEL_3;
 fnd_sel_array[3]= FND_SEL_4;

 DDRA=0xFF;
 PORTA=0xF0;
 TIMSK = 0x01; // interrupt enable
 TCCR0 = 0x04; // prescale : 256
 TCNT0 = 206;   // initial value of TCNT0 : 50
 sei();    // global interrupt on.
 while(1){
  adc2fnd(hour,min);
  if((PIND&0x08)==0) min++;  //버튼 누를시 1분 증가.
  if((PIND&0x04)==0) hour++;//버튼 누를시 1시간 증가
  if((PIND&0x10)==0) sec=0; // 버튼 누를시 초가 0으로 셋팅
  if(min==60) min=0;
  if(hour==24) hour=0;
 }
 return 1;
}


그럼 실제로 동작하는 모습을 보시겠습니다~~


2009/08/04 16:41 2009/08/04 16:41


ㄹㅔㅈㅕ
하드웨어/AVR 2009/08/04 16:41

댓글을 달아 주세요

  1. 이지훈 2009/08/05 18:08  수정/삭제  댓글쓰기

    근데 시간은 잘 맞습니까??ㅋㅋ

    • ㄹㅔㅈㅕ 2009/08/06 03:33  수정/삭제

      하루에 무려 4초나 오차가 생깁니다.ㅋㅋㅋㅋㅋ
      된장... RTC를 써야돼....ㅡㅡ;

자작 8*24 도트 매트릭스 (8X24 Dot Matrix)


난번 8*8 도트 매트릭스를 직접 만들어 구동을 해본적이 있습니다.
8*8도 많은 공부가 되었지만 약간은 부족한 감이 없지않아 있어서 이번에 큰 결심을 하고 8*24 도트 매트릭스를
제작하기로 하였습니다.  부품을 구입하고, 크게 심호흡을 하고 제작에 들어갔지요..
지난번에 한번 만들어본 경험이 있어서 그런지 시간도 2시간밖에(?)안걸렸고, 훨씬 수월하더군요....ㅋ
이렇게 제작된 도트매트릭스 버전 2 !!  드디어 공개합니다!!!


사용자 삽입 이미지


8X24 도트매트릭스를 구동하기 위해선 제일 무식한 방법으로 AVR의 포트 4개를 이용하는 방법이 있습니다.
포트 하나로 8개의 가로줄을 컨트롤하고, 나머지 3개의 포트로 24개의 세로줄을 각각 컨트롤 합니다.

뒷면 보시겠습니다~ 완전 감동의 눈물이 좔좔~~ㅠ.ㅠ


사용자 삽입 이미지

깔끔하게 만드느라 고생좀 했습니다... 이젠 누가 돈만 많이 주면 어느크기라도 만들수 있을것 같습니다!!ㅋ
하지만 절대로 제가 제 취미로 이걸 다시 만들거나 더 큰걸 만들진 않을것 같습니다.... 막노동이라;;;
(뭐... 만들고 나면 뿌듯하긴 합니다.ㅋㅋ)


그런데 아주 큰 문제점이 있습니다..
이걸 만들고도 제대로 구동시킬 펌웨어를 제작할 능력이 없다는...........;;
지난번 8*8 도트매트릭스는 그래도 프로그램을 잘 짜서 제대로 구동이 되었지만...
이번엔 무려 곱하기 3이 되었으니 머리 안돌아갑니다.. 아무리 쥐어짜도.....ㅡㅡ; 그나마 위에 사진보시면 LED몇 개 들어오는데 이것도 이상하게 나오는걸 보실수 있습니다.... 실패작이지요...

오늘은 이 도트매트릭스를 제대로 구동시킬 펌웨어를 제작하는데 총력을 가해야 겠군요...
그런데 밤을 새서 그런지 정신이 몽롱합니다... 언제 쓰러질지 모릅니다....(근데 나 왜 밤샌거야;;)
2009/07/17 10:09 2009/07/17 10:09


ㄹㅔㅈㅕ
하드웨어/AVR 2009/07/17 10:09

댓글을 달아 주세요

자작 8*8 도트 매트릭스 + 구동 소스


  이즈가 간당간당한 만능기판과 양이 좀 되는 3파이 적색 LED로 8*8 도트 매트릭스를 제작해 보았습니다.
IC는 ULN2803 하나만 썼습니다. 포트는 행을 제어하는 8핀과 열을 제어하는 8핀 총 16라인으로 동작합니다.
포트수를 줄여야 하는데... 기술도,,,,능력도,,,,,IC도,,,,없다는....ㅎㅎㅎㅎ(핑계.ㅡㅡ;)

사용자 삽입 이미지

사용자 삽입 이미지
제작한 8*8 도트 매트릭스 입니다... 뭐 그냥 좀 깔끔하지 않나요??
만드는데 좀 힘들었습니다.ㅎㅎ 뒷면을 보면 왜 힘든지 알수있습니다.ㅡㅡ;



사용자 삽입 이미지
좀 조잡하군요..ㅎㅎ 아무튼 저거 납땜하느라 눈알이 빠지는줄 알았습니다...
자작으로 8*32 도트매트릭스 만드시는 분들 존경스럽습니다..ㅎㅎ

이 도트매트릭스를 구동하는 소스를 공개합니다.
제가 열심히 짜맞춘 영문폰트를 넣어놨습니다.(숫자는 어디서 긁어온건데 맘에 안든다는;;)

도트매트릭스 소스 보기....



이 도트매트릭스의 구동 모습은 아래 동영상을 플레이하면 보실수 있습니다..



AVR Studio 4 로 제작됨.


폰트추가 및 변경
2009/07/11 00:24 2009/07/11 00:24


ㄹㅔㅈㅕ
하드웨어/AVR 2009/07/11 00:24

댓글을 달아 주세요

  1. 후덜덜 2009/11/27 23:28  수정/삭제  댓글쓰기

    이거 소스 8051칩에서도 가능한가요.

  2. 비밀방문자 2009/11/30 22:17  수정/삭제  댓글쓰기

    관리자만 볼 수 있는 댓글입니다.

    • ㄹㅔㅈㅕ 2009/11/30 22:29  수정/삭제

      네~ 물론입니다. 비영리목적으로 활용하셔서 도움이 되신다면 제가 더 감사하죠.ㅎㅎ

AVR에서 AND연산자, OR연산자, XOR연산자 사용 예..


& 연산자 (AND)
& 연산자는 둘다 1이어야 1이 되기 때문에

1)특정 비트만 0으로 만들고 싶을때
2)특정 비트만 확인 하고 싶을때 (masking)

로 많이 사용됩니다.  예를 들어 보겠습니다.

1)특정 비트만 0으로 만들고 싶을때
PORTA 에 LED8개가 붙어 있고 모두 켜져 있습니다.(PORTA==0xFF)
그런데 다른 비트는 건드리지 않고 0번 1번 7번 비트의 LED 만 끄고 싶다면???

PORTA=PORTA & 0x7C;

라고 하면 됩니다.
쓰고 보니 PORTA=0x7C; 라고 하면 되지 않느냐? 라고 물으실 분들을 위해 다른 가정을 하나 더 넣겠습니다.
현재 LED 가 어떻게 켜져 있는지 모르는데 0번 1번 7번 비트의 LED 만 끄고 싶다면??? 그렇다면..
PORTA=PORTA & 0x7C; 이런식으로 & 연산자를 쓰는 것이 다른 비트는 건드리지 않게 됩니다.

2)특정 비트만 확인 하고 싶을때 (masking)
특정 비트만 확인하는 부분은 조건문에서 많이 들어 가는데..
예를 들어 PORTA 에 스위치가 8개 붙어 있는데
PORTA 3번 비트에 달려 있는 스위치가 눌렸는지 판단하고 싶다면?? (스위치는 안눌렀을때 1 눌리면 0으로 가정합니다. )

if((PINA & 0x08) == 0){  ... }

else

 이런식으로 사용하게 되면 스위치가 눌렸다면 {  ... }  의 동작을 수행하고 눌리지 않았다면  else 문을 수행 하겠죠??




| 연산자 (OR)

| 연산자는 둘중 하나라도 1이면 1이 되기 때문에

1)특정 비트만 1으로 만들고 싶을때
로 많이 사용됩니다.  예를 들어 보겠습니다.

1)특정 비트만 1으로 만들고 싶을때
AVR의 ADC관련 레지스터 중에 ADCSRA 라는 레지스터가 있습니다.
그런데 이 레지스터의 6번 비트를 1로 set 하면 ADC를 시작하라는 명령을 내리는 비트입니다.  다른 비트들은 ADC 관련 설정 값이죠..
만약.. ADC를 시작하고 싶은데 ADC 의 다른 설정은 건드리지 말아야 할때.. 바로 | 를 쓰면 됩니다.

ADCSRA |= 0x40;



이렇게 사용하면 해당 비트만 1로 만들수 있습니다.
포트 출력할때 특정포트만 1로 만들고 싶다면 동일한 방법으로 사용하면 됩니다.



^ 연산자 (XOR)

두개가 다르면 1이 되기 때문에

1)특정 비트를 토글하고 싶을때

많이 사용됩니다.  예를 들어 보겠습니다.
PORTA 에 연결된 LED중 0번 비트에 연결된 LED만 켰다 껏다를 반복하고 싶습니다.
그럼 이렇게 코드는 어떻게 작성할까요??

while(1)
{
     PORTA = 0x01;
     delay_ms(1000);
     PORTA = 0x00;
     delay_ms(1000);
}

이렇게 작성해도 되지만  ^ 를 사용하면

while(1)
{
     PORTA ^= 0x01;        
     delay_ms(1000);
}

코드가 간단해 집니다.
PORTA 의 값이 뭐든 다른 비트는 변화 없이 0번 비트만 토글됩니다.

------------------------------------------------------------------------------------------

출처 : 당근이의 AVR갖구놀기
2009/06/18 13:05 2009/06/18 13:05


ㄹㅔㅈㅕ
tags : ,
하드웨어/AVR 2009/06/18 13:05

댓글을 달아 주세요

[ SG, SB ] Powerd by Textcube, designed by criuce
rss