第二章 智能家居子系统——C51单片机 配置波特率115200

前言

本章为智能家居项目的第二章,本章主要写51单片机的定时器timer,串口UART,中断,外接模块DHT11

同项目其他博文:

项目的概述链接:Linux智能家居项目概述-CSDN博客

第一章 主控代码开发链接:第一章 智能家居(主控)的开发及代码分析-CSDN博客

文章目录

目录

前言

文章目录

一 定时器中断

1.1 定时器0和定时器1初始化

1.2 定时器0中断函数

1.3 定时器1中断函数

二 串口波特率配置及中断115200

三 DHT11实现监测温湿度,并通过串口发送给主控系统


一 定时器中断

1.1 定时器0和定时器1初始化

在下文的定时器函数中出现的PT0和PT1为中断优先级控制位

定时器0初始化(定时器0用于舵机控制)

void Time0Init()
{
	TMOD = 0x01;
	TL0=0x33;   	//装初值,0.5ms
	TH0=0xFE;
	TR0 = 1;  		//开始数数
	TF0 = 0;
	ET0 = 0; 			//关定时器0中断
	EA = 1;    		//打开总中断
	PT0 =1;				//设定时器T0为高优先级中断
}

PT0:T0中断优先级控制位。PT0=1,设定定时器T0为高优先级中断;PT0=0,设定时器T0为低优先级中断。

定时器1初始化(定时器1 用于定时发送数据)

void Timer1Init(void)		//设置定时器1
{
	AUXR &= 0xBF;		
	TMOD &= 0x0F;			//高位清0 低位不变
	TMOD |= 0x10;			//高位置1 低位不变
	TL1 = 0x00;				//装初值,定时50ms
	TH1 = 0x4C;		
	TF1 = 0;					//开始定时
	TR1 = 1;					//TRTF 开始数数
	ET1 = 1;   				//打开定时器1中断
	EA  = 1;					//打开总中断
	PT1 = 0;					//设定时器T1为低优先级中断
}

PT1:T1中断优先级控制位。PT1=1,设定定时器T1为高优先级中断;PT1=0,设定定时器T1为低优先级中断。

1.2 定时器0中断函数

/******************************************
	*函数功能:实现舵机转现
	*定时器0中断
*****************************************/
void Time0Handler() interrupt 1
{
	cnt++; 				//用于调节IO的输出频率,用于舵机
	LED_count++;
	TL0=0x33;           // 重装初值,设置中断时间为0.5ms
	TH0=0xFE;
	if(cnt < jd){       //jd = 0时舵机角度为0度,jd = 5舵机角度为180度
		sg90 = 1;
	}else{
		sg90 = 0;
	}
	if(cnt == 40){
		cnt = 0; 
		sg90 = 1;
	}
}

1.3 定时器1中断函数

/******************************************
	*函数功能:1s 发送温湿度给主机
	*定时器1中断
*****************************************/

void Time1Handler() interrupt 3
{	
	timer1_conut++;
	TL1 = 0x00;		                //装低八位初值 50ms
	TH1 = 0x4C;		                //装高八位初值
	
	  if(timer1_conut == 20){       //计时一秒时,发一次温湿度数据
			ET0 = 0;                //定时器1断开,等待串口将温湿度数据发送完毕
			timer1_conut = 0;
			get_wenshidu();
			ET0 = 1;	            //定时器1继续计时
	}
}

二 串口波特率配置及中断115200

由于使用使用软件不能直接配置出115200的波特率,然后上网查资料,最后使用定时器2和波特率发生器后完成串口的配置。

//设置串口波特率为115200
void init_com( void ) 
{ 
     SCON = 0x50; //串口工作方式1,8位UART,波特率可变  
     TH2 = 0xFF;           
     TL2 = 0xFD;    //波特率:115200 晶振=11.0592MHz 
     RCAP2H = 0xFF;   
     RCAP2L = 0xFD; 16位自动再装入值
		/*****************/
     TCLK = 1;   
     RCLK = 1;   
     C_T2 = 0;   
     EXEN2 = 0; //波特率发生器工作方式
		/*****************/
     TR2 = 1 ;    //定时器2开始
	 EA = 1;    //总中断
	 ES = 1;      //串口中断标志位
	 PS = 1;      //设置串口优先级为最高
}

