1950 년에 시작된 디지털 혁명은 기존의 모든 기계 및 아날로그 전자 구조를 디지털 컴퓨터로 변경합니다. 디지털 전자 장치의 성장이 기하 급수적으로 증가했기 때문에 오늘날 사람이 전자 장비 사용에 저항하는 것은 거의 불가능합니다. 당신을 깨우는 알람 시계와 아침 식사를 제공하는 토스터부터 시작하여 모든 것이 디지털 전자 제품의 기여입니다. 이 모든 것을 생각 하면 PIC 마이크로 컨트롤러 로이 프로젝트에서 구축 할 알람 시계 와 같이 간단하면서도 유용한 작업을 수행 할 수있는 자체 작업을 프로그래밍하는 것은 정말 흥미 롭습니다. 이전에 다른 마이크로 컨트롤러로 알람 시계를 구축했습니다.
- RTC 모듈 DS1307을 사용하는 Raspberry Pi 알람 시계
- 알람 기능이있는 Arduino 기반 디지털 시계
- ATmega32 마이크로 컨트롤러를 사용한 알람 시계
이 알람 시계에는 현재 시간과 설정 시간을 표시하는 16x2 LCD 디스플레이가 있습니다. 필요할 때마다 몇 개의 푸시 버튼을 사용하여 알람 시간을 설정합니다. 현재 시간은 DS3231 RTC 모듈을 사용하여 추적되며 IIC 통신을 사용하여 RTC 모듈에서 이러한 값을 가져옵니다. 우리는 이미 RTC 모듈과이를 PIC와 인터페이스하는 방법에 대해 배웠습니다. 따라서 해당 자습서를 읽는 것이 좋습니다. 해당 자습서에서 다루는 대부분의 정보는 건너 뛸 것입니다.
필요한 재료:
- 브레드 보드 – 2Nos
- PIC16F877A
- 5V 전원-공급 모듈
- 20MHz 크리스탈
- 33pf 커패시터 – 2Nos
- DS3231 RTC 모듈
- 16 * 2 LCD 디스플레이 모듈
- 10K POT
- 10k 및 1K 저항
- 푸시 버튼 – 5Nos
- 부저
- 전선 연결
전제 조건:
이 프로젝트에서는 PIC 마이크로 컨트롤러에 대한 기본 사항과 프로그래밍 방법을 거의 알 필요가 없습니다. 이 프로젝트에서는 GPIO, LCD 디스플레이 및 RTC 모듈을 사용합니다. 따라서 이러한 모듈을 사용하는 방법을 미리 배우는 것이 좋습니다. 다음 링크는 동일한 것을 배우는 데 도움이 될 것입니다
- PIC 마이크로 컨트롤러로 첫 번째 프로그램 작성
- LCD와 PIC 인터페이스
- PIC를 이용한 I2C 통신
- PIC와 인터페이싱하는 DS3231 RTC
회로도:
이 PIC 기반 알람 시계 프로젝트의 회로도 는 proteus 소프트웨어를 사용하여 만든 다음과 같습니다. 또한이 프로젝트에서 추가 시뮬레이션에 사용됩니다.
5 개의 푸시 버튼은 필요한 시간 동안 알람을 설정하기위한 입력으로 작동합니다. 따라서 모든 푸시 버튼의 한쪽 끝은 접지에 연결되고 다른 쪽 끝은 PORTB 핀에 연결됩니다.이 핀에는 내부 풀업 저항이 사용되어 핀이 떠 다니는 것을 방지합니다. Buzzer는 출력 역할을하며 알람이 트리거되고 PORT S 핀에 연결될 때 경고음을 제공합니다. 현재 시간은 PIC가 I2C 버스를 통해 데이터를 수신 하는 DS3231 RTC 모듈에 의해 항상 추적 되므로 RTC 모듈의 SCL 및 SDA 핀은 PIC 컨트롤러의 SCL 및 SDA 핀에 연결됩니다. 현재 시간과 설정 시간을 표시하는 데 사용되는 PIC의 PORTD에 LCD 디스플레이가 부착되어 있습니다. 여기에서 PIC와 함께 DS3231 RTC 모듈을 사용하는 방법에 대해 자세히 알아보십시오.
전체 회로는 브레드 보드 위에 구축 할 수 있습니다. 연결할 전선이 수십 개이므로 인내심을 갖고 연결이 올바른지 확인하십시오. 연결을 마치면 하드웨어 설정이 아래와 같이 보입니다.
브레드 보드 모듈과 12V 어댑터를 사용하여 모듈에 전원을 공급했습니다. 이것은 + 5V 공급 전압의 소스입니다. 또한 회로를 깨끗하게 유지하기 위해 두 개의 브레드 보드를 사용해야합니다. 더 강력한 프로젝트를 만들고 싶다면 전체 회로를 성능 기판에 납땜 할 수도 있습니다.
알람 시계 프로그래밍:
이 알람 시계 프로젝트 의 전체 PIC 프로그램 은이 페이지 하단에서 찾을 수 있습니다. 이 프로젝트에는 LCD, I2C 및 RTC와 PIC를 사용하기위한 3 개의 라이브러리도 필요합니다. 헤더 파일이 포함 된 전체 코드는 여기 ZIP 파일에서 다운로드 할 수 있으며 압축을 푼 후 MPLABX를 사용하여 열 수 있습니다. 더 아래에서는 메인 c 파일을 작은 스 니펫으로 설명하겠습니다. 헤더 파일이 어떻게 작동하는지 알고 싶다면 위에서 언급 한 튜토리얼로 돌아갈 수 있습니다.
메인 프로그램에 들어가기 전에 사용했던 핀 을 좀 더 의미있는 이름 으로 정의 해야합니다. 이렇게하면 프로그래밍 중에 쉽게 사용할 수 있습니다. 프로그램에 정의 된 핀은 다음과 같습니다.
// LCD 핀 정의 #define RS RD2 // LCD 핀 재설정 #define EN RD3 // LCD 핀 활성화 #define D4 RD4 // LCD의 데이터 비트 0 #define D5 RD5 // LCD의 데이터 비트 1 #define D6 RD6 // LCD의 데이터 비트 2 #define D7 RD7 // LCD의 데이터 비트 3 // 버튼 정의 #define MB RB1 // 중간 버튼 #define LB RB0 // 왼쪽 버튼 #define RB RB2 // 오른쪽 버튼 # define UB RB3 // 상단 버튼 #define BB RB4 // 하단 버튼 // 버즈 정의 #define BUZZ RD1 // 버저가 RD1에 연결됨
주 함수 내에서 입력 및 출력 핀을 선언하는 것으로 시작 합니다. 우리 프로젝트에서 PORTB는 입력 장치 인 푸시 버튼에 사용되므로 핀을 입력으로 설정하고 PORTD는 LCD 및 부저에 사용하므로 핀을 출력으로 설정합니다. 또한 핀은 부동 상태로 두어서는 안되며, I / O 핀은 항상 접지 또는 + 5V 전압에 연결되어야합니다. 푸시 버튼의 경우 버튼을 누르지 않으면 핀이 아무 것도 연결되지 않으므로 사용하지 않을 때 핀을 High로 설정하는 내부 풀업 저항을 사용합니다. 이것은 아래와 같이 제어 레지스터를 사용하여 수행됩니다.
TRISD = 0x00; // LCD 인터페이스를위한 출력 으로 포트 D 핀을 만듭니다 . TRISB = 0xFF; // 스위치 는 입력 핀으로 선언됩니다 . OPTION_REG = 0b00000000; // 스위치 에 대해 포트 B의 풀업 저항기를 활성화합니다 . BUZZ = 0; // 부저를 켭니다.
메인 프로그램과 연결된 LCD 및 I2C 헤더 파일이 있으므로 간단한 함수를 호출 하여 LCD 초기화 를 시작할 수 있습니다. I2C 초기화 에 대해서도 동일하게 수행 할 수 있습니다. 여기서는 RTC 모듈이 100kHz로 작동하므로 100kHz에서 I2C 통신을 시작합니다.
Lcd_Start (); // LCD 모듈 초기화 I2C_Initialize (100); // 100KHz 클럭으로 I2C 마스터 초기화
아래 기능은 RTC 모듈에 시간과 날짜 를 설정하는 데 사용되며, 시간과 날짜가 설정되면이 줄을 제거합니다. 그렇지 않으면 프로그램을 시작할 때마다 시간과 날짜가 계속해서 설정됩니다.
// 시간과 날짜 가 처음 설정 되면 아래 줄을 제거합니다 . Set_Time_Date (); // RTC 모듈에 시간 및 날짜 설정
프로그램이 시작되고 있음을 나타 내기 위해 아래와 같이 프로젝트 이름과 웹 사이트 이름을 표시하는 작은 소개 화면 이 표시됩니다.
// LCD에 인트로 메시지 제공 Lcd_Clear (); Lcd_Set_Cursor (1,1); Lcd_Print_String ("알람 시계"); Lcd_Set_Cursor (2,1); Lcd_Print_String ("-Circuit Digest"); __delay_ms (1500);
다음으로 while 루프 내에서 RTC 모듈에서 현재 시간과 날짜 를 읽어야합니다. 아래 함수를 호출하면됩니다.
Update_Current_Date_Time (); // RTC 모듈에서 현재 날짜 및 시간 읽기
위의 함수를 호출하면 변수 sec, min 및 hour가 현재 값으로 업데이트됩니다. LCD 화면에 표시 하려면 아래 코드를 사용하여 개별 문자로 분할해야 합니다.
// LCD 에 표시 할 문자로 분할 char sec_0 = sec % 10; char sec_1 = (초 / 10); char min_0 = 최소 % 10; char min_1 = 최소 / 10; char hour_0 = 시간 % 10; char hour_1 = 시간 / 10;
다음으로 LCD 화면에서 값을 업데이트합니다. 현재 시간이 첫 번째 줄에 표시되고 알람이 트리거되어야하는 설정 시간이 두 번째 줄에 표시됩니다. 동일한 작업을 수행하는 코드는 다음과 같습니다.
// LCD 화면에 현재 시간 표시 Lcd_Clear (); Lcd_Set_Cursor (1, 1); Lcd_Print_String ("시간:"); Lcd_Print_Char (시간 _1 + '0'); Lcd_Print_Char (시간 _0 + '0'); Lcd_Print_Char (':'); Lcd_Print_Char (min_1 + '0'); Lcd_Print_Char (min_0 + '0'); Lcd_Print_Char (':'); Lcd_Print_Char (sec_1 + '0'); Lcd_Print_Char (sec_0 + '0'); // LCD 화면에 날짜 표시 Lcd_Set_Cursor (2, 1); Lcd_Print_String ("알람:"); Lcd_Print_Char (alarm_val + '0'); Lcd_Print_Char (alarm_val + '0'); Lcd_Print_Char (':'); Lcd_Print_Char (alarm_val + '0 '); Lcd_Print_Char (alarm_val + '0');
이제 LCD에 시간과 설정 시간을 표시하여 사용자가 알람 시간 설정을 시도하고 있는지 확인해야합니다. 이를 위해 사용자는 중간 버튼을 눌러야하므로 중간 버튼이 눌 렸는지 확인하고 변수를 토글하여 알람 설정 모드로 들어갑니다. 동일한 버튼을 다시 눌러 값이 설정되었음을 확인하고이 경우 알람 설정 모드에서 빠져 나와야합니다. 따라서 아래 코드 줄을 사용하여 변수 set_alarm 의 상태를 변경합니다.
// 중간 버튼을 사용하여 알람 설정 여부 확인 if (MB == 0 && set_alarm == 0) {// 중간 버튼을 눌렀는데 (! MB); // 버튼을 놓을 때까지 기다 립니다 set_alarm = 1; // 알람 값 설정 시작 } if (MB == 0 && set_alarm == 1) {// 중간 버튼을 눌렀을 때 (! MB); // 버튼을 놓을 때까지 기다 립니다 set_alarm = 0; // 알람 값 설정 중지 }
사용자가 중간 버튼을 눌렀다면 알람 시간을 설정하려고한다는 의미입니다. 이 경우 프로그램은 위의 코드를 사용하여 알람 설정 모드로 들어갑니다. 알람 설정 모드에서 사용자가 좌 / 우 버튼을 누르면 커서를 좌 / 우로 움직여야 함을 의미합니다. 이를 위해 커서가 위치해야하는 위치의 값을 감소시키기 만하면됩니다.
if (LB == 0) {// (! LB); // 버튼을 놓을 때까지 기다리십시오 pos--; // 그런 다음 커서를 왼쪽으로 이동 } if (RB == 0) {// (! RB); // 버튼이 해제 될 때까지 기다립니다 pos ++; // 커서를 오른쪽으로 이동 }
마이크로 컨트롤러 또는 마이크로 프로세서와 함께 푸시 버튼을 사용하는 동안 해결해야 할 일반적인 문제가 하나 있습니다. 이 문제를 스위치 바운싱 이라고 합니다. 즉, 버튼을 눌렀을 때 MCU / MPU에 잡음이있는 펄스를 제공하여 여러 항목에 대해 MCU를 위조 할 수 있습니다. 이 문제는 스위치에 커패시터를 추가 하거나 버튼 누름이 감지되는 즉시 지연 기능을 사용하여 해결할 수 있습니다. 이러한 유형의 솔루션을 디 바운싱이라고합니다. 여기 에서는 버튼을 놓을 때까지 프로그램을 유지하기 위해 while 루프를 사용했습니다. 이것은 최고의 디 바운싱 솔루션은 아니지만 우리에게는 잘 작동합니다.
while (! RB);
왼쪽 및 오른쪽 버튼과 마찬가지로 알람 시간 값 을 높이거나 낮추는 데 사용할 수있는 상단 및 하단 버튼도 있습니다. 동일한 작업을 수행하는 코드는 아래와 같습니다. 설정된 알람 시간의 각 문자는 배열의 인덱스 값으로 처리됩니다. 이것은 값을 변경해야하는 필수 문자에 쉽게 액세스 할 수 있다는 것입니다.
if (UB == 0) {// (! UB); // 버튼이 해제 될 때까지 대기 alarm_val ++; // 특정 char 값을 증가 } if (BB == 0) {// (! UB); // 버튼이 해제 될 때까지 기다림 alarm_val--; // 특정 char 값을 줄입니다. }
알람 시간이 설정되면 사용자는 중간 버튼을 다시 누릅니다. 그런 다음 현재 시간과 설정된 시간을 비교할 수 있습니다. 현재 시간의 모든 문자가 설정된 시간의 문자와 동일한 지 확인하여 비교합니다. 값이 같으면 trigger_alarm 변수 를 설정하여 알람을 트리거합니다. 그렇지 않으면 같을 때까지 비교합니다.
// 경보가 설정된 경우 설정 값이 현재 값 과 같은지 확인 if (set_alarm == 0 && alarm_val == hour_1 && alarm_val == hour_0 && alarm_val == min_1 && alarm_val == min_0) trigger_alarm = 1; // 값이 일치하면 트리거를 켭니다.
알람이 설정되어 있으면 사용자에게 알람을 알리기 위해 부저 를 울려 야합니다. 아래 그림과 같이 정기적으로 버저를 토글하면됩니다.
if (trigger_alarm) {// 알람이 발생하면 // 부저 가 울립니다 . BUZZ = 1; __delay_ms (500); 버즈 = 0; __delay_ms (500); }
시뮬레이션:
이 프로그램은 proteus 소프트웨어를 사용하여 시뮬레이션 할 수도 있습니다. 위에 표시된 회로를 다시 만들고 16 진수 파일을 PIC에로드하면됩니다. 이 프로젝트의 16 진수 코드는 여기에 링크 된 ZIP 파일에서 찾을 수 있습니다. 시뮬레이션 중에 찍은 스크린 샷은 아래와 같습니다.
시뮬레이션은 프로젝트에 새로운 기능을 추가하려고 할 때 매우 유용합니다. I2C 디버거 모듈을 사용하여 I2C 버스를 통해 들어오고 나가는 데이터를 확인할 수도 있습니다. 버튼을 눌러보고 알람 시간을 설정할 수도 있습니다. 설정된 시간이 현재 시간과 같으면 부저가 높아집니다.
PIC16F877A를 사용한 디지털 알람 시계 작동:
브레드 보드에 회로를 빌드하고 다운로드 링크에서 코드를 가져온 다음 MplabX 및 XC8 컴파일러를 사용하여 컴파일합니다. 여기에 제공된 ZIP 파일에서 코드를 다운로드했다면 헤더 파일이 이미 첨부되어 있으므로 컴파일하는 데 문제가 없습니다.
컴파일 후 PicKit3 프로그래머를 사용하여 하드웨어에 프로그램을 업로드합니다. Pickit 프로그래머를 PIC IC에 연결하기위한 연결도 회로도에 표시됩니다. 프로그램이 업로드되면 인트로 화면이 표시되고 시간이 표시되면 푸시 버튼을 사용하여 알람 시간을 설정할 수 있습니다. 전원이 공급 될 때의 하드웨어 설정은 다음과 같습니다.
알람 시간이 현재 시간과 일치하면 부저가 울리기 시작 하여 사용자에게 경고합니다. 전체 작업은 아래 비디오 에서 찾을 수 있습니다. 이 프로젝트에는 구축 할 수있는 많은 옵션이 있습니다. RTC 모듈은 모든 시간과 날짜를 추적 할 수 있으므로 필요한 시간 / 날짜에 예약 된 작업을 수행 할 수 있습니다. 팬이나 조명과 같은 AC 기기를 연결하고 필요할 때 켜거나 끄도록 예약 할 수도 있습니다. 이 프로젝트를 기반으로 더 많은 것을 만들 수 있습니다.이 프로젝트를 업그레이드 할 때 어떤 아이디어가 떠오르는 지 알려 주시면 기꺼이 답변 해 드리겠습니다.
프로젝트를 이해하고 그 과정에서 유용한 것을 배웠기를 바랍니다. 이 프로젝트에 의문이있는 경우 댓글 섹션을 사용하여 게시하거나 포럼을 사용하여 기술적 인 도움을 받으십시오.
헤더 파일이있는 전체 PIC 코드는 여기에서 찾을 수 있습니다.