硬件:max6675 STC12C5A60S2 K型热电偶
功能:实现读取K型热电偶温度,并通过上位机打印出实际温度
难点:读取Max6675的数据是16位,而STC12系列单片机每次接收的数据为8位,如何通过硬件SPI实现直接读取Max6675的温度成为一难点。网上相关教程以及相关论文均是采用软件SPI模拟时序方式采集数据,故而通过STC12系列单片机自带的硬件SPI实现直接读取Max6675的数据具有实际研究意义。
代码:
#include "reg51.h" #include "stdio.h" #include<intrins.h> //??_nop_()???? #define MASTER //define:master undefine:slave #define FOSC 11059200L #define BAUD (256 - FOSC / 32 / 9600) //253 typedef unsigned char BYTE; typedef unsigned int WORD; typedef unsigned long DWORD; sfr AUXR = 0x8e; //Auxiliary register sfr SPSTAT = 0xcd; //SPI status register #define SPIF 0x80 //SPSTAT.7 #define WCOL 0x40 //SPSTAT.6 sfr SPCTL = 0xce; //SPI control register #define SSIG 0x80 //SPCTL.7 #define SPEN 0x40 //SPCTL.6 #define DORD 0x20 //SPCTL.5 #define MSTR 0x10 //SPCTL.4 #define CPOL 0x08 //SPCTL.3 #define CPHA 0x04 //SPCTL.2 #define SPDHH 0x00 //CPU_CLK/4 #define SPDH 0x01 //CPU_CLK/16 #define SPDL 0x02 //CPU_CLK/64 #define SPDLL 0x03 //CPU_CLK/128 sfr SPDAT = 0xcf; //SPI data register sbit SPISS = P1^3; //SPI slave select, connect to slave' SS(P1.4) pin void InitUart(); void InitSPI(); void SendUart(BYTE dat); //send data to PC BYTE RecvUart(); //receive data from PC unsigned int SPISwap(); //swap SPI data between master void Delay_xms(unsigned int z){ unsigned char i, j; unsigned int k; for(k=0;k<z;k++){ //for???????1ms?? _nop_(); _nop_(); i = 12; j = 84; do{while (--j);} while (--i); } } /////////////////////////////////////////////////////////// void main() { unsigned int t; unsigned int a= 0x01; unsigned int MAX6675_Temp; unsigned char Flag_connect; InitUart(); //initial UART InitSPI(); //initial SPI while (1) { // #ifdef MASTER //for master (receive UART data from PC and send it to slave, // // in the meantime receive SPI data from slave and send it to PC) // SendUart(SPISwap(RecvUart())); // #else //for salve (receive SPI data from master and // ACC = SPISwap(ACC); // send previous SPI data to master) // printf("dd"); // #endif t=SPISwap(); Flag_connect=t&0x04; //¶Á³öÊý¾ÝµÄD2λÊÇÈȵçżµôÏß±ê־룬¸ÃλΪ1±íʾµôÏߣ¬¸ÃλΪ0±íʾÁ¬½Ó Flag_connect=Flag_connect>>2; //MAX6675ÊÇ·ñÔÚÏß t = t<<1; //¶Á³öÀ´µÄÊý¾ÝµÄD3~D14ÊÇζÈÖµ t = t>>4; MAX6675_Temp = t/4-28; //²âµÃµÄζȵ¥Î»ÊÇ0.25£¬ËùÒÔÒª³ËÒÔ0.25£¨¼´³ýÒÔ4£©²ÅÄܵõ½ÒÔ¶ÈΪµ¥Î»µÄζÈÖµ if(Flag_connect==0) //Flag_connectΪ0±íʾÈȵçżÒÑÁ¬½Ó£¬ÕâʱÏÔʾÎÂ¶È { printf("%d ",MAX6675_Temp); } else { printf("δÁ¬ÉÏ "); } // printf("%d ",t); //// printf("%d ",t/4); Delay_xms(1000); } } /////////////////////////////////////////////////////////// void InitUart() { SCON = 0x5a; //set UART mode as 8-bit variable baudrate TMOD = 0x20; //timer1 as 8-bit auto reload mode AUXR = 0x40; //timer1 work at 1T mode TH1 = TL1 = BAUD; //115200 bps TR1 = 1; } /////////////////////////////////////////////////////////// void InitSPI() { SPDAT = 0; //initial SPI data SPSTAT = SPIF | WCOL; //clear SPI status #ifdef MASTER SPCTL = SPEN | MSTR; //master mode #else SPCTL = SPEN; //slave mode #endif } /////////////////////////////////////////////////////////// void SendUart(BYTE dat) { while (!TI); //wait pre-data sent TI = 0; //clear TI flag SBUF = dat; //send current data } /////////////////////////////////////////////////////////// BYTE RecvUart() { while (!RI); //wait receive complete RI = 0; //clear RI flag return SBUF; //return receive data } /////////////////////////////////////////////////////////// unsigned int SPISwap() { unsigned int temp=0; SPISS = 0; //pull low slave SS SPDAT = 25; //trigger SPI send while (!(SPSTAT & SPIF)); //wait send complete SPSTAT = SPIF | WCOL; //clear SPI statusa temp = SPDAT; temp = temp << 8; SPDAT = 45; while (!(SPSTAT & SPIF)); //wait send complet temp = temp | SPDAT; SPSTAT = SPIF | WCOL; //clear SPI status SPISS = 1; //push high slave SS return temp; //return received SPI data }