📄 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 + -