?? mcs51-項目開發經典.c
字號:
//=================================================================================================
// 項目名:MCS51-項目開發經典
// 硬件文件名:51Studay.DDB
// 程序組目錄名:MCS51-項目開發經典
// 開始時間:2007年5月21日
// 完成時間:2007年6月10日
//-------------------------------------------------------------------------------------------------
// 程序中用到哪些C51標準函數,就需要把該函數對應的頭文件包含進來
//-------------------------------------------------------------------------------------------------
#include <intrins.h>
#include <string.h>
#include <absacc.h>
#include <reg52.h>
//-------------------------------------------------------------------------------------------------
// 為提高書寫效率做以下宏定義
//-------------------------------------------------------------------------------------------------
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
#define CLOSE 1
#define OPEN 0
sbit dq =P2^4;
bit flag;
//-------------------------------------------------------------------------------------------------
// 操作UART串口相關的全局變量
//-------------------------------------------------------------------------------------------------
uchar idata uart_buffer[40];//串口接收緩沖區,可接收字符串的最大長度為40
uchar uart_buffer_address;//串口接收緩沖區地址計數器
bit uart_receive_start; //串口接收啟動
bit uart_receive_ok; //串口接收(UART0)中斷里已接收完整消息標志
//-------------------------------------------------------------------------------------------------
uint t1_delay_time;//50毫秒計數器累加變量,在T1中斷里累加
// 函數聲明
//-------------------------------------------------------------------------------------------------
void init_cpu(void);
void uart_byte_out(uchar uart_data_out);
void uart_string_out(char * char_array);
void uart_data_decimalist_out(uint data_to_out);
void uart_newline(uchar newline_number);
uchar change_hex_to_askii(uchar data_hex);
void init_18b20 (void);
uint read_word (void);
void write (uchar wr);
float get_temp (void);
void delay(unsigned int i);
//=================================================================================================
//=================================================================================================
//=================================================================================================
//===================== ================================================
//===================== 主程序 ================================================
//===================== ================================================
//=================================================================================================
void main (void)
{
float temperature=0;
uint ttttt;
init_cpu();
init_18b20 ();
wqyloop:
t1_delay_time=0;
temperature=get_temp ();//讀溫度
ttttt=(uint)(temperature*10+0.5);
uart_string_out("The wendu is :");
uart_data_decimalist_out(ttttt);
uart_newline(2);
for(t1_delay_time=0;t1_delay_time<50;);//延時500毫秒
goto wqyloop;
}//The end of main()
//########################## 主程序結束 #########################################################
//########################## 子程序開始 #########################################################
//=================================================================================================
// 函數功能:CPU初始化函數
// 串口波特率可以由T1或T2產生,本例中用T1產生波特率
// T2用于50毫秒精確定時
// T0用于PWM控制中頻率的時基
//=================================================================================================
void init_cpu(void)
{
TMOD=0x12;//T1為16位計數器,T0為8位自動重裝載計數器
ET1=1;
TH1=0x4c;//11.0592M晶振時T1定時時間長度為50毫秒
TL1=0x00;
TR1=1;//T1開始定時
T2CON=0x30;//定時器T2工作于波特率發生器方式
RCAP2H=0xff;//11.0592M晶振,9600bps初值
RCAP2L=0xdc;
TH2=0xff;
TL2=0xdc;
TR2=1;//允許T2中斷
SCON=0x40;//串口工作于方式1,啟動串口接收
EA=1;//CPU中斷開放
}
//=================================================================================================
// 串口UART操作相關程序
//=================================================================================================
//函數功能:串口發射1個字節
void uart_byte_out(uchar uart_data_out)
{ SBUF = uart_data_out;
while(TI==0);
TI=0;
}
//-------------------------------------------------------------------------------------------------
//函數功能:串口發射字符數組。通常將要發送的字符數組定義在CODE代碼區。
void uart_string_out(char * char_array)
{ uchar i;
for(i=0; i<strlen(char_array) ;i++)
{
uart_byte_out(char_array[i]);
}
}
//-------------------------------------------------------------------------------------------------
//函數功能:串口輸出數據十進制到PC機屏幕上
//形參:范圍 0-65535 ;例如:data_to_out=12345(或0x3039),則計算機屏幕就顯示12345
void uart_data_decimalist_out(uint data_to_out)
{ bit entrance;
uchar ge,shi,bai,qian,wan;
wan = (data_to_out/10000) ;//拆分萬位,并轉化為ASKII碼
qian = (data_to_out%10000)/1000;//拆分千位,并轉化為ASKII碼
bai = (data_to_out%1000)/100 ;//拆分百位,并轉化為ASKII碼
shi = (data_to_out%100)/10 ;//拆分十位,并轉化為ASKII碼
ge = (data_to_out%10) ;//拆分個位,并轉化為ASKII碼
entrance=1;//開放個、十、百、千、萬的判斷傳輸入口
if(wan && entrance)
{uart_byte_out(change_hex_to_askii(wan));
uart_byte_out(change_hex_to_askii(qian));
uart_byte_out(change_hex_to_askii(bai));
uart_byte_out(change_hex_to_askii(shi));
uart_byte_out(change_hex_to_askii(ge));
entrance=0;//如果萬位不為0,則不再判斷其它位
}
else if(qian && entrance)
{uart_byte_out(change_hex_to_askii(qian));
uart_byte_out(change_hex_to_askii(bai));
uart_byte_out(change_hex_to_askii(shi));
uart_byte_out(change_hex_to_askii(ge));
entrance=0;//如果千位不為0,則不再判斷其它位
}
else if(bai && entrance)
{uart_byte_out(change_hex_to_askii(bai));
uart_byte_out(change_hex_to_askii(shi));
uart_byte_out(change_hex_to_askii(ge));
entrance=0;//如果百位不為0,則不再判斷其它位
}
else if(shi && entrance)
{uart_byte_out(change_hex_to_askii(shi));
uart_byte_out(change_hex_to_askii(ge));
entrance=0;//如果十位不為0,則不再判斷其它位
}
else
{uart_byte_out(change_hex_to_askii(ge));
}
}
//-------------------------------------------------------------------------------------------------
// 函數功能:串口顯示的回車換行
// 形參:newline_number 表示一共換幾行
void uart_newline(uchar newline_number)
{ uchar i;
for(i=0;i<newline_number;i++)
{
uart_byte_out(0x0d);
uart_byte_out(0x0a);
}
}
//=================================================================================================
// 數制轉換相關程序
//=================================================================================================
uchar change_hex_to_askii(uchar data_hex)//HEX轉換成ASKII,實參范圍:0-9、A-F
{ if(data_hex<=0x09) return(data_hex+0x30);
else return(data_hex+0x37);
}
//=================================================================================================
//18B20_________溫度
//=================================================================================================
//初始化函數
//=================================================================================================
void init_18b20 (void)
{ dq=1;
_nop_();
dq=0;
delay(90); //delay 530 uS
dq=1;
delay(6); //delay 100 uS
if(dq==0)
flag=1; //detect 1820 success!
else
flag=0; //detect 1820 fail!
delay(20);
dq=1;
}
//=================================================================================================
//讀2個字節
//=================================================================================================
uint read_word (void)
{
uchar i;
uint u=0;
for(i=0;i<16;i++)
{
dq=0;
u>>=1;
dq=1;
if(dq==1)
u|=0x8000;
delay (4);
}
return(u);
}
//=================================================================================================
//寫一個字節
//=================================================================================================
void write (uchar wr)
{
uchar i;
for (i=0;i<8;i++)
{
dq=0;
_nop_();
dq=wr&0x01;
delay(5); //delay 45 uS
dq=1;
wr>>=1;
}
}
//=================================================================================================
//讀取溫度
//=================================================================================================
float get_temp (void)
{
uint temp;
float tem;
init_18b20();
if (flag)
{ write (0xcc); //skip rom
write (0x44); //temp convert
init_18b20 ();
write (0xcc); //skip rom
write (0xbe); //read temp
temp=read_word(); //read
if(temp<0x8000)
tem=(float)temp*0.0625; //temperature>=0
else
tem=((float)(~temp)+0x01)*(-0.0625); //temperature< 0
}
return(tem);
}
//=================================================================================================
//延時函數-----------------------------------------------------------------------------------------
//=================================================================================================
void delay(unsigned int i)
{
while(i--);
}
//=================================================================================================
// T1中斷服務程序
//=================================================================================================
void T1_interrupt(void) interrupt 3
{
TH1=0x4c;//11.0592M晶振時T1定時時間長度為50毫秒
TL1=0x00;
t1_delay_time++;//在需要延時的地方清空并判斷該變量
}
//=================================================================================================
// end of the file
//=================================================================================================
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -