仿真 代碼 原理圖 PCB實物已設計整理好!各位下載可直接使用
這是本人做的關于51單片機的一個小設計,主要將論壇里的溫度報警器和計算器代碼進行了整合,簡單的說可以當做計算器使用也可以當做溫度報警器使用。PCB也對各個版本進行了優化,原理圖劃分了功能塊方便看不懂的小伙伴,這主要針對一些不會做手工PCB的小伙伴,而且現在立創和捷配的打樣活動也比自己手工做PCB成本低很多,鑒于能白嫖就白嫖的原則,請大家不要錯過。
功能簡單介紹:
一、溫度報警器功能
插電后打開開關(開關可直接短接)初始化完成后LCD1602第一行居中顯示實時溫度,第二行顯示HT:60 LT:2表示默認設置的溫度上限以及下限,若溫度超過上限或者低于下限值,對應led發光以提示用戶。按下k2鍵,可進入溫度報警器的設置模式,此時lcd顯示屏幕上第一行最末尾出現H或者L,表示此時可按K3,K4對對應的HT或者LT的上下限值進行加減來改變報警閾值,并且這三個按鍵按下時蜂鳴器會有響聲提醒。
二、計算器功能
按下K1鍵可切換為計算器模式,此時矩陣鍵盤生效,lcd顯示屏幕清空,進入計算器模式,矩陣鍵盤上PCB絲印字體對應按鍵按下的值。其余不多做解釋,按照正常計算器玩法操作。再按下K1鍵可切換回溫度報警器模式。
代碼篇幅有限,這里不做介紹,上傳文件中可自行查閱。有其他建議聯系我哈。
制作出來的實物圖如下:
實物圖.jpg (4.32 MB, 下載次數: 85)
下載附件
2021-4-3 21:38 上傳
Altium Designer畫的原理圖和PCB圖如下:(51hei附件中可下載工程文件)
正面3D圖.png (324.52 KB, 下載次數: 69)
下載附件
2021-4-3 21:38 上傳
正面3D透視.png (209.89 KB, 下載次數: 91)
下載附件
2021-4-3 21:38 上傳
正面2維圖.png (359.23 KB, 下載次數: 88)
下載附件
2021-4-3 21:38 上傳
原理圖.png (99.2 KB, 下載次數: 82)
下載附件
原理圖
2021-4-3 21:40 上傳
單片機源程序如下:
- /*******************************************************************************
- * 標題: LCD1602簡易計算器 *
- * *
- * 實驗說明:1602簡易計算器,可以實現四位數以內的加減乘除, *
- ********************************************************************************
- * 實驗心得:當內部ram不夠用的時候,可以定義成xdata,使用外部ram,但是有一個問題*
- 就是在用proteus仿真的時候,如果有xdata的代碼,可能仿真會出現點問題,因為peoteus*
- 不支持外部擴展ram *
- ********************************************************************************/
- #include<reg52.h>
- #include"lcd.h"
- #include"math.h"
- #include"temp.h"
- #include"intrins.h"
- //--定義使用的IO口--//
- #define GPIO_KEY P1
- sbit K_set=P3^3;
- sbit K_up=P3^5;
- sbit K_down=P3^6;
- sbit bee_key=P3^7;
- sbit ledL=P2^3;
- sbit ledH=P2^4;
- unsigned char setting_flag=0,up_flag=0,down_flag=0;
- //--定義全局變量--//
- unsigned char code XuJian[16]="01470258=369+-x/";
- long value[16];
- unsigned char Num[8];//此處寫成unsigend char xdata Num[8]時,實物可以用,但是仿真有點問題,因為proteus不支持外部擴展ram.
- unsigned long result;//運算結果
- unsigned int flag=0;//標志位
- unsigned int m;
- unsigned int c=0;
- long First=0;//輸入的第一位數
- long Second=0;//輸入的第二位數
- unsigned int Key;//符號判斷,如果key=12,為+,13,為-,14為×,15為/。
- unsigned char KeyValue=-1;
- //用來存放讀取到的鍵值
- //--聲明全局函數--//
- int KeyScan(void);//鍵值判斷函數
- void Delay10ms(unsigned int c); //誤差 0us
- void RES();//結果運算函數
- //
- //模式切換標致
- unsigned char moshi_flag=0,temp_max=60,temp_min=2,lcd_flag=0;
- unsigned int temp=0;
- uchar code Init1[]=" DB:000 "; //初始化時1行顯示
- uchar code Init2[]=" HT:000 LT:000 "; //初始化時2行顯示
- void Init1602_temp()
- {
- uchar i=0;
- LcdWriteCom(0x38);//屏幕初始化
- LcdWriteCom(0x0c);//打開顯示 無光標 無光標閃爍
- LcdWriteCom(0x06);//當讀或寫一個字符是指針后一一位
- LcdWriteCom(0x01);//清屏
- LcdWriteCom(0x80);//設置位置
- for(i=0;i<16;i++)
- {
- LcdWriteData(Init1[i]); //1行初始化顯示
- }
- LcdWriteCom(0x80+0x40);
- for(i=0;i<16;i++)
- {
- LcdWriteData(Init2[i]);//2行初始化顯示
- }
- }
- //顯示實時溫度
- void display_temp(unsigned int temp)
- {
- unsigned char a,b,c;
-
- a=temp/1000%10;
- b=temp/100%10;
- c=temp/10%10;
-
- LcdWriteCom(0x80+7);
- LcdWriteData(a+0x30);
- LcdWriteData(b+0x30);
- LcdWriteData('.');
- LcdWriteData(c+0x30);
- }
- //顯示溫度上下限
- void display_temp_M(unsigned char temp_max,unsigned char temp_min)
- {
- unsigned char a,b,c;
- a=temp_max/100;
- b=temp_max/10%10;
- c=temp_max%10;
- LcdWriteCom(0x80+0x40+5);
- LcdWriteData(a+0x30);
- LcdWriteData(b+0x30);
- LcdWriteData(c+0x30);
- a=temp_min/100;
- b=temp_min/10%10;
- c=temp_min%10;
- LcdWriteCom(0x80+0x40+12);
- LcdWriteData(a+0x30);
- LcdWriteData(b+0x30);
- LcdWriteData(c+0x30);
- }
- void Delay500us() //@11.0592MHz
- {
- unsigned char i, j;
- _nop_();
- _nop_();
- i = 6;
- j = 93;
- do
- {
- while (--j);
- } while (--i);
- }
- void bee_anjian(unsigned int c )
- {
- unsigned char a, b;
- bee_key=0;
- //--c已經在傳遞過來的時候已經賦值了,所以在for語句第一句就不用賦值了--//
- for (;c>0;c--)
- {
- bee_key=!bee_key;
- Delay500us();
-
- }
- bee_key=0;
- }
- void temp_scan()//按鍵掃描
- { unsigned char dis_play_flag=0;
- if(K_set==0) //判斷設置是否按下
- {
- Delay10ms(1);
- if(K_set==0)
- { bee_key=0;
- setting_flag=setting_flag+1;
- dis_play_flag=1;
- if(setting_flag>2)
- {setting_flag=0;}
- // bee_anjian(100);
- //bee_anjian(100);
- Delay10ms(50);
-
- }
- }
- if(dis_play_flag)
- {
-
- if(setting_flag==1)
- {
- LcdWriteCom(0x80+15);
- LcdWriteData('H');
- }
- else if(setting_flag==2)
- {
- LcdWriteCom(0x80+15);
- LcdWriteData('L');
- }
- else
- {
- LcdWriteCom(0x80+15);
- LcdWriteData(' ');
- }
- dis_play_flag=0;
-
- }
- if(setting_flag) //設置按下
- {
- if(K_up==0)
- {
- Delay10ms(1);
- if(K_up==0)
- {
- bee_key=0;
- up_flag=1;
- }
- }
- }
- if(setting_flag)
- {
- if(K_down==0)
- {
- Delay10ms(1);
- if(K_down==0)
- {
- bee_key=0;
- down_flag=1;
- }
- }
- }
- if(up_flag==1)
- {
- if(setting_flag==1)
- {
- temp_max=temp_max+1;
- if(temp_max>99)
- {temp_max=99;}
- display_temp_M(temp_max,temp_min);
-
- // bee_anjian(50);
- //bee_anjian(100);
- Delay10ms(50);
- up_flag=0;
- }
- else if(setting_flag==2)
- {
- temp_min=temp_min+1;
- if(temp_min>99)
- {temp_min=99;}
- display_temp_M(temp_max,temp_min);
- // bee_anjian(50);
- //bee_anjian(100);
- Delay10ms(50);
- up_flag=0;
- }
- }
- if(down_flag==1)
- {
- if(setting_flag==1)
- {
- temp_max=temp_max-1;
- if(temp_max<1)
- {temp_max=1;}
- display_temp_M(temp_max,temp_min);
- Delay10ms(50);
- // bee_anjian(100);
- down_flag=0;
- }
- else if(setting_flag==2)
- {
- temp_min=temp_min-1;
- if(temp_min<1)
- {temp_min=1;}
- display_temp_M(temp_max,temp_min);
- Delay10ms(50);
- //bee_anjian(100);
- down_flag=0;
- }
- }
- bee_key=1;
- }
- //中斷函數初始化
- void Init_INT()
- {
- IT0 = 1; //設置為下降沿觸發
- EX0 = 1; //外部中斷0中斷允許位
- EA = 1;
- }
- void EX0_ISR(void) interrupt 0 //中斷服務函數的書寫格式
- {
-
- moshi_flag=!moshi_flag;
- lcd_flag=moshi_flag+1;
-
-
- }
- /*******************************************************************************
- * 函 數 名 : main
- * 函數功能 : 主函數
- * 輸 入 : 無
- * 輸 出 : 無
- *******************************************************************************/
- void main(void)
- {
- LcdInit();
- // for(i=0;i<7;i++)
- // {
- // LcdWriteData(TiShi[i]);
- // }
- Init_INT();//開啟外部中斷
- Init1602_temp();
- bee_anjian();
- while(1)
- {
- if(lcd_flag==1)
- {
- Init1602_temp();
- lcd_flag=0;
- }
- else if(lcd_flag==2)
- {
- LcdInit();
- lcd_flag=0;
- }
- if(moshi_flag==1)
- {
- KeyValue=KeyScan();
- switch(KeyValue)
- {
- case(0):
- LcdWriteCom(0x01);
- KeyValue=-1;
- First=0;
- Second=0;
- c=0;
- break;
- case(1):
- if(flag==0)//flag為0時,正常計算
- {
- LcdWriteData(XuJian[1]);
- KeyValue=-1;
- if(c==0)
- First=10*First+1;
- else if(c==1)
- Second=10*Second+1;
- }
- else if(flag==1)//flag為1時,可以在第一次運算好后,繼續輸入數字,開始第二次計算
- {
- LcdWriteCom(0x01);
- LcdWriteData(XuJian[1]);
- KeyValue=-1;
- First=0;
- Second=0;
- c=0;
- flag=0;
-
- ................限于篇幅代碼請下載附件................
- do
- {
- value[i]=result%10;
- result/=10;
- i++;
- }while((result/10)!=0);
- value[i]=result;
- m=i;
- for(j=0;j<=i;j++) //for循環如果是for(j=i;j>=0;j++)就會出現不同的結果,很奇怪
- {
- Num[j]=value[j]+'0';
- }
- for(i=0;i<=m;i++)//這里的for循環也是和上面一樣的結果,改成for(i=m;i>=0;i--)就會出現奇怪的結果,有興趣的可以試試。
- {
- LcdWriteData(Num[m-i]);
- }
-
- }
- /*******************************************************************************
- * 函 數 名 : KeyScan
- * 函數功能 : 檢測有按鍵按下并讀取鍵值
- * 輸 入 : 無
- * 輸 出 : 無
- *******************************************************************************/
- int KeyScan(void) //測試行(row)的時候就是線是豎著的的那一列為1,測試列(col)的時候就是線是橫著的那幾行為1
- {
- char a = 0;
- GPIO_KEY=0x0f;
- if(GPIO_KEY!=0x0f)//讀取按鍵是否按下
- {
- Delay10ms(1);//延時10ms進行消抖
- if(GPIO_KEY!=0x0f)//再次檢測鍵盤是否按下
- {
-
- //測試列
- GPIO_KEY=0X0F;
- switch(GPIO_KEY)
- {
- case(0X07): KeyValue=0;break;
- case(0X0b): KeyValue=4;break;
- case(0X0d): KeyValue=8;break;
- case(0X0e): KeyValue=12;break;
- }
- //測試行
- GPIO_KEY=0XF0;
- switch(GPIO_KEY)
- {
- case(0X70): KeyValue=KeyValue+3;break;
- case(0Xb0): KeyValue=KeyValue+2;break;
- case(0Xd0): KeyValue=KeyValue+1;break;
- case(0Xe0): KeyValue=KeyValue;break;
- }
- while((a<50) && (GPIO_KEY!=0xf0)) //檢測按鍵松手檢測
- {
- Delay10ms(1);
- a++;
- }
- }
- }
- return KeyValue;
- }
- /*******************************************************************************
- * 函 數 名 : Delay10ms
- * 函數功能 : 延時函數,延時10ms
- * 輸 入 : 無
- * 輸 出 : 無
- *******************************************************************************/
- void Delay10ms(unsigned int c) //誤差 0us
- {
- unsigned char a, b;
- //--c已經在傳遞過來的時候已經賦值了,所以在for語句第一句就不用賦值了--//
- for (;c>0;c--)
- {
- for (b=38;b>0;b--)
- {
- for (a=130;a>0;a--);
- }
- }
- }
復制代碼
51hei.png (19.54 KB, 下載次數: 80)
下載附件
2021-4-4 04:16 上傳
所有資料51hei提供下載:
溫度報警加簡易計算器資料.7z
(3.52 MB, 下載次數: 79)
2021-4-4 04:21 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|