- //-----------------------------------------------------------------
- // 名稱: 帶日歷時鐘及溫度顯示的電子萬年歷
- //-----------------------------------------------------------------
- // 說明: 本例使用了DS1302讀取日期時間,用TC72獲取溫度數據
- // 通過74HC595驅動數碼管顯示.
- //
- //-----------------------------------------------------------------
- #include <reg51.h>
- #include <intrins.h>
- #include <stdio.h>
- #include <string.h>
- #define INT8U unsigned char
- #define INT16U unsigned int
- const INT8U SEG_CODE[]= //0~9的段碼,攝氏度段碼(2字節(jié)),黑屏段碼,負號段碼
- { 0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8, 0x80,0x90,0xC6,0x9C,0xFF,0xBF};
- INT8U DateTime[7] = {5,4,3,2,1,5,12}; //假定時間12年1月2日,3點,4分5秒
- sbit DS = P3^0; //串行數據輸入
- sbit SH_CP = P3^1; //移位時鐘脈沖
- sbit ST_CP = P3^2; //輸出鎖存器控制脈沖
- extern void Init_DS1302();
- extern void GetDateTime();
- extern void SetDateTime();
- extern INT8U CurrDateTime[];
- extern void Config_TC72();
- extern float Read_TC72_Temperature();
- //所有數碼管的顯示緩沖(年有高2位固定為20),最后2位固定為攝氏度段碼索引
- INT8U disp_buff[21] = {2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,10};
- //-----------------------------------------------------------------
- // 延時函數
- //-----------------------------------------------------------------
- void delay_ms(INT16U x) { INT8U t; while(x--) for(t = 0; t<120; t++);}
- //-----------------------------------------------------------------
- // 1字節(jié)數據串行輸入595子程序
- //-----------------------------------------------------------------
- void Serial_Input_595(INT8U d)
- {
- INT8U i;
- for(i=0;i<8;i++)
- { d<<=1;DS=CY;
- SH_CP=0;_nop_();_nop_();
- SH_CP=1;_nop_();_nop_();
- }
- SH_CP=0;
- }
- //-----------------------------------------------------------------
- // 595并行輸出子程序
- //-----------------------------------------------------------------
- void Parallel_Output_595()
- {
- ST_CP=0;_nop_();_nop_();
- ST_CP=1;_nop_();_nop_();
- ST_CP=0;_nop_();_nop_();
- }
- //------------------------------------------------------------------
- // 主程序
- //------------------------------------------------------------------
- void main()
- {
- INT8U i,j,len;char t_buff[6],c;INT8U curr_second=0xFF;
- TMOD=0x01;
- TH0=(INT16U)(-11.0592/12*50000)>>8;
- TL0=(INT16U)(-11.0592/12*50000)&0xFF;
- IE=0x82;
- Init_DS1302();
- while(1)
- {
- GetDateTime();
- disp_buff[2]=CurrDateTime[6]>>4;
- disp_buff[3]=CurrDateTime[6]&0x0F;
- disp_buff[4]=CurrDateTime[4]>>4;
- disp_buff[5]=CurrDateTime[4]&0x0F;
- disp_buff[6]=CurrDateTime[3]>>4;
- disp_buff[7]=CurrDateTime[3]&0x0F;
- disp_buff[8]=CurrDateTime[2]>>4;
- disp_buff[9]=CurrDateTime[2]&0x0F;
- disp_buff[10]=CurrDateTime[1]>>4;
- disp_buff[11]=CurrDateTime[1]&0x0F;
- disp_buff[12]=CurrDateTime[0]>>4;
- disp_buff[13]=CurrDateTime[0]&0x0F;
- disp_buff[14]=CurrDateTime[5]-1;
-
- for(i=15;i<18;i++)disp_buff[i]=12;
- Config_TC72();
- sprintf(t_buff,"%5.1f",Read_TC72_Temperature());
- i=j=0;len=strlen(t_buff);
- for(i=len-1;i!=0xFF;i--)
- {
- c=t_buff[i];if(c=='.')continue;
- if(c>='0'&&c<='9')disp_buff[18-j]=c-'0';
- else if (c=='-')disp_buff[18-j]=13;
- j++;
- }
-
- for(i=20;i!=0xFF;i--)
- {
- if(i!=17)Serial_Input_595(SEG_CODE[disp_buff[i]]);
- else Serial_Input_595(SEG_CODE[disp_buff[i]]&0x7F);
- }
-
- Parallel_Output_595();
-
- if(curr_second!=CurrDateTime[0])
- {
- curr_second=CurrDateTime[0];
- if(TR0==0)P0&=0xFC;TR0=1;
- }
- }
- }
- //-----------------------------------------------------------------
- // T0中斷函數(控制秒閃爍,每隔500ms關閉LED,開LED由主程序控制)
- //-----------------------------------------------------------------
- void LED_Flash() interrupt 1
- {
- static INT8U T_Count=0;
- TH0=(INT16U)(-11.0592/12*50000)>>8;
- TL0=(INT16U)(-11.0592/12*50000)&0xFF;
- if(++T_Count==10)
- {
- P0|=0x03;T_Count=0;TR0=0;
- }
- }
復制代碼//-----------------------------------------------------------------
// 名稱: SPI接口溫度傳感器TC72驅動程序
//-----------------------------------------------------------------
#include "STC15xxx.h"
#include <intrins.h>
#include <stdio.h>
#include <math.h>
#define u8 unsigned char
#define u16 unsigned int
//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; //串行數據輸入
sbit SDO = P3^7; //串行數據輸出
u8 Temp_Value[2]; //兩字節(jié)溫度值原始數據
extern void delay_ms(u16 x);
//-----------------------------------------------------------------
// 從當前地址讀取一字節(jié)數據(模擬方式)
//-----------------------------------------------------------------
u8 _ReadByte() {
u8 i ,d = 0x00;
for(i = 0; i < 8; i++) //串行讀取8位數據
{ //SCK下降沿讀取數據,讀取的位保存到左移以后的d的低位
SCK = 1; SCK = 0; d = (d << 1) | SDO;
}
return d; //返回讀取的字節(jié)
}
//-----------------------------------------------------------------
// 向當前地址寫入一字節(jié)數據(模擬方式)
//-----------------------------------------------------------------
void _WriteByte(u8 dat) {
u8 i;
for(i = 0; i < 8; i++) { //串行寫入8位數據
dat <<= 1; SDI = CY; //dat左移位,高位被移入CY,發(fā)送高位
SCK = 0; SCK = 1; //時鐘上升沿向存儲器寫入數據
}
}
//-----------------------------------------------------------------
// 向TC72寫入兩字節(jié)(地址,數據)(模擬方式)
//-----------------------------------------------------------------
void Write_TC72(u8 addr, u8 dat) {
CE = 1; //SPI_EN();
_WriteByte(addr); //SPI_SendData(addr);
_WriteByte(dat); //SPI_SendData(dat);
CE = 0; //SPI_DI();
}
//-----------------------------------------------------------------
// 寫TC72配置數據
//-----------------------------------------------------------------
void Config_TC72() {
Write_TC72(TC72_CTRL,0x15); //配置為單次轉換與關斷模式
}
//-----------------------------------------------------------------
// 從TC72讀取兩字節(jié)溫度數據并轉換為浮點溫度值
//-----------------------------------------------------------------
float Read_TC72_Temperature() {
Config_TC72();
delay_ms(50);
CE = 1; //SPI_EN();
//發(fā)送讀溫度高字節(jié)命令
_WriteByte(TC72_TEMP_MSB); //SPI_SendData(TC72_TEMP_MSB);
//連續(xù)讀取兩字節(jié)(連續(xù)讀取時先得到的是高字節(jié),后得到的是低字節(jié))
Temp_Value[1] = _ReadByte(); //SPI_SendData(0xFF);//讀高字節(jié)
Temp_Value[0] = _ReadByte(); //SPI_SendData(0xFF);//讀低字節(jié)
CE = 0; //SPI_DI();
//還可以使用以下單字節(jié)讀取的方法
//SPI_EN();
//SPI_SendData(TC72_TEMP_LSB); //發(fā)送讀溫度低字節(jié)命令
//T[0] = SPI_SendData(0xFF); //讀LSB
//SPI_DI();
//SPI_EN();
//SPI_SendData(TC72_TEMP_MSB); //發(fā)送讀溫度高字節(jié)命令
//T[1] = SPI_SendData(0xFF); //讀MSB
//SPI_DI();
return (int)(((int)((Temp_Value[1]<<8)|Temp_Value[0]))>>6) * 0.25;
}
|