|
三機通信界面圖.jpg (322.52 KB, 下載次數: 46)
下載附件
2021-7-13 14:55 上傳
單片機源程序如下:
#include<AT89X52.h> //頭文件
#include<intrins.h> //包含_nop_()函數定義的頭文件
#define uchar unsigned char //宏定義
#define schar signed char
#define uint unsigned int
#define sint signed int
#define ulong unsigned long
#define slong signed long
#define HIGH 1
#define LOW 0
#define DISABLE EA=0; //關所有中斷
#define ENABLE EA=1; //開所有中斷
#define TXEN P3_7=HIGH; //發送使能
#define RXEN P3_7=LOW; //接收使能
#define WDTA {WDTRST = 0x1E; WDTRST = 0xE1;} //喂狗
#define REG_BANK_0 0 //寄存器組0
#define REG_BANK_1 1 //寄存器組1
#define REG_BANK_2 2 //寄存器組2
#define REG_BANK_3 3 //寄存器組
//中斷入口地址
#define INTERRUPT_INT0 0 //0x0003
#define INTERRUPT_T0 1 //0x000b
#define INTERRUPT_INT1 2 //0x0013
#define INTERRUPT_T1 3 //0x001b
#define INTERRUPT_UART 4 //0x0023
#define TIME_10MS_12MHZ 10000 //12MHZ時,定時10mS
#define TIME_25MS_12MHZ 25000
#define TIME_50MS_12MHZ 50000
#define TIME_10MS_11MHZ 9216//11MHZ時,定時10mS
#define TIME_25MS_11MHZ 23040
#define TIME_50MS_11MHZ 46080
#define BAUD9600_12M 0xfd //波特率為9600時,定時器初始化的初值
#define BAUD9600_11M 0xfd
sbit BEEP = P2^4; //蜂鳴器報警驅動
sbit Relay1 = P2^0; //繼電器1驅動控制
sbit Relay2 = P2^1; //繼電器2驅動控制
sbit Scl = P2^2; //AT24C02 串行時鐘
sbit Sda = P2^3; //AT24C02 串行數據
sbit DS1302_CLK = P1^0; //實時時鐘時鐘線引腳
sbit DS1302_IO = P1^1; //實時時鐘數據線引腳
sbit DS1302_RST = P1^2; //實時時鐘復位線引腳
sbit Set = P1^4; //模式切換鍵
sbit Up = P1^5; //加法按鈕
sbit Down = P1^6; //減法按鈕
sbit out = P1^7; //立刻跳出調整模式按鈕
sbit wireless_1 = P3^2; //無線遙控數據接口
sbit wireless_2 = P3^3;
sbit wireless_3 = P3^4;
sbit wireless_4 = P3^5;
sbit ACC0 = ACC^0;
sbit ACC7 = ACC^7;
char hide_temp,hide_sec,hide_min,hide_hour,hide_day,hide_week,hide_month,hide_year; //溫度,秒,分,時到日,月,年位閃的計數
char done,count,temp,flag,up_flag,down_flag; //done顯示切換標志,count模式鍵按下次數計數,temp暫存時間值
uchar T0Count=0;
uchar temp_value[2][4]={{0,0,0,0},{0,0,0,0}}; //第一個字節是從機地址,第2~4個字節測量溫度值的十位、個位和小數位
uchar TempBuffer1[11]={0x31,0x3a,0x20,0x20,0x2e,0x20,0xdf,0x43,0x20,0x20,'\0'};//從機1溫度顯示緩沖區 1:**.*
uchar TempBuffer2[9]={0x32,0x3a,0x20,0x20,0x2e,0x20,0xdf,0x43,'\0'}; //從機2溫度顯示緩沖區 2:**.*
uchar TempBuffer3[5]={0x33,0x37,0xdf,0x43,'\0'}; //溫度上限值顯示緩沖區
uchar TemperatureSetUp[2]={3,7}; //設定溫度的上限值顯示緩沖區37度
uchar UpTemp=40; //溫度的上限值
uchar TempBuffer[5],week_value[2];
void show_time(); //液晶顯示程序
/**********************************************************
* 延時子程序 x*0.14MS
**********************************************************/
void delay(uchar x) //x*0.14MS
{
uchar i;
while(x--)
{
for (i = 0; i<13; i++) {WDTA;}
}
}
/**********************************************************
* 延時子程序 ms毫秒
**********************************************************/
void mdelay(uint delay)
{ uint i;
for(;delay>0;delay--)
{for(i=0;i<62;i++) //1ms延時.
{ WDTA;}//喂狗
}
}
/**********************************************************
* 蜂鳴器響一聲
**********************************************************/
void beep()
{
uchar i;
for (i=0;i<180;i++)
{
delay(5);
BEEP=!BEEP; //BEEP取反
}
BEEP=1; //關閉蜂鳴器
mdelay(200);
}
/***********1602液晶顯示部分子程序****************/
//Port Definitions**********************************************************
sbit LcdRs = P2^7;
sbit LcdRw = P2^6;
sbit LcdEn = P2^5;
sfr DBPort = 0x80; //P0=0x80,P1=0x90,P2=0xA0,P3=0xB0 數據端口
//內部等待函數**************************************************************************
unsigned char LCD_Wait(void)
{
LcdRs=0;
LcdRw=1; _nop_();
LcdEn=1; _nop_();
LcdEn=0;
return DBPort;
}
//向LCD寫入命令或數據************************************************************
#define LCD_COMMAND 0 // Command
#define LCD_DATA 1 // Data
#define LCD_CLEAR_SCREEN 0x01 // 清屏
#define LCD_HOMING 0x02 // 光標返回原點
void LCD_Write(bit style, unsigned char input)
{
LcdEn=0;
LcdRs=style;
LcdRw=0; _nop_();
DBPort=input; _nop_();//注意順序
LcdEn=1; _nop_();//注意順序
LcdEn=0; _nop_();
LCD_Wait();
}
//設置顯示模式************************************************************
#define LCD_SHOW 0x04 //顯示開
#define LCD_HIDE 0x00 //顯示關
#define LCD_CURSOR 0x02 //顯示光標
#define LCD_NO_CURSOR 0x00 //無光標
#define LCD_FLASH 0x01 //光標閃動
#define LCD_NO_FLASH 0x00 //光標不閃動
void LCD_SetDisplay(unsigned char DisplayMode)
{
LCD_Write(LCD_COMMAND, 0x08|DisplayMode);
}
//設置輸入模式************************************************************
#define LCD_AC_UP 0x02
#define LCD_AC_DOWN 0x00 // default
#define LCD_MOVE 0x01 // 畫面可平移
#define LCD_NO_MOVE 0x00 //default
void LCD_SetInput(unsigned char InputMode)
{
LCD_Write(LCD_COMMAND, 0x04|InputMode);
}
//初始化LCD************************************************************
void LCD_Initial()
{
LcdEn=0;
LCD_Write(LCD_COMMAND,0x38); //8位數據端口,2行顯示,5*7點陣
LCD_Write(LCD_COMMAND,0x38);
LCD_SetDisplay(LCD_SHOW|LCD_NO_CURSOR); //開啟顯示, 無光標
LCD_Write(LCD_COMMAND,LCD_CLEAR_SCREEN); //清屏
LCD_SetInput(LCD_AC_UP|LCD_NO_MOVE); //AC遞增, 畫面不動
}
//液晶字符輸入的位置************************
void GotoXY(unsigned char x, unsigned char y)
{
if(y==0)
LCD_Write(LCD_COMMAND,0x80|x);
if(y==1)
LCD_Write(LCD_COMMAND,0x80|(x-0x40));
}
//將字符輸出到液晶顯示
void Print(unsigned char *str)
{
while(*str!='\0')
{
LCD_Write(LCD_DATA,*str);
str++;
WDTA;//喂狗
}
}
/*************** AT24C02 start **********************/
/*發送起始條件*/
void Start(void) /*起始條件*/
{
Sda=1;
Scl=1;
_nop_ ();
_nop_ ();
_nop_ ();
_nop_ ();
Sda=0;
_nop_ ();
_nop_ ();
_nop_ ();
_nop_ ();
}
void Stop(void) /*停止條件*/
{
Sda=0;
Scl=1;
_nop_ ();
_nop_ ();
_nop_ ();
_nop_ ();
Sda=1;
_nop_ ();
_nop_ ();
_nop_ ();
_nop_ ();
}
void Ack(void) /*應答位0*/
{
Sda=0;
_nop_ ();
_nop_ ();
_nop_ ();
_nop_ ();
Scl=1;
_nop_ ();
_nop_ ();
_nop_ ();
_nop_ ();
Scl=0;
}
void NoAck(void) /*反向應答位1*/
{
Sda=1;
_nop_ ();
_nop_ ();
_nop_ ();
_nop_ ();
Scl=1;
_nop_ ();
_nop_ ();
_nop_ ();
_nop_ ();
Scl=0;
}
void Send(uchar Data) /*發送數據子程序,Data為要求發送的數據*/
{
uchar BitCounter=8; /*位數控制*/
uchar temp; /*中間變量控制*/
WDTA;//喂狗
do
{
temp=Data;
Scl=0;
_nop_ ();
_nop_ ();
_nop_ ();
_nop_ ();
if((temp&0x80)==0x80)/* 如果最高位是1*/
Sda=1;
else
Sda=0;
Scl=1;
temp=Data<<1; /*RLC*/
Data=temp;
BitCounter--;
}while(BitCounter) ;
Scl=0;
}
uchar Read(void) /*讀一個字節的數據,并返回該字節值*/
{
uchar temp=0;
uchar temp1=0;
uchar BitCounter=8;
Sda=1;
WDTA;//喂狗
do{
Scl=0;
_nop_ ();
_nop_ ();
_nop_ ();
_nop_ ();
Scl=1;
_nop_ ();
_nop_ ();
_nop_ ();
_nop_ ();
if(Sda) /*如果Sda=1;*/
temp=temp|0x01; /*temp的最低位置1*/
else
temp=temp&0xfe; /*否則temp的最低位清0*/
if(BitCounter-1)
{ temp1=temp<<1;
temp=temp1;
}
BitCounter--;
}while(BitCounter) ;
return(temp);
}
void WrToROM(uchar Data[],uchar Address,uchar Num)//寫入一組數據到AT24C02中
{ //參數為數組的首地址,數據在AT24C02中的開始地址,數據個數
uchar i=0;
uchar *PData;
PData=Data;
WDTA;//喂狗
Start();
Send(0xa0); //A0、A1、A2接地,固AT24C02的寫地址為0XA0
Ack();
Send(Address);
Ack();
for(i=0;i<Num;i++)
{
Send(*(PData+i));
Ack();
}
WDTA;//喂狗
Stop();
}
void RdFromROM(uchar Data[],uchar Address,uchar Num)//讀出一組數據到AT24C02中
//參數為數組的首地址,數據在AT24C02中的開始地址,數據個數
{
uchar i=0;
uchar *PData;
PData=Data;
for(i=0;i<Num;i++)
{
WDTA;//喂狗
Start();
Send(0xa0); //A0、A1、A2接地,固AT24C02的寫地址為0XA0
Ack();
Send(Address+i);
Ack();
Start();
Send(0xa1); //A0、A1、A2接地,固AT24C02讀地址為0XA1
Ack();
*(PData+i)=Read();
Scl=0;
NoAck();
Stop();
}
}
/*************** AT24C02 end **********************/
/***********DS1302時鐘部分子程序******************/
typedef struct __SYSTEMTIME__
{
unsigned char Second;
unsigned char Minute;
unsigned char Hour;
unsigned char Week;
unsigned char Day;
unsigned char Month;
unsigned char Year;
unsigned char DateString[11];
unsigned char TimeString[9];
}SYSTEMTIME; //定義的時間類型
SYSTEMTIME CurrentTime;
#define AM(X) X
#define PM(X) (X+12) // 轉成24小時制
#define DS1302_SECOND 0x80 //時鐘芯片的寄存器位置,存放時間
#define DS1302_MINUTE 0x82
#define DS1302_HOUR 0x84
#define DS1302_WEEK 0x8A
#define DS1302_DAY 0x86
#define DS1302_MONTH 0x88
#define DS1302_YEAR 0x8C
void DS1302InputByte(unsigned char d) //實時時鐘寫入一字節(內部函數)
{
unsigned char i;
ACC = d;
for(i=8; i>0; i--)
{
DS1302_IO = ACC0; //相當于匯編中的 RRC
DS1302_CLK = 1;
DS1302_CLK = 0;
ACC = ACC >> 1;
}
}
unsigned char DS1302OutputByte(void) //實時時鐘讀取一字節(內部函數)
{
unsigned char i;
for(i=8; i>0; i--)
{
ACC = ACC >>1; //相當于匯編中的 RRC
ACC7 = DS1302_IO;
DS1302_CLK = 1;
DS1302_CLK = 0;
}
return(ACC);
}
void Write1302(unsigned char ucAddr, unsigned char ucDa) //ucAddr: DS1302地址, ucData: 要寫的數據
{
DS1302_RST = 0;
DS1302_CLK = 0;
DS1302_RST = 1;
DS1302InputByte(ucAddr); // 地址,命令
DS1302InputByte(ucDa); // 寫1Byte數據
DS1302_CLK = 1;
DS1302_RST = 0;
}
unsigned char Read1302(unsigned char ucAddr) //讀取DS1302某地址的數據
{
unsigned char ucData;
DS1302_RST = 0;
DS1302_CLK = 0;
DS1302_RST = 1;
DS1302InputByte(ucAddr|0x01); // 地址,命令
ucData = DS1302OutputByte(); // 讀1Byte數據
DS1302_CLK = 1;
DS1302_RST = 0;
return(ucData);
}
void DS1302_GetTime(SYSTEMTIME *Time) //獲取時鐘芯片的時鐘數據到自定義的結構型數組
{
unsigned char ReadValue;
WDTA;//喂狗
ReadValue = Read1302(DS1302_SECOND);
Time->Second = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
ReadValue = Read1302(DS1302_MINUTE);
Time->Minute = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
ReadValue = Read1302(DS1302_HOUR);
Time->Hour = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
WDTA;//喂狗
ReadValue = Read1302(DS1302_DAY);
Time->Day = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
ReadValue = Read1302(DS1302_WEEK);
Time->Week = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
WDTA;//喂狗
ReadValue = Read1302(DS1302_MONTH);
Time->Month = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
ReadValue = Read1302(DS1302_YEAR);
Time->Year = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
WDTA;//喂狗
}
|
評分
-
查看全部評分
|