因T友要求,分享下使用STCF104E單片機加1637數碼管IIC接囗,只用2根線,加LM75A溫控頭IIC接囗,制作的溫度控制器。實測很穩定,只用一個按鍵完成溫度設置,42-99度。正常工作時實測溫度和設置溫度交替顯示,成本很低。不到10元。現上源代碼
制作出來的實物圖如下:
20181205_221245.jpg (317.88 KB, 下載次數: 54)
下載附件
2018-12-5 22:38 上傳
20181205_221029.jpg (328.6 KB, 下載次數: 41)
下載附件
2018-12-5 22:38 上傳
20181205_221220.jpg (292.4 KB, 下載次數: 55)
下載附件
2018-12-5 22:39 上傳
單片機源程序如下:
- #include <stc15.h>
- #include <INTRINS.H>
- #include <stdio.h>
- #include <intrins.h>
- #define uchar unsigned char
- #define uint unsigned int
- /* ***************************************************** */
- // 起別名定義
- /* ***************************************************** */
- 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;//定義一個溫度長整型變量
- sbit out = P3^5;//輸出繼電器
- sbit k = P3^4;//調節溫度
- int set;//設置溫度
- /* ***************************************************** */
- // 全局變量定義
- /* ***************************************************** */
- 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;// 由于計算機中負數是以補碼形式存的,所以有這樣的算法。
- }
- }
- sbit SCL1=P3^0; //CLK
- sbit SDA1=P3^1; //DIO
- unsigned char code xsbcdbuf[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77};
- void Delay1000ms() //@11.0592MHz
- {
- unsigned char i, j, k;
- _nop_();
- _nop_();
- i = 43;
- j = 6;
- k = 203;
- do
- {
- do
- {
- while (--k);
- } while (--j);
- } while (--i);
- }
- void IIC_delay(void)
- {
- unsigned char i;
- for(i=0;i<20;i++) _nop_();
- }
- void start_IIC(void)// 啟動IIC
- {
- SCL1=1; //給芯片發送開始信號
- SDA1=1;
- IIC_delay();
- SDA1=0;
- IIC_delay();
- SCL1=0; //開始信號傳送完
- IIC_delay();
- }
- void stop_IIC(void) //停止IIC
- {
- SCL1=0;
- IIC_delay();
- SDA1=0;
- IIC_delay();
- SCL1=1;
- IIC_delay();
- SDA1=1;
- }
- void ack_IIC()
- {
- SCL1=0;
- _nop_();_nop_();_nop_();
- while(SDA1);
- SCL1=1;
- _nop_();_nop_();_nop_();
- SCL1=0;
- }
- void WriteByte(unsigned char WriteData) //寫一個字節數據
- {
- unsigned char i;
- for(i=0;i<8;i++)//開始傳送8位數據,每循環一次傳送一位數據
- {
- SCL1=0;
- IIC_delay();
- WriteData=WriteData>>1;
- SDA1=CY;
- IIC_delay();
- SCL1=1;
- IIC_delay();
- }
- //8位數據傳送完
- ack_IIC(); //判斷芯片發過來的ACK應答信號
- }
- void write_LEDSROM(unsigned char addr,unsigned char WData) //寫一字節數據到LEDSROM
- {
- start_IIC(); //調用開始信號
- WriteByte(addr); //寫起始地址命令(0C0H),地址00H單元。
- WriteByte(WData);//給顯示寄存器寫顯示數據,值可根據實參改變
- stop_IIC(); //調用結束信號,一個字節命令發送完畢,可以發送下一個命令
- }
-
-
- void dsplay(int temp) //顯示
- {
-
- SDA1=1;
- SCL1=1;
- start_IIC(); //調用開始信號
- WriteByte(0x40);//寫命令40H(數據設置)
- stop_IIC(); //調用結束信號,一個字節命令發送完畢,可以發送下一個命令
-
-
- write_LEDSROM(0xC0,xsbcdbuf[temp/1000]); //第一個數碼管
- // write_LEDSROM(0xC1,xsbcdbuf[temp%1000/100]); //第二個數碼管,0x80打開DP小數點
- write_LEDSROM(0xC1,xsbcdbuf[temp%1000/100]|0x80); //第二個數碼管,0x80打開DP小數點
- write_LEDSROM(0xC2,xsbcdbuf[temp%100/10]); //第三個數碼管
- //write_LEDSROM(0xC3,xsbcdbuf[temp%10]);//第四個數碼管
-
- write_LEDSROM(0xC3,0x39);//第四個數碼管
-
-
-
-
-
- IIC_delay();
- start_IIC(); //調用開始信號
- WriteByte(0x8a); //送開屏命令,(8BH),亮度可以根據低三位調節。//顯示亮度
- stop_IIC(); //調用結束信號,一個字節命令發送完畢,可以發送下一個命令
- }
- void dsplay2(int temp) //顯示
- {
-
- SDA1=1;
- SCL1=1;
- start_IIC(); //調用開始信號
- WriteByte(0x40);//寫命令40H(數據設置)
- stop_IIC(); //調用結束信號,一個字節命令發送完畢,可以發送下一個命令
-
-
- write_LEDSROM(0xC0,xsbcdbuf[temp/1000]); //第一個數碼管
- write_LEDSROM(0xC1,xsbcdbuf[temp%1000/100]); //第二個數碼管,0x80打開DP小數點
- // write_LEDSROM(0xC1,xsbcdbuf[temp%1000/100]|0x80); //第二個數碼管,0x80打開DP小數點
- // write_LEDSROM(0xC2,xsbcdbuf[temp%100/10]); //第三個數碼管
- //write_LEDSROM(0xC3,xsbcdbuf[temp%10]);//第四個數碼管
-
- //write_LEDSROM(0xC3,0x39);//第四個數碼管
-
- write_LEDSROM(0xC3,0x00);//第4個數碼管//關閉
- write_LEDSROM(0xC2,0x00);//第3個數碼管
-
-
- IIC_delay();
- start_IIC(); //調用開始信號
- WriteByte(0x8a); //送開屏命令,(8BH),亮度可以根據低三位調節。//顯示亮度
- stop_IIC(); //調用結束信號,一個字節命令發送完畢,可以發送下一個命令
- }
- /* ***************************************************** */
- // 函數名稱:main()
- // 函數功能:讀取LN75A溫度值,數碼管顯示并串口打印
- // 入口參數:無
- // 出口參數:無
- /* ***************************************************** */
- void main()
- {
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
所有資料51hei提供下載:
1637數顯STC15F104E LM75A溫度OK2.zip
(50.93 KB, 下載次數: 65)
2018-12-5 22:39 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|