精品国产人成在线_亚洲高清无码在线观看_国产在线视频国产永久2021_国产AV综合第一页一个的一区免费影院黑人_最近中文字幕MV高清在线视频

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

基于PIC16F877A微控制器構建的數字鬧鐘

科技觀察員 ? 來源:circuitdigest ? 作者:阿斯文斯·拉吉 ? 2022-11-15 16:55 ? 次閱讀

始于1950年的數字革命將所有現有的機械模擬電子結構轉變為數字計算機。由于數字電子產品的增長呈指數級增長,今天一個人幾乎不可能抗拒使用任何電子設備。從叫醒你的鬧鐘和為你提供早餐的烤面包機開始,一切都是數字電子產品的貢獻。考慮到所有這些,對我們自己的東西進行編程真的很令人興奮,這些東西可以完成簡單而有用的任務,比如我們將在這個項目中使用PIC 微控制器構建的鬧鐘。

該鬧鐘將有一個 16x2 LCD 顯示屏,將顯示當前時間和設置時間。我們將在需要時使用幾個按鈕來設置鬧鐘時間。使用DS3231RTC模塊可以跟蹤當前時間,我們將使用IIC通信從RTC模塊獲取這些值。我們已經了解了 RTC 模塊以及如何將其與 PIC 接口。因此,建議通讀該教程,我們將跳過該教程中涵蓋的大部分信息

所需材料:

面包板 – 2Nos

PIC16F877A

5V 電源 - 電源模塊

20兆赫晶體

33pf 電容器 – 2 常開

DS3231 RTC 模塊

16*2液晶顯示模塊

10K 鍋

10k 和 1K 電阻

按鈕 – 5 否

蜂鳴器

連接線

先決條件:

本項目要求您了解一些有關PIC微控制器以及如何對其進行編程的基礎知識。我們將在這個項目中使用GPIO,LCD顯示器和RTC模塊。因此,最好事先學習如何使用這些模塊。

電路圖:

這個基于PIC的鬧鐘項目的電路圖如下所示,該項目是使用proteus軟件創建的。該項目還將用于進一步的仿真

poYBAGNzVA-AASGoAADBN-y9ayo128.png

五個按鈕將作為輸入,用于將鬧鐘設置為所需時間。因此,所有按鈕的一端接地,另一端連接到PORTB引腳,這些引腳上將使用內部上拉電阻,以避免引腳浮動。蜂鳴器將充當輸出,并在警報被觸發并連接到 PORT S 引腳時給我們發出嗶嗶聲。當前時間始終由DS3231RTC模塊跟蹤,PIC通過I2C總線從該模塊接收數據,因此RTC模塊的SCL和SDA引腳連接到PIC控制器的SCL和SDA引腳。LCD顯示器連接到PIC的PORTD,用于顯示當前時間和設定時間。在此處了解有關DS3231 RTC模塊與PIC配合使用的更多信息。

整個電路可以構建在面包板上。由于有幾十根電線要連接,所以請耐心等待并確保連接正確。完成連接后,我的硬件設置如下所示

pYYBAGNzVBKAHlk-AAEIReuOf2g254.jpg

我使用面包板模塊和 12V 適配器為模塊供電。這是我的+5V電源電壓源。此外,我還必須使用兩個面包板來保持電路清潔。如果您希望制作更強大的項目,您還可以將整個電路焊接到性能板上。

鬧鐘編程:

此鬧鐘項目的完整PIC程序可以在此頁面底部找到。該項目還需要三個庫來使用LCD,I2C和RTC和PIC。

在進入主程序之前,我們必須定義使用更有意義的名稱使用的引腳。這樣,在編程過程中就很容易使用它們。我們程序中定義的引腳如下所示

//Define the LCD pins

#define RS RD2 //Reset pin of LCD

#define EN RD3 //Enable pin of LCD

#define D4 RD4 //Data bit 0 of LCD

#define D5 RD5 //Data bit 1 of LCD

#define D6 RD6 //Data bit 2 of LCD

