1、系統(tǒng)工作原理 TC72溫度數(shù)字傳感器能夠讀取從-55℃至+125℃范圍內(nèi)的溫度,可用于連續(xù)溫度轉(zhuǎn)換模式或單次轉(zhuǎn)換模式。連續(xù)溫度轉(zhuǎn)換模式每隔約150ms測量溫度并將溫度存儲在溫度寄存器中。相反,單次轉(zhuǎn)換模式只進(jìn)行單次溫度測量,然后轉(zhuǎn)換到節(jié)能的關(guān)斷模式。該傳感器具有的串行接口能夠與主控制器或其它外設(shè)通信。TC72接口兼容SPI協(xié)議。TC72不需要額外的外部元器件。 本系統(tǒng)以MCS-51系列單片機(jī)為核心器件,組成一個溫度傳感器,采用數(shù)字溫度傳感器TC72為檢測器件,進(jìn)行單點(diǎn)溫度檢測,檢測精度為±0.5攝氏度。溫度顯示采用LCD1602顯示,兩位整數(shù),一位小數(shù)。 2、系統(tǒng)硬件原理圖 圖1.系統(tǒng)硬件原理圖
3、程序流程圖 采用AT89C51單片機(jī)作為控制核心對溫度傳感器TC72控制,讀取溫度信號并進(jìn)行計算處理,并送到液晶顯示器LCD1602顯示。 按照系統(tǒng)設(shè)計功能的要求,確定系統(tǒng)由3個模塊組成:主控制器、測溫電路和顯示電路。程序設(shè)計流程圖如下:
圖2.程序流程圖 4、程序清單 系統(tǒng)程序主要包括主程序、讀出溫度子程序、溫度轉(zhuǎn)換子程序、計算溫度子程序、顯示程序、延時程序等等。主程序主要功能是完成TC72的初始化工作,并進(jìn)行讀溫度,將溫度轉(zhuǎn)化成為字符型數(shù)據(jù)并在顯示器上顯示傳感器所測得的實(shí)際溫度。讀出溫度子程序的主要功能是讀出RAM中的9字節(jié),在讀出時需要進(jìn)行CRC校驗(yàn),校驗(yàn)有錯時不進(jìn)行溫度數(shù)據(jù)的改寫。
5、Proteus仿真調(diào)試結(jié)果及分析
PROTEUS 是單片機(jī)課堂教學(xué)的先進(jìn)助手。PROTEUS不僅可以將許多單片機(jī)實(shí)例功能形象化,也可將許多單片機(jī)實(shí)例運(yùn)行過程形象化。前者可在相當(dāng)程度上得到實(shí)物演示實(shí)驗(yàn)的效果,后者則是實(shí)物演示實(shí)驗(yàn)難以達(dá)到的效果。它的元器件、連接線路等卻和傳統(tǒng)的單片機(jī)實(shí)驗(yàn)硬件高度對應(yīng)。這在相當(dāng)程度上替代了傳統(tǒng)的單片機(jī)實(shí)驗(yàn)教學(xué)的功能,例:元器件選擇、電路連接、電路檢測、電路修改、軟件調(diào)試、運(yùn)行結(jié)果等。 在PROTEUS繪制好原理圖后,調(diào)入已編譯好的目標(biāo)代碼文件:*.HEX,可以在PROTEUS的原理圖中看到模擬的實(shí)物運(yùn)行狀態(tài)和過程。 SPI接口TC72溫度傳感器應(yīng)用測試課題仿真調(diào)試結(jié)果如下: 第一步:編寫C語言程序,編譯成功0 error;0 warning;并生成HEX文件; 第二步:繪制仿真圖,檢查無誤,導(dǎo)入HEX文件,運(yùn)行結(jié)果:LCD亮但不顯示TC72溫度傳感器溫度; 第三步:檢查源程序及仿真圖,無法發(fā)現(xiàn)錯誤; 第四步:咨詢老師,經(jīng)檢查缺少LCD1602液晶顯示屏控制與顯示程序; 第五步:修改程序即在已建工程中新建并編寫LCD1602液晶顯示屏控制與顯示程序,編譯成功,生成HEX文件,導(dǎo)入Proteus仿真圖運(yùn)行成功 第六步:送老師檢查通過。 圖3.仿真結(jié)果圖 元件清單 - //-----------------------------------------------------------------
- // 名稱: SPI接口溫度傳感器TC72應(yīng)用測試
- //-----------------------------------------------------------------
- // 說明: 本例運(yùn)行時,單片機(jī)將持續(xù)從TC72傳感器讀取溫度數(shù)據(jù)并轉(zhuǎn)換為
- // 浮點(diǎn)型字符串送LCD顯示(內(nèi)置SPI接口需要在實(shí)物電路測試)
- //
- //-----------------------------------------------------------------
- #include <REG51.H>
- #include <intrins.h>
- #include <stdio.h>
- #include <math.h>
- #define INT8U unsigned char
- #define INT16U unsigned int
- //SPI使能與禁用(注意TC72是高電平使能,低電平禁用)
- #define SPI_EN() P1 |= (1<<4)
- #define SPI_DI() P1 &= ~(1<<4)
- //TC72寄存器地址定義
- #define TC72_CTRL 0x80 //控制寄存器
- #define TC72_TEMP_LSB 0x01 //溫度低字節(jié)
- #define TC72_TEMP_MSB 0x02 //溫度高字節(jié)
- #define TC72_MANU_ID 0x03 //制造商ID
- //SPI接口引腳定義(模擬方式)
- sbit SCK = P3^4; //串行時鐘
- sbit CE = P3^5; //片選
- sbit SDI = P3^6; //串行數(shù)據(jù)輸入
- sbit SDO = P3^7; //串行數(shù)據(jù)輸出
- //內(nèi)置SPI寄存器及寄存器位定義
- //SPCON C3h SPI Control SPR2 SPEN SSDIS MSTR CPOL CPHA SPR1 SPR0
- //SPSTA C4h SPI Status SPIF WCOL SSERR MODF - - - -
- //SPDAT C5h SPI Data SPD7 SPD6 SPD5 SPD4 SPD3 SPD2 SPD1 SPD0
- sfr SPCON = 0xC3;
- sfr SPSTA = 0xC4;
- sfr SPDAT = 0xC5;
- extern void Initialize_LCD();
- extern void LCD_ShowString(INT8U r, INT8U c,INT8U *str);
- extern void delay_ms(INT16U x);
- INT8U T[2]; //兩字節(jié)原始溫度數(shù)據(jù)
- float TempX = 0.0; //浮點(diǎn)溫度值
- //-----------------------------------------------------------------
- // SPI主機(jī)初始化
- //-----------------------------------------------------------------
- void SPI_MasterInit()
- {
- SPCON=0xD0;
- SPSTA=0xC0;
- }
-
- //-----------------------------------------------------------------
- // SPI數(shù)據(jù)傳輸
- //-----------------------------------------------------------------
- INT8U SPI_SendData(INT8U dat)
-
- {
- SPDAT=dat;
- while((SPSTA&0x80)==0x00);
- SPSTA=0xC0;
- return SPDAT;
- }
- //-----------------------------------------------------------------
- // 從當(dāng)前地址讀取一字節(jié)數(shù)據(jù)(模擬方式)
- //-----------------------------------------------------------------
- INT8U ReadByte()
- {
- INT8U i,d=0x00;
- for(i=0;i<8;i++)
- {
- SCK=1;SCK=0;d=(d<<1)|SDO;
- }
- return d;
- }
- //-----------------------------------------------------------------
- // 向當(dāng)前地址寫入一字節(jié)數(shù)據(jù)(模擬方式)
- //-----------------------------------------------------------------
- void WriteByte(INT8U dat)
- {
- INT8U i;
- for(i=0;i<8;i++)
- { dat<<=1;SDI=CY;
- SCK=0;SCK=1;
- }
- }
- //-----------------------------------------------------------------
- // 向TC72寫入兩字節(jié)(地址,數(shù)據(jù))(模擬方式)
- //-----------------------------------------------------------------
- void Write_TC72(INT8U addr, INT8U dat)
- {
- CE=1;
- WriteByte(addr);
- WriteByte(dat);
- CE=0;
- }
- //-----------------------------------------------------------------
- // 寫TC72配置數(shù)據(jù)
- //-----------------------------------------------------------------
- void Config_TC72()
- {
- Write_TC72(TC72_CTRL,0x15);
- }
- //-----------------------------------------------------------------
- // 從TC72讀取兩字節(jié)溫度數(shù)據(jù)并轉(zhuǎn)換為浮點(diǎn)溫度值
- //-----------------------------------------------------------------
- void Read_TC72_Temperature()
- {
- Config_TC72();
- delay_ms(20);
- CE=1;
- WriteByte(TC72_TEMP_MSB);
- T[1]=ReadByte();
- T[0]=ReadByte();
- CE=0;
- TempX=(((int)((T[1]<<8)|T[0]))>>6)*0.25;
- }
- //-----------------------------------------------------------------
- // 主程序
- //-----------------------------------------------------------------
- void main()
- {
- char DisplayBuffer[17];
- Initialize_LCD();
- LCD_ShowString(0,0,"TC72 Sensor Test");
- while(1)
- { Config_TC72();
- Read_TC72_Temperature();
- sprintf(DisplayBuffer,"%TEMP:%6.1f\xDF\x43",TempX);
- LCD_ShowString(1,0,DisplayBuffer);
- }
- }
- //-----------------------------------------------------------------
- // 液晶控制與顯示程序
- //-----------------------------------------------------------------
- #include <reg51rc2.h>
- #include <intrins.h>
- #define INT8U unsigned char
- #define INT16U unsigned int
- sbit RS = P2^0; //寄存器選擇線
- sbit RW = P2^1; //讀/寫控制線
- sbit EN = P2^2; //使能控制線
- //-----------------------------------------------------------------
- // 延時
- //-----------------------------------------------------------------
- void delay_ms(INT16U ms)
- {
- INT8U i;
- while(ms--) for(i = 0; i < 120; i++);
- }
- //-----------------------------------------------------------------
- // 忙等待
- //-----------------------------------------------------------------
- void Busy_Wait()
- {
- INT8U LCD_Status; //液晶狀態(tài)字節(jié)變量
- do
- { P0=0xff; //液晶屏端口初始置高電平
- EN=0;RS=0;RW=1; //LCD禁止,選擇狀態(tài)寄存器,準(zhǔn)備讀
- EN=1;LCD_Status=P0; //LCD使能,從P0端口讀取液晶屏狀態(tài)字節(jié)
- EN=0; //LCD禁止
- } while (LCD_Status & 0x80); //液晶忙繼續(xù)循環(huán)
- }
- //-----------------------------------------------------------------
- // 寫LCD命令
- //-----------------------------------------------------------------
- void Write_LCD_Command(INT8U cmd)
- {
- Busy_Wait();
- RS=0;
- RW=0;
- EN=0;
- P0=cmd;
- EN=1;
- delay_ms(1);
- EN=0;
- }
- //-----------------------------------------------------------------
- // 發(fā)送數(shù)據(jù)
- //-----------------------------------------------------------------
- void Write_LCD_Data(INT8U dat)
- {
- Busy_Wait();
- RS=1;
- RW=0;
- EN=0;
- P0=dat;
- EN=1;
- delay_ms(1);
- EN=0;
- }
- //-----------------------------------------------------------------
- // LCD初始化
- //-----------------------------------------------------------------
- void Initialize_LCD()
- {
- Write_LCD_Command(0x38); delay_ms(1); //置功能,8位,雙行,5*7
- Write_LCD_Command(0x01); delay_ms(1); //清屏
- Write_LCD_Command(0x06); delay_ms(1); //字符進(jìn)入模式:屏幕不動,字符后移
- Write_LCD_Command(0x0C); delay_ms(1); //顯示開,關(guān)光標(biāo)
- }
- //-----------------------------------------------------------------
- // 顯示字符串
- //-----------------------------------------------------------------
- void LCD_ShowString(INT8U r, INT8U c,INT8U *str)
- {
- INT8U i = 0;
- code INT8U DDRAM[] = {0x80,0xC0}; //1602LCD兩行的起始DDRAM地址
- Write_LCD_Command(DDRAM[r] | c); //設(shè)置顯示起始位置
-
- for ( i = 0; str[i] && i < 16 ;i++) //輸出字符串
- Write_LCD_Data(str[i]);
-
- for (i=0; i < 16; i++) //不足一行時用空格填充
- Write_LCD_Data(' ');
- }
復(fù)制代碼
以上圖文的Word格式文檔下載(內(nèi)容和本網(wǎng)頁上的一模一樣,方便大家保存):
|