⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mcs51-项目开发经典.c

📁 18b20底层子函数
💻 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 + -