#define D7 RD7 //Data bit 3 of LCD

//Define Buttons

#define MB RB1 //The middle button

#define LB RB0 //Left button

#define RB RB2 //Right button

#define UB RB3 //Upper Button

#define BB RB4 //Bottom button

//Define Buzz

#define BUZZ RD1 //Buzzer is connected to RD1

在 main 函數中,我們首先聲明輸入和輸出引腳。在我們的項目中,PORTB 用于按鈕,這是一個輸入設備,因此我們將它們的引腳設置為輸入,PORTD 用于 LCD 和蜂鳴器,因此我們將它們的引腳設置為輸出。此外,引腳不應懸空,I/O引腳應始終連接到地或+5V電壓。在我們的例子中,對于按鈕,當按鈕未按下時,引腳不會連接到任何東西,因此我們使用內部上拉電阻器,該電阻器在不使用時將引腳設置為高電平。這是使用控制寄存器完成的,如下所示

TRISD = 0x00; //Make Port D pins as outptu for LCD interfacing

TRISB = 0xFF; //Switchs are declared as input pins

OPTION_REG = 0b00000000; //Enable pull up Resistor on port B for switchs

BUZZ = 0; //Turn of buzzer

由于我們有與主程序鏈接的LCD和I2C頭文件,因此我們可以通過調用一個簡單的函數來開始LCD初始化。I2C初始化也可以這樣做。在這里,我們以 100kHz 開始 I2C 通信,因為 RTC 模塊以 100kHz 工作。

Lcd_Start(); // Initialize LCD module

I2C_Initialize(100); //Initialize I2C Master with 100KHz clock

下面的函數用于在RTC模塊上設置時間和日期,一旦設置了時間和日期,請刪除此行。否則,每次啟動程序時,都會一次又一次地設置時間和日期

//Remove the below line once time and date is set for the first time.

Set_Time_Date(); //set time and date on the RTC module

為了指示程序正在啟動,我們顯示一個小的介紹屏幕,其中顯示項目名稱和網站名稱,如下所示

//Give an intro message on the LCD

Lcd_Clear();

Lcd_Set_Cursor(1,1);

Lcd_Print_String("Alarm Clock");

Lcd_Set_Cursor(2,1);

Lcd_Print_String(" -Circuit Digest");

__delay_ms(1500);

接下來在 while 循環中,我們需要從 RTC 模塊讀取當前時間和日期,這可以通過調用以下函數來完成。

Update_Current_Date_Time(); //Read the current date and time from RTC module

調用上述函數將使用當前值更新變量 sec、min 和 hour。為了在LCD屏幕上顯示它們,我們必須使用以下代碼將它們拆分為單個字符。

//Split the into char to display on lcd

char sec_0 = sec % 10;

char sec_1 = (sec / 10);

char min_0 = min % 10;

char min_1 = min / 10;

char hour_0 = hour % 10;

char hour_1 = hour / 10;

接下來,我們更新LCD屏幕上的值。當前時間將顯示在第一行,必須觸發警報的設置時間顯示在第二行。執行相同操作的代碼如下所示。

//Display the Current Time on the LCD screen

Lcd_Clear();

Lcd_Set_Cursor(1, 1);

Lcd_Print_String("TIME: ");

Lcd_Print_Char(hour_1 + '0');