当时主控开发板的波特率为115200,然后51单片机的波特率为9600,那会我还不清楚主控的波特率是多少,就以为默认为9600,然后一通信,好家伙,数据有时对有时不对,还以为代码逻辑出了问题,改了好久好久

/* 串口中断 */
void Uart_Handler() interrupt 4{
static int i = 0;			//
char tmp;
	if(RI){  //收到数据RI置1
		RI=0;
		tmp = SBUF;
		if(tmp == 'M'){
			i=0;
		} 
			cmd[i] = tmp;
			i++;
			if(cmd[0] == 'M'){
				switch (cmd[1]){
					case'1':								  //打开舵机中断
						LED1 = OFF;
						Fa_msg("开舵机中断");
						//get_wenshidu();
						ET0 = 1;   							//打开定时器0中断			
						 break;
					case'2':									//关闭舵机中断
						LED1 = ON;
						Fa_msg("关舵机中断");
						ET0 = 0;   //关中断
						break;
					case'3'://  							//打开垃圾桶
						Fa_msg("close ash-bin");
						jd = 1;
						break;
					case'4':									//打开垃圾桶
						Fa_msg("open ash-bin");
						jd = 5;
						break;
					case'5'://ding
						Fa_msg("开始发送温湿度");
						ET1 = 0;
						break;
					case'6'://ding
						Fa_msg("停止发送温湿度");
						ET1 = 1;
						break;
					}	
				}	
		if(i == 12){
			memset(cmd,'\0',SIZE);
			i = 0;
		}
	}
}

上述代码为串口UART中断的代码

串口没有数据时,程序正常执行,当串口接收到数据时,串口中断,程序进入串口中断函数,创建cmd[ ]数组接收数据而后判断,如果第一个数据为M时,者证明收到需要的数据,然后判断M的下一位数据cmd[1],如果判断指令存在,则执行相对应的指令

三 DHT11实现监测温湿度,并通过串口发送给主控系统

51单片机发送字符串

void SendByte(char msg){//发送字节
	 SBUF = msg;
	 while(TI == 0);
	 TI=0;
	
}

void Fa_msg(char *p){//发送字符串
	while(*p! = '\0'){
	SendByte(*p);
	p++;
	}
}

将从硬件获取到的温湿度通过串口发送给主控(定时器计算每秒发送一次 )

//将获取到的温湿度值进行赋值,以便利用串口将数据发到主机
void build_data(){ 
	 shidu[0] = 'H';
	 shidu[1] = datas[0]/10 + 0x30;
	 shidu[2] = datas[0]%10 + 0x30;
	 shidu[3] = '.';
	 shidu[4] = datas[1]/10 + 0x30;
	 shidu[5] = datas[1]%10 + 0x30;
	 shidu[6] = '%';
	 shidu[7] = '\0';
	 
	 wendu[0] = 'T';
	 wendu[1] = datas[2]/10 + 0x30;
	 wendu[2] = datas[2]%10 + 0x30;
	 wendu[3] = '.';
	 wendu[4] = datas[3]/10 + 0x30;
	 wendu[5] = datas[3]%10 + 0x30;
	 wendu[6] = 'C';
	 wendu[7] = '\0';
}

//将温湿度通过串口发送给主机
void get_wenshidu(){
		Read_Data_Form_DHT();   //获取硬件的温度,并存进数组中
		build_data();
		Fa_msg(wendu);          //发送温度
		Fa_msg("\r\n");
		//Delay1ms(); 
		Fa_msg(shidu);          //发送湿度
		Fa_msg("\r\n");
}

 这篇文章没用具体说明每个模块的具体实现,如需要看详解,可以看主页,或找我要笔记

你可能感兴趣的:(Linux智能家居,51单片机,c语言,笔记,学习)