基于VS2017和单片机 C#串口通信(时间、温度)

该博客介绍如何使用VS2017进行C#串口通信,与51单片机AT89S52实现DS1302时钟和DS18B20温度传感器的数据交互。下位机程序负责读取时钟和温度信息并发送至上位机,上位机程序将在后续博客中分享。代码包含DS1302的调时功能和两种工作模式选择。
摘要由CSDN通过智能技术生成

选用单片机芯片51单片机 AT89S52
函数功能:串口通信下位机程序,用来读取DS1302时钟和DS18B20温度数据,并发给上位机用于显示。
注意:代码里有DS1302调时和两种工作方式的代码,可根据需要更改,满足自己需求。(现在是:掉电后时钟继续走,每次上电都初始化时间)。
C#上位机程序见下个博客。

/*******************************************************************
函数功能:串口通信下位机程序,用来读取DS1302时钟和DS18B20温度数据,
并发给上位机用于显示。
作者:Crazy Wind      
日期:2020.12.11
version:1.0.0
日期:2020.12.01
version:1.1.0
*增加了液晶显示模块代码
********************************************************************/
#include "reg52.h"
#include "intrins.h"
#define uchar unsigned char
#define uint unsigned int

/*****************************************************
函数功能:ms延时
******************************************************/
void delayms(uint ms) 
{
   
	uchar i,j;
    for(i=0;i<ms;i++)
    {
   
        for(j=115;j>0;j--);
    }
}

/*****************************************************
函数功能:微秒延时
入口参数:n
*****************************************************/ 
void delayus(uchar n)
{
   
 uchar i;
 for(i=0;i<n;i++);
}

/************************************************************************/
/*****************************DS1302操作程序*****************************/
/************************************************************************/
sbit SCLK=P1^0;   //位定义1302芯片的接口,时钟输出端口定义在P1.0引脚
sbit DATA=P1^1;   //位定义1302芯片的接口,数据输出端定义在P1.1引脚
sbit RST=P1^2;    //位定义1302芯片的接口,复位端口定义在P1.2引脚
uchar sec=0,min=13,hour=18,day=1,month=12,year=20,week=2;		//定义时间
/*****************************************************
函数功能:向1302写一个字节数据
入口参数:dat
*****************************************************/
void Write1302(uchar dat)
{
   
	uchar j; 
	SCLK=0;            //拉低SCLK,为脉冲上升沿写入数据做好准备
	delayus(2);        //稍微等待,使硬件做好准备
	for(j=0;j<8;j++)   //连续写8个二进制位数据
	{
   
		DATA=dat&0x01; //取出dat的第0位数据写入1302  低位在前,高位在后
		delayus(2);    //稍微等待,使硬件做好准备
		SCLK=1;        //!!上升沿!!写入数据
		delayus(2);    //稍微等待,使硬件做好准备
		SCLK=0;        //重新拉低SCLK,形成脉冲
		dat>>=1;       //将dat的各数据位右移1位,准备写入下一个数据位
	}	
}

/*****************************************************
函数功能:向1302写命令和一个字节数据
入口参数:Cmd:命令  dat:数据
*****************************************************/
void WriteSet1302(uchar Cmd,uchar dat)
{
   	  
	RST=0;           //禁止数据传递
    SCLK=0;          //确保写数居前SCLK被拉低
	RST=1;           //启动数据传输
	delayus(2);      //稍微等待,使硬件做好准备
	Write1302(Cmd);  //写入命令字
	Write1302(dat);  //写数据
	SCLK=1;          //将时钟电平置于高电平状态
	RST=0;           //禁止数据传递
}

/*****************************************************
函数功能:从1302读一个字节数据
*****************************************************/ 
uchar Read1302(void)
{
   
	uchar i,dat;
	delayus(2);        //稍微等待,使硬件做好准备
	for(i=0;i<8;i++)   //连续读8个二进制位数据
	{
   	 dat>>=1;
		 if(DATA==1)   //如果读出的数据是1
		 dat|=0x80;    //将1取出,写在dat的最高位
		 SCLK=1;       //将SCLK置于高电平,为下降沿读出
		 delayus(2);   //稍微等待
		 SCLK=0;       //!!下降沿!!读出数据
		 delayus(2);   //稍微等待
	}	 
	return dat;        //将读出的数据返回
}  

/*****************************************************
函数功能:向1302写命令和从1302读一个字节数据
入口参数:Cmd:命令
*****************************************************/
uchar ReadSet1302(uchar Cmd)
{
   
	uchar dat;
	RST=0;               //拉低RST
	SCLK=0;              //确保写数居前SCLK被拉低
	RST=1;               //启动数据传输
	Write1302(Cmd);      //写入命令字
	dat=Read1302();      //读出数据
	SCLK=1;              //将时钟电平置于已知状态
	RST=0;               //禁止数据传递
	return dat;          //将读出的数据返回
}

/*****************************************************
函数功能:初始化DS1302
*****************************************************/
void Init_DS1302(void)
{
   
	/*******掉电后时钟继续走,只初始化一次时间*******/
	/*
	uchar flag;
	flag=ReadSet1302(0x81);		//读秒寄存器,81H
	if(flag&0x80)				//读出CH,判断时钟芯片是否关闭(CH=0时时钟开始运行)
	{
		WriteSet1302(0x8E,0x00);                 	  //写寄存器命令,WP写入不保护指令(WP=0,允许写操作) 
	   	WriteSet1302(0x80,((sec/10)<<4|(sec%10)));    //写秒寄存器命令,写入秒的初始值
		WriteSet1302(0x82,((min/10)<<4|(min%10)));    //写分寄存器命令,写入分的初始值
		WriteSet1302(0x84,((hour/10)<<4|(hour%10)));  //写时寄存器命令,写入时的初始值
		WriteSet1302(0x86,((day/10)<<4|(day%10)));    //写日寄存器命令,写入日的初始值
		WriteSet1302(0x88,((month/10)<<4|(month%10)));//写月寄存器命令,写入月的初始值
		WriteSet1302(0x8c,((year/10)<<4|(year%10)));  //写年寄存器命令,写入年的初始值
		WriteSet1302(0x8a,(week%10)); 				  //写星期寄存器命令,写入星期的初始值
		WriteSet1302(0x90,0xa5);                 	  //打开充电功能 选择2K电阻充电方式
		WriteSet1302(0x8E,0x80);			     	  //写寄存器命令,写入保护指令(WP=1,禁止写操作)
	}
	 */
	/*******掉电后时钟继续走,每次上电都初始化时间*******/
	
	WriteSet1302(0x8E,0x00);                 	      //写寄存器命令,WP写入不保护指令(WP=0,允许写操作) 
   	WriteSet1302(0x80,((sec/10)<<4|(sec%10)));        //写秒寄存器命令,写入秒的初始值
	WriteSet1302(0x82,((min/10)<<4|(min%10)));        //写分寄存器命令,写入分的初始值
	WriteSet1302(0x84,((hour/10)<<4|(hour%10)));      //写时寄存器命令,写入时的初始值
	WriteSet1302(0x86,((day/10)<<4|(day%10)));        //写日寄存器命令,写入日的初始值
	WriteSet1302(0x88,((month/10)<<4|(month%10)));    //写月寄存器命令,写入月的初始值
	WriteSet1302(0x8c,((year/10
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值