微型貼片單片機STC15F104E單片機做的LM75A溫控制器,帶1602液晶顯示器,有溫度設置。用最小的單片機做最多的功能
制作出來的實物圖如下:
20181124_022450.jpg (295.33 KB, 下載次數: 54)
下載附件
2018-11-24 02:59 上傳
單片機源碼:
- #include <reg51.h>
- #include <intrins.h>
- #define uchar unsigned char
- #define uint unsigned int
- sbit sda=P3^1;
- sbit scl=P3^0;
- void delay() //@11.0592MHz stc12(100us)
- {
- unsigned char i, j;
- i = 2;
- j = 15;
- do
- {
- while (--j);
- } while (--i);
- }
- void delay1(uint x)//@11.0592MHz stc12(1ms)
- {
- unsigned char i, j;
- _nop_();
- i = 11;
- j = 190;
- do
- {
- while (--j);
- } while (--i);
- }
- /* ***************************************************** */
- // 起別名定義
- /* ***************************************************** */
- typedef unsigned char uChar8;
- typedef unsigned int uInt16;
- typedef enum{FALSE,TRUE} BOOL;
- /* ***************************************************** */
- // 宏定義
- /* ***************************************************** */
- #define LM75ADevIDAddr 0x90
- #define IIC_WRITE 0x00
- #define IIC_READ 0x01
- /* ***************************************************** */
- // 位定義
- /* ***************************************************** */
- sbit SCL = P3^2;//綠色線
- sbit SDA = P3^3;//白色線
- long int LM75WD;
- long int SET=28000; //28.000度
- //sbit led1=P3^0;//溫度燈報警
- //sbit led2=P3^1;//壓力燈報警
- sbit OUT=P3^5;//控制器輸出
- sbit IN=P3^4;//開關輸入設置溫度
- /* ***************************************************** */
- // 全局變量定義
- /* ***************************************************** */
- bit p_bH0L_Flag; // 溫度"0"上、下標志位
- float p_fLM75ATemp; // 溫度值
- /* ***************************************************** */
- // 函數名稱:Delay5US()
- // 函數功能:微秒延時
- // 入口參數:延時微秒數(ValUS)
- // 出口參數:無
- /* ***************************************************** */
- void Delay5US(void)
- {
- unsigned char i;
- _nop_();
- i = 11;
- while (--i);
- }
- /* ***************************************************** */
- // 函數名稱:DelayMS()
- // 函數功能:毫秒延時
- // 入口參數:延時毫秒數(ValMS)
- // 出口參數:無
- /* ***************************************************** */
- void DelayMS(uInt16 ValMS)
- {
- unsigned char i, j;
- _nop_();
- _nop_();
- _nop_();
- i = 11;
- j = 190;
- do
- {
- while (--j);
- } while (--i);
- }
- /* ***************************************************** */
- // 函數名稱:IIC_Start()
- // 函數功能:IIC起動
- // 入口參數:無
- // 出口參數:無
- /* ***************************************************** */
- void IIC_Start(void)
- {
- SDA = 1;
- Delay5US();
- SCL = 1;
- Delay5US();
- SDA = 0;
- Delay5US();
- }
- /* ***************************************************** */
- // 函數名稱:IIC_Stop()
- // 函數功能:IIC停止
- // 入口參數:無
- // 出口參數:無
- /* ***************************************************** */
- void IIC_Stop(void)
- {
- SDA = 0;
- Delay5US();
- SCL = 1;
- Delay5US();
- SDA =1;
- }
- /* ***************************************************** */
- // 函數名稱:IIC_Ack()
- // 函數功能:IIC應答
- // 入口參數:無
- // 出口參數:無
- /* ***************************************************** */
- void IIC_Ack(void)
- {
- SCL = 0; // 為產生脈沖準備
- SDA = 0; // 產生應答信號
- Delay5US(); // 延時你懂得
- SCL = 1;Delay5US();
- SCL = 0;Delay5US(); // 產生高脈沖
- SDA = 1; // 釋放總線
- }
- /* ***************************************************** */
- // 函數名稱:IIC_RdAck()
- // 函數功能:讀IIC應答
- // 入口參數:無
- // 出口參數:是否應答真值
- /* ***************************************************** */
- BOOL IIC_RdAck(void)
- {
- BOOL AckFlag;
- uChar8 uiVal = 0;
- SCL = 0;Delay5US();
- SDA = 1;
- SCL = 1;Delay5US();
- while((1 == SDA) && (uiVal < 255))
- {
- uiVal ++;
- AckFlag = SDA;
- }
- SCL = 0;
- return AckFlag; // 應答返回:0;不應答返回:1
- }
- /* ***************************************************** */
- // 函數名稱:IIC_Nack()
- // 函數功能:IIC不應答
- // 入口參數:無
- // 出口參數:無
- /* ***************************************************** */
- void IIC_Nack(void)
- {
- SDA = 1;
- SCL = 0;Delay5US();
- SCL = 1;Delay5US();
- SCL = 0;
- }
- /* ***************************************************** */
- // 函數名稱:OutputOneByte()
- // 函數功能:從IIC器件中讀出一個字節
- // 入口參數:無
- // 出口參數:讀出的一個字節(uByteVal)
- /* ***************************************************** */
- uChar8 OutputOneByte(void)
- {
- uChar8 uByteVal = 0;
- uChar8 iCount;
- SDA = 1;
- for (iCount = 0;iCount < 8;iCount++)
- {
- SCL = 0;
- Delay5US();
- SCL = 1;
- Delay5US();
- uByteVal <<= 1;
- if(SDA)
- uByteVal |= 0x01;
- }
- SCL = 0;
- return(uByteVal);
- }
- /* ***************************************************** */
- // 函數名稱:InputOneByte()
- // 函數功能:向IIC器件寫入一個字節
- // 入口參數:待寫入的一個字節(uByteVal)
- // 出口參數:無
- /* ***************************************************** */
- void InputOneByte(uChar8 uByteVal)
- {
- uChar8 iCount;
- for(iCount = 0;iCount < 8;iCount++)
- {
- SCL = 0;
- Delay5US();
- SDA = (uByteVal & 0x80) >> 7;
- Delay5US();
- SCL = 1;
- Delay5US();
- uByteVal <<= 1;
- }
- SCL = 0;
- }
- /* ***************************************************** */
- // 函數名稱:IIC_WrDevAddAndDatAdd()
- // 函數功能:向IIC器件寫入器件和數據地址
- // 入口參數:器件地址(uDevAdd),數據地址(uDatAdd)
- // 出口參數:寫入是否成功真值
- /* ***************************************************** */
- BOOL IIC_WrDevAddAndDatAdd(uChar8 uDevAdd,uChar8 uDatAdd)
- {
- IIC_Start(); // 發送開始信號
- InputOneByte(uDevAdd); // 輸入器件地址
- IIC_RdAck(); // 讀應答信號
- InputOneByte(uDatAdd); // 輸入數據地址
- IIC_RdAck(); // 讀應答信號
- return TRUE;
- }
- /* ***************************************************** */
- // 函數名稱:IIC_RdDatFromAdd()
- // 函數功能:向IIC器件讀數據
- // 入口參數:器件ID(uDevID)、數據存儲地址(uStaAddVal)
- // 待存數據(*p)、連續存儲數據的個數(uiLenVal)
- // 出口參數:無
- /* ***************************************************** */
- void IIC_RdDatFromAdd(uChar8 uDevID, uChar8 uStaAddVal, uChar8 *p, uChar8 uiLenVal)
- {
- uChar8 iCount;
- IIC_WrDevAddAndDatAdd(uDevID | IIC_WRITE,uStaAddVal);
- IIC_Start();
- InputOneByte(uDevID | IIC_READ);
- // IIC_READ 為寫命令后綴符
- IIC_RdAck();
- for(iCount = 0;iCount < uiLenVal;iCount++)
- {
- *p++ = OutputOneByte();
- if(iCount != (uiLenVal - 1))
- IIC_Ack();
- }
- IIC_Nack();
- IIC_Stop();
- }
- /* ***************************************************** */
- // 函數名稱:LM75A_ReadReg()
- // 函數功能:讀LM75A任意寄存器值
- // 入口參數:寄存器地址(addr),uLenVal,讀出字節的長度
- // 出口參數:寄存器內容(*val)
- /* ***************************************************** */
- void LM75A_ReadReg(uChar8 addr, uChar8 *val, uChar8 uLenVal)
- {
- IIC_RdDatFromAdd(LM75ADevIDAddr, addr, val, uLenVal);
- }
- /* ***************************************************** */
- // 函數名稱:LM75A_TempConv()
- // 函數功能:溫度轉換
- // 入口參數:無
- // 出口參數:無
- /* ***************************************************** */
- void LM75A_TempConv(void)
- {
- uChar8 TempML[2]={0}; // 臨時數值,用于存放Temp的高低字節
- uInt16 uiTemp; // 用于存放Temp的11位字節數據
- LM75A_ReadReg(0x00,TempML,2); // 讀出溫度,并存于數組TempHL中
- uiTemp = (uInt16)TempML[0]; // 將高字節存入變量uiTemp中
- uiTemp = (uiTemp << 8 | TempML[1]) >> 5; // 接著并入后3位,最后右移5位就是11位補碼數(8+3共11位)
- /* ***** 首先判斷溫度是“0上”還是是“0下” ***** */
- if(!(TempML[0] & 0x80)) // 最高位為“0”則為“0上”
- {
- p_bH0L_Flag = 0;
- p_fLM75ATemp = uiTemp * 0.125;
- }
- else // 這時為“0下”(p_fLM75ATemp)℃
- {
- p_bH0L_Flag = 1;
- p_fLM75ATemp = (0x800 - uiTemp) * 0.125;// 由于計算機中負數是以補碼形式存的,所以有這樣的算法。
- }
- }
- /********************************1602**************************************/
- void start() //開始信號
- {
- sda=1;
- delay();
- scl=1;
- delay();
- sda=0;
- delay();
- }
- void stop() //停止
- {
- sda=0;
- delay();
- scl=1;
- delay();
- sda=1;
- delay();
- }
- void respons() //應答
- {
- uchar i;
- scl=1;
- delay();
- while((sda==1)&&(i<250))i++;
- scl=0;
- delay();
- }
- void init()
- {
- sda=1;
- delay();
- scl=1;
- delay();
- }
- void write_byte(uchar date)
- {
- uchar i,temp;
- temp=date;
- for(i=0;i<8;i++)
- {
- temp=temp<<1;
- scl=0;
- delay();
- sda=CY;
- delay();
- scl=1;
- delay();
- }
- scl=0;
- delay();
- sda=1;
- delay();
- }
- void write_add(uchar date1)
- {
- start();
- write_byte(0x4e); //8574A 地址+寫入 (8574 地址+寫入0x4e)//0x27+0x27=0x4e//全部空0x3f+0x3f=0x7e
- respons();
- write_byte(date1);
- respons();
- stop();
- }
- void write_com(uchar com) //寫命令函數
- { uchar com1,com2;
- com1=com|0x0f;
- write_add(com1&0xfc);
- delay1(2);
- write_add(com1&0xf8);
- com2=com<<4;
- com2=com2|0x0f;
- write_add(com2&0xfc);
- delay1(2);
- write_add(com2&0xf8);
- }
- void write_date(uchar date) //寫數據函數
- {
- uchar date1,date2;
- date1=date|0x0f;
- write_add(date1&0xfd);
- delay1(2);
- write_add(date1&0xf9);
- date2=date<<4;
- date2=date2|0x0f;
- write_add(date2&0xfd);
- delay1(2);
- write_add(date2&0xf9);
- }
- void write_zfc(uchar *p)//定義一個帶指針的函數?(字符串)
- {
- while(*p!=0)//不能用";"
- write_date(*p++);
- }
- void init_lcd() //初始化函數
- {
- write_add(0x08); //默認開始狀態為關使能端,見時序圖 選擇狀態為 寫
- write_com(0x0f);
- write_com(0x28); //顯示模式設置 0x28中高位2,設置4線。
- write_add(0x0c);
- write_add(0x08); //使能4線
- write_com(0x28); //顯示模式設置,為0x28。
- write_com(0x01); //顯示清屏,將上次的內容清除,默認為0x01.
- write_com(0x0c); //顯示功能設置0x0f為開顯示,顯示光標,光標閃爍;0x0c為開顯示,不顯光標,光標不閃
- write_com(0x06); //設置光標狀態默認0x06,為讀一個字符光標加1.
- }
- void display(long temp) //顯示函數
- {
- uchar dt1,dt2,dt3,dt4,dt5,dt6,dt7,dt8;
- //temp=12345678;
- dt1 = temp%10;//1位
- dt2 = temp%100/10;//2位
- dt3 = temp%1000/100;//3位
- dt4 = temp%10000/1000;//4位
- dt5 = temp%100000/10000;//5位
- dt6 = temp%1000000/100000;//6位
- dt7 = temp%10000000/1000000;//7位
- dt8 = temp/10000000;//8位 最高位
- write_com(0xC0); //第1行
- write_zfc("WD:");
- //write_date(dt8+0x30);
- //write_date(dt7+0x30);
- //write_date(dt6+0x30);
- write_date(dt5+0x30);
- write_date(dt4+0x30);
- write_zfc(".");
- write_date(dt3+0x30);
- write_date(dt2+0x30);
- //write_date(dt1+0x30);
- write_zfc("C");
-
- }
- void display2(long temp) //顯示函數
- {
- uchar dt1,dt2,dt3,dt4,dt5,dt6,dt7,dt8;
- //temp=12345678;
- dt1 = temp%10;//1位
- dt2 = temp%100/10;//2位
- dt3 = temp%1000/100;//3位
- dt4 = temp%10000/1000;//4位
- dt5 = temp%100000/10000;//5位
- dt6 = temp%1000000/100000;//6位
- dt7 = temp%10000000/1000000;//7位
- dt8 = temp/10000000;//8位 最高位
- write_com(0xc0+10); //第1行
- write_zfc("SET:");
- //write_date(dt8+0x30);
- //write_date(dt7+0x30);
- //write_date(dt6+0x30);
- write_date(dt5+0x30);
- write_date(dt4+0x30);
- //rite_zfc(".");
- //write_date(dt3+0x30);
- //write_date(dt2+0x30);
- //write_date(dt1+0x30);
- write_zfc("C");
-
- }
- void main()
- {
- init_lcd();
- OUT=1;//啟動時關一下
-
- while(1)
- {
-
-
- LM75A_TempConv();//讀取溫度LM75A
- DelayMS(200);
- LM75WD = p_fLM75ATemp * 1000;// 將溫度全部轉換成整數,以便數碼管顯示
- init(); //通訊1602
- display(LM75WD); // 顯示1602
- display2(SET); // 顯示1602
- if(IN==0)//設置溫度
- {
- SET=SET+1000;
- if(SET>99999)//設置溫度
- SET=28000;
- }
-
-
- if(LM75WD>=SET)// 溫度30
- {
- OUT=0;
- write_com(0x80); //第1行
- write_zfc("OUT:OFF");//220V電源關閉
-
- }
- else{
- if(LM75WD<=SET-1000)// 溫度回落1.000度后再執行,防閃爍
- {
- OUT=1;
- write_com(0x80); //第1行
- write_zfc("OUT: ON");//220V電源輸出
- }
- else
- {
- OUT=0;
- write_com(0x80); //第1行
- write_zfc("OUT:OFF");//220V電源關閉
- }
- }
-
-
- }
- }
復制代碼
全部資料51hei下載地址:
1602顯串STC15F104E LM75A溫度OK3(0x4e).zip
(67.22 KB, 下載次數: 53)
2018-11-24 03:00 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|