仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
51hei.gif (228.62 KB, 下載次數(shù): 62)
下載附件
2022-4-27 22:15 上傳
單片機(jī)源程序如下:
- /*設(shè)計(jì)思路
- 1、利用定時(shí)器中斷0二十次產(chǎn)生1s時(shí)間變量miao增加到60變量分+1并把miao清零,shi同理
- 2、第一行左邊顯示年月日,右邊為功能區(qū),‘c’———調(diào)整時(shí)間,此時(shí)定時(shí)器中斷關(guān)閉
- ‘a(chǎn)’———調(diào)整鬧鐘,此時(shí)顯示的是設(shè)定鬧鐘的時(shí)間,小時(shí)和分鐘。
- ‘o’———鬧鐘開啟
- 第二行左邊為當(dāng)前調(diào)整的位,分別有 miao shi fen ri yue nian
- 3、采用4個(gè)按鍵 key1,key2,key3,key4
- 在時(shí)鐘模式下,調(diào)整區(qū)顯示‘TIME’:
- 當(dāng)長key4兩秒后首先進(jìn)入時(shí)間鐘整預(yù)選模式,此時(shí)調(diào)整區(qū)顯示‘clock’,此時(shí)單擊key1即可確定進(jìn)入時(shí)間調(diào)整模式,
- 此時(shí)功能區(qū)顯示的是當(dāng)前調(diào)整的位,按key1切換,key2,3進(jìn)行調(diào)整,調(diào)整完畢后單擊key4退出調(diào)整模式
- 再次長按key4進(jìn)入下一個(gè)預(yù)調(diào)整界面,調(diào)整區(qū)顯示‘a(chǎn)larm’,此時(shí)表示設(shè)置鬧種,方法與時(shí)鐘相同
- 再次長安key4進(jìn)入鬧鐘開關(guān)界面,調(diào)整區(qū)顯示‘onoff’,此時(shí)單擊key1可以開啟或關(guān)閉鬧鐘,‘o’表示開啟
- 再次長按,即可退出調(diào)整模式,調(diào)整區(qū)顯示‘TIME’
- 4、第一行日期后面顯示光照強(qiáng)度,0~102;
- */
- #include"XPT2046.h"
- #include"LCD1602.h"
- #include<reg52.h>
- void LCD_display(void);
- void keykan(void);
- void my_alarm_clock(void);
- void shezhi(void);
- void xingqi(void);
- void datapros(void);
- void T0_init();
- void delay(uint x);
- void mybeep(void);
- void mybeeplong(void);
- void mybeeplongplus(void);
- int num[10]={0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39}; // lcd1602 0~9字碼
- uchar miao=0, fen=5, shi=12 , zhou=1 , yue=6 , nian=21 ; //進(jìn)位標(biāo)志位 秒 分 時(shí) 周 月 年
- uchar ri=21; //進(jìn)位標(biāo)志位 日 不知道為啥放在上面會報(bào)錯(cuò),單獨(dú)定義就可以
- uint i=0; //定時(shí)器計(jì)時(shí)標(biāo)志位
- uchar *time[]={&miao , &fen , &shi ,&ri ,&yue , &nian, &zhou}; //指針變量time存放進(jìn)位標(biāo)志位的地址,由于數(shù)組不能存放標(biāo)量,但是卻可以存放標(biāo)量的地址,采用指針的方式來間接修改變量的值
- uchar naofen=0 , naoshi=7; //鬧鐘值
- uchar *nao[]={&naofen, &naoshi}; //存放鬧鐘值的數(shù)組
- uint light_ ;
- uchar set = 0 ;
- bit kaiguan=0;
- uchar SetPlace=0; //功能選擇標(biāo)志
- bit mod =0; //設(shè)置模式標(biāo)志位
- bit alarmset=0 , alarm=0 ; //鬧鐘設(shè)置需要的標(biāo)志位
- bit x=0; //鬧鐘開關(guān)標(biāo)志位
- sbit key1=P3^1; //定義四個(gè)按鍵 key1選擇需要調(diào)整的位
- sbit key2=P3^0; //key2加
- sbit key3=P3^2; //key3減
- sbit key4=P3^3; //長按兩秒鐘進(jìn)入或退出設(shè)置模式,前面三個(gè)按鍵需要進(jìn)入設(shè)置模式才能使用
- void datapros() //光敏電阻數(shù)值處理
- {
-
- static uchar i;
- if(i==40)
- {
- i=0;
- light_ = (Read_AD_Data(0xA4))/10; // AIN2 光敏電阻
- }
- i++;
- }
- //光照強(qiáng)度顯示函數(shù)
- void lightdisplay(void){
- LCD_disp_char(1,11,num[light_/100]);
- delay(50);
- LCD_disp_char(1,12,num[light_%100/10]);
- delay(50);
- LCD_disp_char(1,13,num[light_%100%10]);
- delay(50);
- }
- void xingqi(void){ //星期計(jì)算函數(shù)
- uchar c , y , m , d;
- c=20;
- y=nian;
- m=yue;
- d=ri;
- if (m==1|| m==2) //將12月按上一年1314月處理
- {
- m+=12;
- y-=1;
- }
- zhou = ((c/4) - 2*c +y + (y/4) + (13*(m+1)/5)+d-1)%7; //蔡勒公式
- }
- void main(void) //主函數(shù)
- {
- T0_init(); //定時(shí)器初始化
- LCD_init(); //lcd1602初始化
- SPI_Start(); //AD初始化
- while(1) //死循環(huán)
- {
- datapros();
- lightdisplay();
- shezhi();
- my_alarm_clock();
- keykan();
- xingqi();
- LCD_display(); //lcd1602顯示時(shí)分秒年月日周
- }
-
- }
- void keykan(void) //按鍵處理函數(shù)
- {
- if ((alarmset==0) && (mod==0))
- {
- LCD_disp_char(1,14,' ');
- delay(50);
- }
-
- if (alarmset==1)
- {
- LCD_disp_char(1,14,'a');
- if (SetPlace==0) //功能選擇位為0就顯示“miao” 為1就顯示“fen” 以此類推
- {
- LCD_row(2);
- LCD_DispString(" fen ");
- delay(50);
- }
- switch (SetPlace) //調(diào)整位閃爍
- {
- case 0 : { LCD_disp_char(2,12,' ');
- delay(700);} ; break;
- case 1 : { LCD_disp_char(2,9,' ');
- delay(700);} ; break;
- }
-
- if(key1==0) //檢測按鍵key1是否按下
- {
- delay(10); //消除抖動
- if(key1==0)
- { //按一下功能選擇位就+1,加到7就清零
- SetPlace++;
- if(SetPlace>=2)
- SetPlace=0;
- }
-
- if (SetPlace==1)
- {
- LCD_row(2);
- LCD_DispString(" shi ");
- delay(50);
- }
- mybeep(); //蜂鳴器發(fā)聲
- while(key1==0) //檢測按鍵是否松開
- {
- delay(10);
- }
- }
-
- if(key2==0) //檢測按鍵key2是否按下
- {
- delay(10); //消除抖動
- if(key2==0)
- {
- (*nao[SetPlace])++; //按鍵按一次 指針數(shù)組*time[SetPlace]里對應(yīng)的地址的數(shù)據(jù)值就+1,也就是說進(jìn)位標(biāo)志位年月日時(shí)分秒的值就會+1
- if ((((*nao[SetPlace]))>=60) && (SetPlace==0))
- {
- (*nao[SetPlace])=0; //秒只能加dao59
- }
- if ((((*nao[SetPlace]))>=60) && (SetPlace==1))
- {
- (*nao[SetPlace])=0; //分只能加到59
- }
-
-
- mybeep(); //蜂鳴器發(fā)聲
- while(key2==0) //檢測按鍵是否松開
- {
- delay(10);
- }
- }
- }
- if(key3==0) //檢測按鍵key3是否按下
- {
- delay(10); //消除抖動
- if(key3==0)
- {
- //按鍵按一次 指針數(shù)組*time[SetPlace]里對應(yīng)的地址的數(shù)據(jù)值就+1,也就是說進(jìn)位標(biāo)志位年月日時(shí)分秒的值就會+1
- if ((((*nao[SetPlace]))<=0) && (SetPlace==0))
- {
- (*nao[SetPlace])=60; //秒只能加dao59
- }
- if ((((*nao[SetPlace]))<=0) && (SetPlace==1))
- {
- (*nao[SetPlace])=60; //分只能加到59
- }
- (*nao[SetPlace])--;
-
- mybeep(); //蜂鳴器發(fā)聲
- while(key3==0) //檢測按鍵是否松開
- {
- delay(10);
- }
- }
- }
- }
-
- if (mod==1) //如果進(jìn)入設(shè)置模式顯示一個(gè)c
- {
- LCD_disp_char(1,14,'c');
- if (SetPlace==0) //功能選擇位為0就顯示“miao” 為1就顯示“fen” 以此類推,shi zhou ri yue nian
- {
- LCD_row(2);
- LCD_DispString("miao ");
- delay(50);
- }
- switch (SetPlace) //調(diào)整位閃爍
- {
- case 0 : { LCD_disp_char(2,15,' ');
- delay(700);} ; break;
- case 1 : { LCD_disp_char(2,12,' ');
- delay(700);} ; break;
- case 2 : { LCD_disp_char(2,9,' ');
- delay(700); } ; break;
- case 3 : { LCD_disp_char(1,9,' ');
- delay(700); } ; break;
- case 4 : { LCD_disp_char(1,6,' ');
- delay(700); } ; break;
- case 5 : { LCD_disp_char(1,3,' ');
- delay(700); } ; break;
-
- }
-
- if(key1==0) //檢測按鍵key1是否按下
- {
- delay(10); //消除抖動
- if(key1==0)
- { //按一下功能選擇位就+1,加到7就清零
- SetPlace++;
- if(SetPlace>=6)
- SetPlace=0;
- }
- switch (SetPlace) //調(diào)整為顯示
- {
- case 1 : { LCD_row(2);
- LCD_DispString(" fen ");
- delay(50);} ; break;
- case 2 : { LCD_row(2);
- LCD_DispString(" shi ");
- delay(50); } ; break;
- case 3 : { LCD_row(2);
- LCD_DispString(" ri ");
- delay(50); } ; break;
- case 4 : { LCD_row(2);
- LCD_DispString(" yue ");
- delay(50); } ; break;
- case 5 : { LCD_row(2);
- LCD_DispString("nian ");
- delay(50); } ; break;
-
- }
- mybeep(); //蜂鳴器發(fā)聲
- while(key1==0) //檢測按鍵是否松開
- {
- delay(10);
- }
-
- }
- if(key2==0) //檢測按鍵key2是否按下
- {
- delay(10); //消除抖動
- if(key2==0)
- {
-
- (*time[SetPlace])++; //按鍵按一次 指針數(shù)組*time[SetPlace]里對應(yīng)的地址的數(shù)據(jù)值就+1,也就是說進(jìn)位標(biāo)志位年月日時(shí)分秒的值就會+1
- if ((((*time[SetPlace]))>=60) && (SetPlace==0))
- {
- (*time[SetPlace])=0; //秒只能加dao59
- }
- void LCD_display(void) //lcd1602顯示年月日時(shí)分秒周
- {
- LCD_disp_char(2,6, *time[6]); //顯示周幾 此處顯示的為自定義字符 當(dāng)zhou=1的時(shí)候即*time[3]=1 對應(yīng)地址0x01的字符為 一 ;以此類推
- delay(50);
- LCD_disp_char(2,15,num[*time[0]%10]); //顯示秒的個(gè)位 當(dāng)miao%10的值為0時(shí)即(*time[0])==0, 此時(shí)num[0]=0x30 對應(yīng)1602字符庫中的0 ,lcd1602對應(yīng)第2行第16位顯示0
- delay(50); //當(dāng)miao%10的值為1時(shí)即(*time[1])==1, 此時(shí)num[1]=0x31 對應(yīng)1602字符庫中的1
- LCD_disp_char(2,14,num[*time[0]/10]); //秒的十位
- delay(50);
- LCD_disp_char(2,13,':');
- delay(50);
- if (alarmset==0) //時(shí)鐘模式
- {
- LCD_disp_char(2,12,num[*time[1]%10]); //分的各位
- delay(50);
-
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復(fù)制代碼 RAM地址映射
HD44780內(nèi)置DDRAM、CGROM和CGRAM。
DDRAM就是顯示數(shù)據(jù)RAM,用來寄存待顯示的字符代碼。共80個(gè)字節(jié),地址和屏幕的對應(yīng)關(guān)系如下:
也就是說想要在LCD1602屏幕上的第一行第一個(gè)位置顯示一個(gè)“A”,就要向DDRAM的00H地址寫“A”字的代碼就OK了,但具體的寫入是要按照LCD模塊的指令格式來進(jìn)行的。在寫入地址是,地址最高位D7必須為1,所以實(shí)際寫入數(shù)據(jù)應(yīng)該是80H。 控制時(shí)序圖 圖3-2 讀操 作時(shí)序
圖3-3 寫操作時(shí)序 代碼實(shí)現(xiàn) 1、寫指令 RS=L,RW=L,D0~D7=指令碼,E=高脈沖。 寫指令函數(shù)代碼段: void LCD_write_command(uchar dat) { LCD_DB=dat; LCD_RS=0; //指令 LCD_RW=0; //寫入 LCD_E=1; //允許 LCD_E=0; delay_n40us(2); } 2、寫數(shù)據(jù) RS=H,RW=L,D0~D7=數(shù)據(jù),E=高脈沖。 寫數(shù)據(jù)函數(shù)代碼片段 void LCD_write_data(uchar dat ) { LCD_DB=dat; LCD_RS=1; //數(shù)據(jù) LCD_RW=0; //寫入 LCD_E=1; //允許 LCD_E=0; delay_n40us(2); } 有了以上基礎(chǔ)知識我們就能夠?qū)?602顯示屏進(jìn)行基本的顯示操作了,1602內(nèi)置字符發(fā)生器CGROM中儲存了160個(gè)字符,每一個(gè)字符都有一個(gè) 固定的代碼,我把它理解為地址,可以參考其字符代碼與字符圖形對應(yīng)的關(guān)系。
(4)CGRAM自定義字模(簡易漢字顯示,我把它用來顯示星期) 這里說明一下lcd1602液晶是不能顯示漢字的,因?yàn)樗娘@示原理是由若干個(gè)5X7或者5X11的點(diǎn)陣字符位組成的,又因?yàn)闈h字較為復(fù)雜,所以1602的主要作用就是顯示字母、數(shù)字、符號的。但是真的不能顯示漢字嗎?也并非絕對不能。
接就是下面要說的CGRAM自定義字模。要顯示我們自定義的字符,就要用到LCD中的CGRAM存儲器(character generate RAM),而我們之前用的顯示自帶的字符用到的是DDRAM,兩個(gè)是不同的。看手冊我們知道,CGRAM的容量是64個(gè)字節(jié),而一個(gè)字符是8個(gè)字節(jié),所以一共能顯示8個(gè)自定義的字符。內(nèi)部常用字符的顯示是從0x20開始的,0x00 ~ 0x0F是專門留給自定義字符顯示用的,0x00-0x07和0x08~0x0F顯示的內(nèi)容是一樣的,也就是說0x00=0x08,0x01=0x09,以此類推。CGRAM共128個(gè)位,地址是0x40-0x7F,128/8=16正好對應(yīng)的是0x00-0x0F共16個(gè),剛才說了,0x00與0x08對應(yīng),0x01與0x09對應(yīng),共16個(gè),這并不矛盾!說了這么多,那么怎樣顯示一個(gè)自定義字符呢?
首先我們要清楚LCD1602顯示字符的點(diǎn)陣大小,眼力好的可以看出來,LCD1602一個(gè)顯示字符的位置是58的點(diǎn)陣,也就是說它所能顯示的點(diǎn)陣圖形的大小是58的!要顯示一個(gè)自定義的字符,首先我們要知道所顯示自定義字符的點(diǎn)陣數(shù)據(jù),也就是在一個(gè)58的點(diǎn)陣上那個(gè)點(diǎn)是黑的(將該點(diǎn)點(diǎn)黑,就是高電平----1),哪個(gè)點(diǎn)是白的(該點(diǎn)不顯示,為低電平----0),但是我們送入到LCD中的是ASCII碼,它是8位的數(shù)據(jù),而一個(gè)顯示字符的點(diǎn)陣大小只是58的,顯然不夠,顯示的辦法是8*8點(diǎn)陣的前三列不用,也就是不顯示,我們只用后面的5列來顯示。
然后設(shè)定我們是要定義第幾個(gè)自定義字符,前面已經(jīng)介紹了,LCD1602最多顯示8個(gè)自定義字符;然后要規(guī)定在液晶的什么位置顯示自定義字符,看過數(shù)據(jù)手冊我們知道,第一行第一個(gè)位置的地址是0x80,第二行一個(gè)位置的地址是0xC0。最后就是要顯示我們定義的第幾個(gè)字符其對應(yīng)CGRAM地址的關(guān)系式是:
0x00:第一個(gè)(0x40) 0x01:第二個(gè)(0x48) 0x02:第三個(gè)(0x50) 0x03:第四個(gè)(0x58) 0x04:第五個(gè)(0x60) 0x05:第六個(gè)(0x68) 0x06:第七個(gè)(0x70) 0x07:第八個(gè)(0x78)
每個(gè)字符由5X8點(diǎn)陣組成,想要實(shí)現(xiàn)顯示,只需如下圖:例:以5X8點(diǎn)陣為例,顯示字符 A 0代表滅,1代表亮
只需將想要顯示的字符的對應(yīng)位置1,就能顯示該字
01110 □█ █ █□ 10001 █ □□□ █ 10001 █ □□□ █ 10001 █ □□□ █ 11111 █ ███ █ 10001 █ □□□ █ 10001 █ □□□ █ 10001 █ □□□ █ A={0x0e,0x11,0x11,0x11,0x1f,0x11,0x11,0x11} 定義好自定義字符后,需要將定義的字符裝入CGRAM中
代碼實(shí)現(xiàn)如下: 1、定義了一個(gè)存儲簡單漢字的數(shù)組 uint code Xword[]={ 0x1F,0x15,0x1D,0x17,0x11,0x15,0x01,0x00, //周,代碼 0x00(由于這個(gè)lcd1602像素太小了5*8,這個(gè)周字屬實(shí)有點(diǎn)認(rèn)不出) 0x00,0x00,0x00,0x00,0xff,0x00,0x00,0x00, //一,代碼 0x01 0x00,0x00,0x00,0x0e,0x00,0xff,0x00,0x00, //二,代碼 0x02 0x00,0x00,0xff,0x00,0x0e,0x00,0xff,0x00, //三,代碼 0x03 0x00,0x00,0xff,0xf5,0xfb,0xf1,0xff,0x00, //四,代碼 0x04 0x00,0xfe,0x08,0xfe,0x0a,0x0a,0xff,0x00, //五,代碼 0x05 0x00,0x04,0x00,0xff,0x00,0x0a,0x11,0x00, //六,代碼 0x06 0x00,0x1f,0x11,0x1f,0x11,0x11,0x1f,0x00, //日,代碼 0x07 }; 2、將數(shù)組內(nèi)容寫入CGRAM void CgramWrite(void) { // 裝入CGRAM // uint i; LCD_write_command(0x06); // CGRAM地址自動加1 LCD_write_command(0x40); // CGRAM地址設(shè)為00處 for(i=0;i<64;i++) { LCD_write_data(Xword[ i]);// 按數(shù)組寫入數(shù)據(jù) } }
由此我們就能讓我們的電子時(shí)鐘顯示簡單的漢字:一、二、三、四、五、六、日。
(五)XPT2046芯片使用簡介(XPT2046的功能有很多,我在這里只做了簡單的ADC使用方法介紹,更多詳細(xì)的內(nèi)容可參考附件XPT2046中文資料。) XPT2046 是一種典型的逐次逼近型模數(shù)轉(zhuǎn)換器(SAR ADC),包含了采樣/保持、模數(shù)轉(zhuǎn)換、串口數(shù)據(jù) 輸出等功能。同時(shí)芯片集成有一個(gè) 2.5V的內(nèi)部參考電壓源、溫度檢測電路,工作時(shí)使用外部時(shí)鐘。XPT2046 可以單電源供電,電源電壓范圍為 2.7V~5.5V。參考電壓值直接決定ADC的輸入范圍,參考電壓可以使用內(nèi)部參考電壓,也可以從外部直接輸入 1V~VCC范圍內(nèi)的參考電壓(要求外部參考電壓源輸出阻抗低)。我這塊開發(fā)板使用的參考電壓為XPT2046供電電壓5V。
我們需要了解和使用到的幾個(gè)引腳如圖所示,我用圓圈圈出來了:
圖5-1 XPT2016引腳說明 
了解完引腳之后,就要看怎么去使用和控制這些引腳來達(dá)成目標(biāo),
所以接下來要看的就是時(shí)序工作圖,要了解芯片是如何工作,如何完成采樣 保持 量化 編碼這幾個(gè)步驟的。一次完整的轉(zhuǎn)換需要 24 個(gè)串行同步時(shí)鐘(DCLK)來完成。(看DCLK時(shí)序那,一共出現(xiàn)了3次8, 3*8=24) 
圖5-1 8位總線接口,無DCLK時(shí)鐘延遲,24時(shí)鐘周期轉(zhuǎn)換時(shí)序 
表5-2 制字的控制位命令 
表5-3 單端模式輸入配置
要想啟動選中該芯片,首先得給CS和CLK置0 (因?yàn)閱纹瑱C(jī)默認(rèn)引腳輸出1) ,然后開始寫入數(shù)據(jù)。 處理器和轉(zhuǎn)換器之間的的通信需要 8 個(gè)時(shí)鐘周期,可采用 SPI、SSI 和Microwire 等同步串行接口。前面8個(gè)時(shí)鐘就在進(jìn)行通信。 前8個(gè)時(shí)鐘就是用來通過DIN引腳輸入控制字節(jié)。 先看DIN的時(shí)序(圖中有幾個(gè)英文單詞,Idle的意思是閑置的意思,aquire是獲取的意思,conversion是轉(zhuǎn)換的意思,個(gè)人理解是圖中把DIN在24個(gè)時(shí)鐘周期內(nèi)的變化,分成了幾個(gè)段,閑置段,獲取段,轉(zhuǎn)換段)DIN的控制位有8位,下面開始從最高位開始介紹:
控制字節(jié)由 DIN 輸入的控制字如表所示,它用來啟動轉(zhuǎn)換,尋址,設(shè)置 ADC 分辨率,配置和對XPT2046 進(jìn)行掉電控制。圖4-1和表4-2給出控制字的各控制位的詳細(xì)說明。 起始位——第一位,即 S 位。控制字的首位必須是 1,即 S=1。在 XPT2046 的 DIN 引腳檢測到起始位前,所有的輸入將被忽略。 地址——接下來的 3 位(A2、A1 和 A0)選擇多路選擇器的現(xiàn)行通道(見表4-3和圖4-1),觸摸屏驅(qū)動和參考源輸入。這里我參考我手里的開發(fā)板原理圖光敏電阻是接在AIN2通道,也就是AUX引腳,所以A1/A2/A3為010。 MODE——模式選擇位,用于設(shè)置 ADC 的分辨率。MODE=0,下一次的轉(zhuǎn)換將是 12 位模式;MODE=1,下一次的轉(zhuǎn)換將是 8 位模式。這里我們選擇12位模式,此位為0。 SER/ ——SER/ 位控制參考源模式,選擇單端模式(SER/ =1)或差分模式(SER/ =0),我們在這里選擇單端模式,此位為1。 PD0 和 和 PD1——低功率模式選擇位,若為11,器件處于供電狀態(tài),若為00,器件在交換之間處于低功率模式。我們選擇PD0/PD1都為0。
綜上所述,最后我們給DIN的值為A4H。 
圖5-2 開發(fā)板XPT2046原理圖
(六)其他外圍元器件的介紹光敏電阻是一種無結(jié)器件 , 它是利用半導(dǎo)體的光致導(dǎo)電特性制成的 , 在受光時(shí)產(chǎn)生空穴和電子( 光生載流子) ,在復(fù)合前就由一電級到達(dá)另一電極 , 有效的參與導(dǎo)電 , 從而使光電導(dǎo)體的電阻率發(fā)生變化。光照強(qiáng)度越強(qiáng) , 電阻越小 如右圖所示, 目前生產(chǎn)的光敏電阻主要是硫化鎘 (cdS) 光敏電阻 ( 占 90 % 以上 ) 。為提高硫化鎘光敏電阻的光靈敏度 , 在 cdS中摻入銅銀等雜質(zhì)。 圖4-1
光敏電阻的應(yīng)用在生活中也非常的廣泛,我們在這里應(yīng)用是給光敏電阻串聯(lián)一個(gè)100k的普通電阻如下圖4-2,我們只需要測量普通電阻兩端的電壓,就可以間接收集到光照強(qiáng)度。再將測得的電壓值通過ADC傳送給單片機(jī)。
圖4-2 光敏電阻接線
我是用到的蜂鳴器是一個(gè)無源蜂鳴器,相比有源蜂鳴器的通電發(fā)聲簡單操作,無源蜂鳴器卻需要給特定的方波信號才能發(fā)聲。但是無源蜂鳴器卻能夠通過給定方波信號不同而發(fā)出不同頻率的聲音。 我的蜂鳴器發(fā)聲程序如下: uint n; for ( n = 0; n < 100; n++) //改變循環(huán)次數(shù)可以改變發(fā)聲時(shí)長 { BEEP=~BEEP; delay(20); //改變此處延時(shí)程序的值,可以改變蜂鳴器音調(diào) }
(七)Protues仿真圖
在protues里面我找不到XPT2046芯片,就沒有畫它的電路。下面附上開發(fā)板的ADC電路圖 
《電子時(shí)鐘》 四、軟件設(shè)計(jì)(一)按鍵操作邏輯
1、LCD顯示區(qū)域劃分 
2、按鍵分布
3、按鍵操作邏輯
(1)、首先,這是正常的時(shí)鐘模式,右下角顯示TIME
(2)、長按設(shè)置鍵可以選擇模式,左下角模式調(diào)整區(qū)clock,按key1 OK鍵進(jìn)入時(shí)鐘調(diào)整模式 
(3)、進(jìn)入時(shí)鐘調(diào)整模式后,繼續(xù)按key1切換要調(diào)整的位,同時(shí)右上角功能顯示區(qū)域顯示字母c,功能調(diào)整區(qū)會顯示需要調(diào)整的位,同時(shí)會閃爍,按加減鍵會進(jìn)行相應(yīng)的加減。 
(4)、調(diào)整完畢后按設(shè)置/return鍵返回,在次長按設(shè)置/return鍵,進(jìn)入鬧鐘調(diào)整界面,功能調(diào)整區(qū)會顯示alarm。

(5)、按切換/ok鍵進(jìn)入鬧鐘調(diào)整模式,右上角功能顯示區(qū)域會顯示字母a,調(diào)整方式與是時(shí)鐘模式相同。 
(6)、鬧鐘設(shè)置完畢后,按設(shè)置/return鍵退出,再次長按進(jìn)入鬧鐘開關(guān)界面,功能調(diào)整區(qū)域顯示onoff,按切換/ok鍵開關(guān)鬧鐘,鬧鐘打開后右上角功能顯示區(qū)域會顯示字母o。再次長按設(shè)置鍵就會退出。
2、設(shè)置掃描函數(shù)
(1)流程圖
3、按鍵掃描函數(shù) (1)程序圖 
本人初學(xué),僅供參考,存在錯(cuò)誤和不足之處,請大家回帖多多指教,切勿照搬,文件下載:
Keil代碼與Proteus仿真下載:
電子時(shí)鐘文件.7z
(2.37 MB, 下載次數(shù): 97)
2022-4-27 22:28 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
|