Lcd_Print_Char(hour_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');

//Display the Date on the LCD screen

Lcd_Set_Cursor(2, 1);

Lcd_Print_String("Alarm: ");

Lcd_Print_Char(alarm_val[0] + '0');

Lcd_Print_Char(alarm_val[1] + '0');

Lcd_Print_Char(':');

Lcd_Print_Char(alarm_val[2] + '0');

Lcd_Print_Char(alarm_val[3] + '0');

現在,我們已經在LCD上顯示了時間和設置時間,我們必須檢查用戶是否正在嘗試設置鬧鐘時間。為此,用戶必須按下中間按鈕,因此我們將檢查是否按下中間按鈕并切換變量以進入警報設置模式。將再次按下相同的按鈕以確認已設置值,在這種情況下,我們必須退出警報設置模式。因此,我們使用下面的代碼行來更改變量set_alarm的狀態。

//Use middle button to check if alarm has to be set

if (MB == 0 && set_alarm == 0) { //If middle button is pressed and alarm is not turned on

while (!MB); //Wait till button is released

set_alarm = 1; //start setting alarm value

}

if (MB == 0 && set_alarm == 1) { //If middle button is pressed and alarm is not turned off

while (!MB); //Wait till button is released

set_alarm = 0; //stop setting alarm value

}

如果用戶按下了中間按鈕,則表示他正在嘗試設置鬧鐘時間。在這種情況下,程序使用上面的代碼進入警報設置模式。在警報設置模式下,如果用戶按下左或右按鈕,則意味著我們必須向左或向右移動光標。為此,我們只需遞增遞減光標必須放置的位置值

if (LB == 0) { //If left button is pressed

while (!LB); //Wait till button is released

pos--; //Then move the cursor to left

}

if (RB == 0) { //If right button is pressed

while (!RB); //Wait till button is released

pos++; //Move cursor to right

}

在將按鈕與微控制器或微處理器一起使用時,有一個常見問題需要解決。此問題稱為開關彈跳。也就是說,當按下按鈕時,它可能會給MCU / MPU發出嘈雜的脈沖,這可能會偽造MCU的多個條目。這個問題可以通過在開關上增加一個電容或在檢測到按鈕按下后立即使用延遲功能來解決。這種類型的解決方案稱為去抖動。在這里,我們使用了一個while循環來將程序固定到位,直到按鈕被釋放。這不是最好的去抖動解決方案,但對我們來說,它會很好地工作。

while (!RB);

與左右按鈕類似,我們也有上下按鈕,可用于增加或減少鬧鐘時間的值。執行相同操作的代碼如下所示。請注意,設置的警報時間的每個字符都由數組的索引值尋址。這是我們可以輕松訪問必須更改其值的所需字符。

if (UB == 0) { //If upper button is pressed

while (!UB); //Wait till button is released

alarm_val[(pos - 8)]++; //Increase that particular char value

}

if (BB == 0) { //If lower button is pressed

while (!UB); //Wait till button is released

alarm_val[(pos - 8)]--; //Decrease that particular char value

}

設置鬧鐘時間后,用戶將再次短按中間按鈕。然后我們可以開始將當前時間與設置的時間進行比較。通過檢查當前時間的每個字符是否等于設置時間的字符來進行比較。如果值相等,那么我們通過設置 trigger_alarm 變量來觸發警報,否則我們只是比較直到它相等。

//IF alarm is set Check if the set value is equal to current value

if (set_alarm == 0 && alarm_val[0] == hour_1 && alarm_val[1] == hour_0 && alarm_val[2] == min_1 && alarm_val[3] == min_0)

trigger_alarm = 1; //Turn on trigger if value match

如果設置了警報,我們必須發出蜂鳴器以提醒用戶警報。這可以通過簡單地定期切換蜂鳴器來完成,如下所示。

if (trigger_alarm) { //If alarm is triggered

//Beep the buzzer

BUZZ = 1;

__delay_ms(500);

BUZZ = 0;

__delay_ms(500);

}

模擬

該程序也可以使用變形蟲軟件進行模擬。只需重新創建上面顯示的電路,并將十六進制文件加載到 PIC 中即可。

模擬期間拍攝的屏幕截圖如下所示

poYBAGNzVBOADiPYAABPqwO1h4U864.png

當您嘗試向項目添加新功能時,模擬變得非常有用。您 還 可以 使用 I2C 調試 器 模 塊 來 檢查 哪些 數據 通過 I2C 總 線 進出。您可以嘗試按下按鈕并設置鬧鐘時間。當設定的時間等于當前時間時,蜂鳴器將變高。

使用PIC16F877A的數字鬧鐘工作:

在試驗板上構建電路,從下載鏈接獲取代碼并使用MplabX和XC8編譯器進行編譯。

編譯后,使用PicKit3編程器將程序上傳到您的硬件。電路圖中還顯示了將拾取器編程器連接到PIC IC的連接。程序上傳后,您應該會看到介紹屏幕,然后顯示時間,然后您可以使用按鈕設置鬧鐘時間。通電時的硬件設置如下所示。

pYYBAGNzVBuAKbDCAAD5LP0kPMI676.jpg

當鬧鐘時間與當前時間匹配時,蜂鳴器將開始發出蜂鳴聲以提醒用戶。完整的工作可以在下面的視頻中找到。該項目有很多選擇可以構建。RTC 模塊可以跟蹤任何時間和日期,因此您可以在所需的任何時間/日期執行計劃任務。您還可以連接風扇或燈等交流電器,并在需要時安排其打開或關閉。

/*

* Program: Alarm Clock Using PIC

* Author: B.Aswinth Raj

* More info: www.circuitdigest.com

* Created on 11 May, 2018, 3:02 PM

*/

#pragma config FOSC = HS // Oscillator Selection bits (HS oscillator)

#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled)

#pragma config PWRTE = ON // Power-up Timer Enable bit (PWRT enabled)

#pragma config BOREN = ON // Brown-out Reset Enable bit (BOR enabled)

#pragma config LVP = OFF // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming)

#pragma config CPD = OFF // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off)

#pragma config WRT = OFF // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)

#pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off)


#define _XTAL_FREQ 20000000 //We are running on 20MHz crystal


//Define the LCD pins

#define RS RD2 //Reset pin of LCD

#define EN RD3 //Enable pin of LCD

#define D4 RD4 //Data bit 0 of LCD

#define D5 RD5 //Data bit 1 of LCD

#define D6 RD6 //Data bit 2 of LCD

#define D7 RD7 //Data bit 3 of LCD


//Define Buttons

#define MB RB1 //The middle button

#define LB RB0 //Left button

#define RB RB2 //Right button

#define UB RB3 //Upper Button

#define BB RB4 //Bottom button


//Define Buzz

#define BUZZ RD1 //Buzzer is connected to RD1


/*Set the current value of date and time below*/

int sec = 00;

int min = 55;

int hour = 10;

int date = 06;

int month = 05;

int year = 18;

/*Time and Date Set*/


/*Vars for Alarm clock*/

char set_alarm = 0;

char trigger_alarm = 0;

char pos = 8;

char jump = 0;


char alarm_h0 = 0;

char alarm_h1 = 0;

char alarm_m0 = 0;

char alarm_m1 = 0;

int alarm_val[4] = {0, 0, 0, 0};

/*End of var declaration*/


#include

#include "lcd.h" //Header for using LCD module

#include "PIC16F877a_I2C.h" // Header for using I2C protocal

#include "PIC16F877a_DS3231.h" //Header for using DS3231 RTC module


int main() {


TRISD = 0x00; //Make Port D pins as outptu for LCD interfacing

TRISB = 0xFF; //Switchs are declared as input pins

OPTION_REG = 0b00000000; //Enable pull up Resistor on port B for switchs

BUZZ = 0; //Turn of buzzer


Lcd_Start(); // Initialize LCD module


I2C_Initialize(100); //Initialize I2C Master with 100KHz clock


//Remove the below line once time and date is set for the first time.

Set_Time_Date(); //set time and date on the RTC module


//Give an intro message on the LCD

Lcd_Clear();

Lcd_Set_Cursor(1,1);

Lcd_Print_String("Alarm Clock");

Lcd_Set_Cursor(2,1);

Lcd_Print_String(" -Circuit Digest");

__delay_ms(1500);


while (1) {


Update_Current_Date_Time(); //Read the current date and time from RTC module


//Split the into char to display on lcd

char sec_0 = sec % 10;

char sec_1 = (sec / 10);

char min_0 = min % 10;

char min_1 = min / 10;

char hour_0 = hour % 10;

char hour_1 = hour / 10;



//Display the Current Time on the LCD screen

Lcd_Clear();

Lcd_Set_Cursor(1, 1);

Lcd_Print_String("TIME: ");

Lcd_Print_Char(hour_1 + '0');

Lcd_Print_Char(hour_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');





//Display the Date on the LCD screen

Lcd_Set_Cursor(2, 1);

Lcd_Print_String("Alarm: ");

Lcd_Print_Char(alarm_val[0] + '0');

Lcd_Print_Char(alarm_val[1] + '0');

Lcd_Print_Char(':');

Lcd_Print_Char(alarm_val[2] + '0');

Lcd_Print_Char(alarm_val[3] + '0');


__delay_ms(50);



//Use middle button to check if alarm has to be set

if (MB == 0 && set_alarm == 0) { //If middle button is pressed and alarm is not turned on

while (!MB); //Wait till button is released

set_alarm = 1; //start setting alarm value

}

if (MB == 0 && set_alarm == 1) { //If middle button is pressed and alarm is not turned off

while (!MB); //Wait till button is released

set_alarm = 0; //stop setting alarm value

}



//If alarm has to be navigate through each digit

if (set_alarm == 1) {

if (LB == 0) { //If left button is pressed

while (!LB); //Wait till button is released

pos--; //Then move the cursor to left

}

if (RB == 0) { //If right button is pressed

while (!RB); //Wait till button is released

pos++; //Move cursor to right

}


if (pos >= 10) //eliminate ":" symbol if cursor reaches there

{

jump = 1; //Jump over the ":" symbol

} else

jump = 0; //get back to normal movement



if (UB == 0) { //If upper button is pressed

while (!UB); //Wait till button is released

alarm_val[(pos - 8)]++; //Increase that particular char value

}

if (BB == 0) { //If lower button is pressed

while (!UB); //Wait till button is released

alarm_val[(pos - 8)]--; //Decrease that particular char value

}


Lcd_Set_Cursor(2, pos + jump);

Lcd_Print_Char(95); //Display "_" to indicate cursor position

}


//IF alarm is set Check if the set value is equal to current value

if (set_alarm == 0 && alarm_val[0] == hour_1 && alarm_val[1] == hour_0 && alarm_val[2] == min_1 && alarm_val[3] == min_0)

trigger_alarm = 1; //Turn on trigger if value match




if (trigger_alarm) { //If alarm is triggered

//Beep the buzzer

BUZZ = 1;

__delay_ms(500);

BUZZ = 0;

__delay_ms(500);

}


__delay_ms(200);//Update interval


}


return 0;

}

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 微控制器
    +關注

    關注

    48

    文章

    7490

    瀏覽量

    151056
  • PIC16F877A
    +關注

    關注

    2

    文章

    43

    瀏覽量

    21782
  • 數字鬧鐘
    +關注

    關注

    0

    文章

    6

    瀏覽量

    5442
收藏 人收藏

    評論

    相關推薦

    將繼電器與PIC微控制器PIC16F877A連接的教程

    在本項目中,我們將繼電器與PIC微控制器PIC16F877A連接。繼電器是一種機械設備,用于從較低的電壓電平控制高電壓、大電流電器的“ON”或“OFF”。繼電器在兩個電壓電平之間提供隔
    的頭像 發表于 11-14 16:20 ?3331次閱讀
    將繼電器與<b class='flag-5'>PIC</b><b class='flag-5'>微控制器</b><b class='flag-5'>PIC16F877A</b>連接的教程

    如何使用PIC微控制器旋轉步進電機

    在本教程中,我們將步進電機與PIC微控制器PIC16F877A連接。
    發表于 11-15 17:25 ?1443次閱讀
    如何使用<b class='flag-5'>PIC</b><b class='flag-5'>微控制器</b>旋轉步進電機

    如何使用PIC微控制器構建一個線路跟隨機器人

    線路跟隨機器人是一個簡單而迷人的機器人,適合大多數學生/業余愛好者建造。在本教程中,我們將學習線路跟隨機器人的工作原理以及如何使用 PIC 微控制器 PIC16F877A 構建一個。
    發表于 11-30 17:17 ?1549次閱讀
    如何使用<b class='flag-5'>PIC</b><b class='flag-5'>微控制器</b><b class='flag-5'>構建</b>一個線路跟隨機器人

    pic16f877a中文資料pdf

    pic16f877a中文資料
    發表于 07-15 13:20 ?4548次下載
    <b class='flag-5'>pic16f877a</b>中文資料pdf

    基于PIC16F877A的太陽能與市電互補照明系統控制器的設

    基于PIC16F877A的太陽能與市電互補照明系統控制器的設計 介紹了一款以單片機PIC16F877A控制核心的太陽能與市電互補照明系統控制器
    發表于 04-10 22:06 ?1346次閱讀
    基于<b class='flag-5'>PIC16F877A</b>的太陽能與市電互補照明系統<b class='flag-5'>控制器</b>的設

    PIC16F877A串口發送查詢方式

    PIC16F877A串口發送,查詢方式,就為了調出這個費了我一天時間,原來是串口芯片電壓問題,現總結如下
    發表于 09-01 11:03 ?10次下載
    <b class='flag-5'>PIC16F877A</b>串口發送查詢方式

    PIC16F877A串口芯片電壓問題

    PIC16F877A串口發送,查詢方式,就為了調出這個費了我一天時間,原來是串口芯片電壓問題,現總結如下
    發表于 09-01 11:15 ?9次下載
    <b class='flag-5'>PIC16F877A</b>串口芯片電壓問題

    PIC16F877A的T0定時制作的電子鐘程序

    經過努力,利用PIC16F877A的T0定時制作的電子鐘實驗成功!
    發表于 05-15 09:42 ?1877次閱讀

    PIC16F877A開發板 數碼管動態掃描實驗

    //****************電子園PIC16F877A開發板 數碼管動態掃描實驗****************//////mcu: PIC16F877A 4MHz //2010年12月
    發表于 11-16 19:51 ?13次下載
    <b class='flag-5'>PIC16F877A</b>開發板 數碼管動態掃描實驗

    PIC16F877A開發板 普通IO驅動74595實驗

    //*****************電子園PIC16F877A開發板 普通IO驅動74595實驗***************////PIC16F877A 實驗板////mcu
    發表于 11-16 19:51 ?13次下載
    <b class='flag-5'>PIC16F877A</b>開發板 普通IO驅動74595實驗

    PIC16F877A 看門狗定時實驗

    //*******************PIC16F877A 看門狗定時實驗******************* // //PORTA,PORTB,PORTC,PORTD,PORTE
    發表于 11-16 20:06 ?8次下載
    <b class='flag-5'>PIC16F877A</b> 看門狗定時<b class='flag-5'>器</b>實驗

    使用熱敏打印機連接PIC16F877A并使用輕觸開關實現打印的教程

    在本教程中,我們將熱敏打印機 CSN A1 與廣泛使用的 PIC 微控制器 PIC16F877A 連接。在本項目中,熱敏打印機連接在PIC16F87
    的頭像 發表于 11-04 15:10 ?2742次閱讀
    使用熱敏打印機連接<b class='flag-5'>PIC16F877A</b>并使用輕觸開關實現打印的教程

    PIC16F877A單片機代碼生成系統

    PIC16F877A單片機代碼生成系統V3.4_221214_1035
    發表于 12-20 17:00 ?8次下載

    如何在PIC16F877A微控制器中使用EEPROM保存數據

    在本教程中,我們將了解使用 **PIC16F877A 微控制器中的 EEPROM** 保存數據是多么容易。在大多數實時項目中,我們可能必須保存一些數據,即使關閉電源也不應刪除這些數據。這聽起來像是一
    的頭像 發表于 01-25 15:39 ?2475次閱讀
    如何在<b class='flag-5'>PIC16F877A</b><b class='flag-5'>微控制器</b>中使用EEPROM保存數據

    PIC16F877A開發板原理圖

    PIC16F877A開發板原理圖免費下載。
    發表于 03-21 15:47 ?12次下載