前言

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

同项目其他博文:

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

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

文章目录

目录

一 定时器中断

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

1.2 定时器0中断函数

1.3 定时器1中断函数

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

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

一 定时器中断

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

C51中的定时器和计数器是同一个硬件电路支持的,通过寄存器配置不同,就可以将他当做定时器 或者计数器使用。 确切的说,定时器和计数器区别是致使他们背后的计数存储器加1的信号不同。当配置为定时器使 用时,每经过1个机器周期,计数存储器的值就加1。而当配置为计数器时,每来一个负跳变信号 (信号从P3.4 或者P3.5引脚输入),就加1,以此达到计数的目的。 标准C51有2个定时器/计数器:T0和T1。他们的使用方法一致。C52相比C51多了一个T2

在下文的定时器函数中出现的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中断时间为0.5ms

/******************************************

*函数功能:实现舵机转现

*定时器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中断函数

将定时器1中断时间为50ms

/******************************************

*函数功能: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实现监测温湿度,并通过串口发送给主控系统

只有一根数据线DATA,51单片机发送序列指令给DHT11模块,模块一次完整的数据传输为40bit,高位先 出

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");

}

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

推荐链接

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: