免费开源51单片机个人课程设计--基于stc89c52及红外遥控的测温智能电风扇

这篇具有很好参考价值的文章主要介绍了免费开源51单片机个人课程设计--基于stc89c52及红外遥控的测温智能电风扇。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

51单片机个人课程设计–基于stc89c52及红外遥控的测温智能电风扇
个人学校的课程设计-智能电风扇,包含proteus原理图与源代码。
代码部分由我个人写的也有普中实验中的代码块。
3.1 硬件设计
主要器件:

  1. 单片机 AT89C52
  2. 红外接收 HS0038
  3. LCD1602
  4. 温度测量 DS18B20
  5. 驱动集成芯片 L298N
  6. 导线及各类电阻
  7. 红外遥控器
    功能设计:
    本智能风扇采用 stc89c52 为芯片,使用 lcd1602 作为信息输出设备,配
    备有红外遥控器,同时使用 DS18B02 作为温度收集元件,而使用 L298N 芯片
    来实现 pwm 控制电机不同转速。图 1 智能风扇仿真
    DS18B20图 3 DS18B20 温度测量模块
    DS18B20dq 为数据传输线。
    (3) HS0038 红外接收模块
    PROTEUS 中无 HS0038 元件,所以无仿真图,实物连接时连接 P3^2。
    HS0038 红外接收通过接收红外信号,信号经过芯片处理后即可判别选择不同功
    能。
    (4) L298N 电机驱动模块
    图 4 L298N 直流电机模块
    3.2 软件设计
    本程序设计采用多个头文件形式,使得程序结构层次分明,逻辑清晰,在
    后续的开发改进升级维护时更加容易。
    本程序分为多个功能程序单独文件编写调用形式,在很大程度上减少了主
    程序长度,代码逻辑清晰分明,程序分为多个模块,包含了 lcd1602 显示程序,
    temp 测温模块,红外遥控模块,及各个模块的初始化程序。在主程序中包含了
    一些定义与对各个模块函数的调用,以及风扇驱动与状态判断程序。
    (1) .红外接收模块:
    此模块使用了红外接收头 HS0038 作为硬件功能部分, 在主要程序上其连接
    P3^2 即 INT0 引脚,设定为下降沿触发,在接收到红外信号后进入中断程序,
    在中断程序中通过判断 P3^2 上电平持续时间来得到所需要的信息。在这里不得
    不提到红外协议中的 NEC 协议。载波 38khz 包含了逻辑 0 与逻辑 1。
    逻辑 1 共计 2.25ms 先是持续 0.56ms 的低电平然后是 1.69ms 的高电平。
    逻辑 0 共计 1.12ms,先为 0.56ms 的低电平然后是 0.56ms 的高电平。
    NEC 协议格式:
    P3.6
    P3.7 5 IN1
    7 IN2
    6 ENA
    OUT1 2
    OUT2 3
    11 ENB OUT3 13
    OUT4 14
    10 IN3
    12 IN4
    1 SENSA
    15 SENSB GND
    8
    VS
    4
    VCC
    9 U2
    L298
    +88.8图 5 红外 NEC 协议
    首先发送 9ms 的起始码然后是 4.5ms 的低电平,然后是 8 位用户码之后是
    8 位用户码的反码(主要用于校验是否出错) 然后是 8 位数据码之后是 8 位数
    据码的反码。需要注意的是数据从低位开始发送选择右移接收方式。
    (1) .红外接收程序;
    Ired.c 文件包含了红外接收的各种函数及中断程序
    /*******************************************************************************
  • 函 数 名 : ired_init
  • 函数功能 : 红外端口初始化函数,外部中断 0 配置
  • 输 入 : 无
  • 输 出 : 无
    /
    void ired_init(void)
    {
    IT0=1; //下降沿触发
    EX0=1; //打开中断 0 允许
    EA=1; //打开总中断
    IRED=1; //初始化端口
    }
    void ired() interrupt 0 //外部中断 0 服务函数
    {
    u8 ired_high_time=0;
    u16 time_cnt=0;
    u8 i=0,j=0;
    if(IRED0){
    time_cnt=1000;
    while((!IRED)&&(time_cnt))//等待引导信号 9ms 低电平结束,若超过 10ms 强制退

    {
    delay_10us(1);//延时约 10us
    time_cnt–;
    if(time_cnt
    0)return;
    }
    if(IRED)//引导信号 9ms 低电平已过,进入 4.5ms 高电平
    {
    time_cnt=500;
    while(IRED&&time_cnt)//等待引导信号 4.5ms 高电平结束,若超过 5ms 强制
    退出
    {
    delay_10us(1);
    time_cnt–;
    if(time_cnt0)return;
    }
    for(i=0;i<4;i++)//循环 4 次,读取 4 个字节数据
    {
    for(j=0;j<8;j++)//循环 8 次读取每位数据即一个字节
    {
    time_cnt=600;
    while((IRED
    0)&&time_cnt)//等待数据 1 或 0 前面的 0.56ms 结束,
    若超过 6ms 强制退出
    {
    delay_10us(1);
    time_cnt–;
    if(time_cnt==0)return;}
    time_cnt=20;
    while(IRED)//等待数据 1 或 0 后面的高电平结束,若超过 2ms 强制
    退出
    {
    delay_10us(10);//约 0.1ms
    ired_high_time++;
    if(ired_high_time>20)return;
    }
    gired_data[i]>>=1;//先读取的为低位,然后是高位
    if(ired_high_time>=8)//如果高电平时间大于 0.8ms,数据则为 1,
    否则为 0
    gired_data[i]|=0x80;
    ired_high_time=0;//重新清零,等待下一次计算时间
    }
    }
    }
    if(gired_data[2]!=~gired_data[3])//校验控制码与反码,错误则返回
    {
    for(i=0;i<4;i++)
    gired_data[i]=0;
    return;
    }
    }
    }
    (2) .lcd1602 显示模块;
    此功能模块硬件选择 lcd1602 作为硬件部分在硬件部分上 vo 位额外使用滑动变阻器使得能够
    自由调整亮度,软件部分包含了写命令与写字符部分,以次来实现写入字符与命令等。
    Lcdplus.c 文件包含 lcd1602 的各种函数包括写命令和写入字符功能等。
    #include"lcdplus.h"void Lcd1602_Delay1ms(int c) //误差 0us
    {
    u8 a,b;
    for (; c>0; c–)
    {
    for (b=199;b>0;b–)
    {
    for(a=1;a>0;a–);
    }
    }
    }
    void init()
    {
    wc51r(0x38);
    wc51r(0x0c);
    wc51r(0x06);
    }
    void fbusy()
    {
    P2=0Xff;RS=0;RW=1;
    E=0;
    E=1;
    while(P0&0X80){E=0;E=1;}
    }
    void wc51r(u8 j)
    {
    fbusy();
    E=0;RS=0;RW=0;
    E=1;P0=j;
    Lcd1602_Delay1ms(2);E=0;}
    void wc51ddr(u8 j)
    {
    fbusy();
    E=0;RS=1;RW=0;Lcd1602_Delay1ms(2);
    E=1;P0=j;E=0;
    }
    ( 3) .温度检测程序部分:
    硬件采用 DS18b20 进行温度的采集处理。 软件部分有初始化,写
    数据等函数, 对于各个函数在函数前有队函数的说明。 模块包含两个
    文件 temp.H 与 temp.C 文件
    temp.h 此文件包含了 temp.c 所需的各种宏定义等。
    /
  • 函数名 : Ds18b20Init
  • 函数功能 : 初始化
  • 输入 : 无
  • 输出 : 初始化成功返回 1,失败返回 0
    /
    unsigned char Ds18b20Init()
    {
    unsigned int i;
    DSPORT=0; //将总线拉低 480us~960us
    i=70;
    while(i–);//延时 642us
    DSPORT=1; //然后拉高总线,如果 DS18B20 做出反应会将在 15us~60us 后总线
    拉低
    i=0;
    while(DSPORT) //等待 DS18B20 拉低总线
    {i++;
    if(i>5000)//等待>5MS
    return 0;//初始化失败
    }
    return 1;//初始化成功
    }
    /
  • 函数名 : Ds18b20WriteByte
  • 函数功能 : 向 18B20 写入一个字节
  • 输入 : com
  • 输出 : 无
    /
    void Ds18b20WriteByte(unsigned char dat)
    {
    unsigned int i,j;
    for(j=0;j<8;j++)
    {
    DSPORT=0; //每写入一位数据之前先把总线拉低 1us
    i++;
    DSPORT=dat&0x01; //然后写入一个数据,从最低位开始
    i=6;
    while(i–); //延时 68us,持续时间最少 60us
    DSPORT=1; //然后释放总线,至少 1us 给总线恢复时间才能接着写入第二个数值
    dat>>=1;
    }
    }/
  • 函数名 : Ds18b20ReadByte
  • 函数功能 : 读取一个字节
  • 输入 : com
  • 输出 : 无
    **/
    unsigned char Ds18b20ReadByte()
    {
    unsigned char byte,bi;
    unsigned int i,j;
    for(j=8;j>0;j–)
    {
    DSPORT=0;//先将总线拉低 1us
    i++;
    DSPORT=1;//然后释放总线
    i++;
    i++;//延时 6us 等待数据稳定
    bi=DSPORT; //读取数据,从最低位开始读取
    /将 byte 左移一位,然后与上右移 7 位后的 bi,注意移动之后移掉那位补 0。 /
    byte=(byte>>1)|(bi<<7);
    i=4; //读取完之后等待 48us 再接着读取下一个数
    while(i–);
    }
    return byte;
    }
    /
  • 函数名 : Ds18b20ChangTemp
  • 函数功能 : 让 18b20 开始转换温度
  • 输入 : com
  • 输出 : 无*******************************************************************************/
    void Ds18b20ChangTemp()
    {
    Ds18b20Init();
    Delay1ms(1);
    Ds18b20WriteByte(0xcc); //跳过 ROM 操作命令
    Ds18b20WriteByte(0x44); //温度转换命令
    }
    /*******************************************************************************
  • 函数名 : Ds18b20ReadTempCom
  • 函数功能 : 发送读取温度命令
  • 输入 : com
  • 输出 : 无
    /
    void Ds18b20ReadTempCom()
    {
    Ds18b20Init();
    Delay1ms(1);
    Ds18b20WriteByte(0xcc); //跳过 ROM 操作命令
    Ds18b20WriteByte(0xbe); //发送读取温度命令
    }
    /
  • 函数名 : Ds18b20ReadTemp
  • 函数功能 : 读取温度
  • 输入 : com
  • 输出 : 无*******************************************************************************/
    short Ds18b20ReadTemp()
    {
    unsigned char temp=0;
    unsigned char tmh,tml;
    short tem;
    Ds18b20ChangTemp(); //先写入转换命令
    Ds18b20ReadTempCom(); //然后等待转换完后发送读取温度命令
    tml=Ds18b20ReadByte(); //读取温度值共 16 位,先读低字节
    tmh=Ds18b20ReadByte(); //再读高字节
    if(tmh>7)
    {
    tmh=~tmh;
    tml=~tml;
    temp=0;//温度为负
    }
    else
    {
    temp=1;//温度为正
    }
    tem=tmh; //获得高八位
    tem<<=8;
    tem|=tml;//获得底八位
    tem=(double)tem*0.625;//转换 放大 10 倍 精度 0.1
    if(temp)
    return tem; //返回温度值
    elsereturn -tem;
    }
    ( 4) 主程序部分:
    程序运行的主体部分,调用以上各文件中函数实现智能电风扇的功能。
    遥控器开关数据码: 44 开关启动 40 43 加数 46 47 减数 按下 eq07 后 设置定时时间按对应数字键。
    程序主体:
    #include “reg52.h”
    #include “public.h”
    #include “ired.h”
    #include “lcdplus.h”
    #include “temp.h”
    sbit PWM=P3^6;
    sbit PWM2=P3^7;
    unsigned char time;
    double count=0;
    int eq1;
    u8 gsmg_code[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
    0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
    u8 lcdnum[10]={‘0’,‘1’,‘2’,‘3’,‘4’,‘5’,‘6’,‘7’,‘8’,‘9’};
    u8 p={’ ‘};
    u8 E1,E2,E3,EQ;
    u8 blueh ;u8 bluel;
    u8 blue1,blue2,blue3;
    int red1,red2,red3;
    sbit led=P2^0;
    static unsigned char time1,time2,time3,time4;
    unsigned char num = 0;
    void delay(u8 c) //误差 0us 1ms 延时;{
    for (; c>0; c–);
    }
    u8 temp_buf[5];
    void Temp_DataPros()
    {
    short temp;
    temp=Ds18b20ReadTemp();
    if(temp<0)
    {
    temp=-temp;
    }
    temp_buf[0]=temp/100+0x30;
    temp_buf[1]=temp%100/10+0x30;
    temp_buf[2]=’.’;
    temp_buf[3]=temp%100%10+0x30;
    temp_buf[4]=’\0’; //显示检测的温度 xx.x
    }
    void tmtime() interrupt 1
    {
    TH0=0X3C;
    TL0=0XB0;
    num++;
    if(num20)
    {num = 0;
    time4=time4-1;if(IRED
    1)
    if(time40)
    {time4=9;time3=time3-1;
    if(time3
    0){time3=6;time2=time2-
    1;if(time2==0){time2=9;time1=time1-1;}}
    }
    }
    }
    *******************************************************************************/
  • 函数名 : time0()
  • 函数功能 : 电机转速 pwm 控制
  • 输入 : 无
  • 输出 : 无
    *******************************************************************************/
    void time0() interrupt 3
    {
    TR1=0; //设置定时器初值期间,关闭定时器
    TH1=(65536-10000)/256;
    TL1=(65536-10000)%256;
    TR1=1;
    PWM2=0;
    time++;
    if(time<count) //count 为占空比
    {
    PWM=1;
    //输出高电平
    }
    else
    PWM=0;if(time>=100)
    {
    time=0;
    }
    }
    *******************************************************************************/
  • 函数名 : fengshan()
  • 函数功能 : 红外遥控控制
  • 输入 : 无
  • 输出 : 无
    *******************************************************************************/
    void fengshan ()
    {
    unsigned char a;
    unsigned char b;
    a=gsmg_code[gired_data[2]/16];//将控制码高 4 位转换为段码
    b=gsmg_code[gired_data[2]%16];//将控制码低 4 位转换为段码
    switch(a)
    {
    case 0x66:
    {a=0x00;
    switch(b)
    {
    case 0x3f: //档位减小
    {
    red1=red1-1;b=0x00;count=count-10;
    gired_data[2]=0;
    if(red1<0){
    red1=0;count=0;
    }
    }break;
    case 0x7d: //时间减少
    {time2=time2-1;b=0x00;if(time20)
    {time2=9;time1=time1-1;}
    gired_data[2]=0;
    }break;
    case 0x4f: //档位加大
    {
    red1=red1+1;b=0x00;
    gired_data[2]=0;count=count+10;
    if(red1>9)
    {red1=0;count=0;
    }
    }break;
    case 0x07: //时间曾大
    { time2=time2+1;b=0x00;
    if(time2>=9){time2=0;time1=time1+1;}
    gired_data[2]=0;
    } break;
    case 0x6d: //风扇开关
    { TR1=~TR1;gired_data[2]=0;
    }break;
    case 0x66: //定时开关 默认关默认时间 10 分钟
    { TR0=~TR0;gired_data[2]=0;
    } break;}
    }break;
    case 0x3f:
    {
    if(b
    0x07)
    {
    E1=’ ';E2=‘O’,E3=‘N’;
    gired_data[2]=0;
    eq1=1;
    }
    if(b==0x39)
    {
    E1=‘O’;E2=‘F’,E3=‘F’; eq1=0;
    }
    } break;
    }
    }
    *******************************************************************************/
  • 函数名 : main
  • 函数功能 : 主函数
  • 输入 : 无
  • 输出 : 无
    *******************************************************************************/
    void main()
    {
    ired_init();//红外初始化
    P2=0X00;
    SP=0X50;
    init();blue1=blue2=blue3=0;//比分初始化
    time1=0,time2=9,time3=5;time4=9;
    EA=1;TMOD=0X01;TR0=1;ET0=1;
    TH0=0X3C;
    TL0=0XB0;
    P2=0X00;
    Ds18b20Init();
    TH1=(65536-100)/256;
    TL1=(65536-100)%256;
    ET1=1;
    TR1=0;//默认风扇开
    E1=‘O’;E2=‘F’,E3=‘F’;
    while(1)
    { TR1=0;
    Ds18b20ReadTempCom();
    Temp_DataPros();
    fengshan ();
    wc51r(0x80);
    wc51ddr(‘T’);wc51ddr(‘E’);wc51ddr(‘M’);wc51ddr(‘P’);wc51ddr(’:’);wc51ddr(
    temp_buf[0]);wc51ddr(temp_buf[1]);wc51ddr(temp_buf[2]);wc51ddr(temp_buf[3]);wc
    51ddr§; wc51ddr§;wc51ddr§;wc51ddr(‘K’);wc51ddr(lcdnum[red1]);
    wc51ddr§;wc51ddr§;
    wc51r(0xc0);wc51ddr(‘t’);wc51ddr(‘i’);wc51ddr(‘m’);wc51ddr(‘e’);wc51ddr(l
    cdnum[time1]);wc51ddr(lcdnum[time2]);wc51ddr(’:’);wc51ddr(lcdnum[time3]);wc51d
    dr(lcdnum[time4]);
    wc51ddr§;wc51ddr(‘E’);wc51ddr(‘Q’);wc51ddr§;wc51ddr(E1);wc51ddr(E2);wc51dd
    r(E3);
    if(eq11){TR1=1;
    if(temp_buf[0]
    ‘2’||temp_buf[0]‘3’||temp_buf[0]‘4’||temp_buf[0]‘5’
    ||temp_buf[0]
    ‘6’||temp_buf[0]‘7’||temp_buf[0]‘8’||temp_buf[0]‘9’)
    if(temp_buf[1]
    ‘5’||temp_buf[1]‘6’||temp_buf[1]‘7’||temp_buf[1]‘8’
    ||temp_buf[1]
    ‘9’)
    {red1=red1+1;count=count+10;
    if(red1>=9)
    red1=9;count=90;}
    else
    red1=count=0;
    }
    else
    TR1=1;
    } }

proteus仿真图:

免费开源51单片机个人课程设计--基于stc89c52及红外遥控的测温智能电风扇

完整代码:

包含多个头文件,各位在复现时可创建新文件然后复制代码即可。文章来源地址https://www.toymoban.com/news/detail-409852.html

1 完整代码
文件 main.C
//44 开关启动 40 43 加数 46 47 减数 按下 eq07 后 设置定时时间按对应数字键。
#include "reg52.h"
#include "public.h"
#include "ired.h"
#include "lcdplus.h"
#include "temp.h"
sbit PWM=P3^6;
sbit PWM2=P3^7;
unsigned char time;
double count=0;
int eq1;
u8 gsmg_code[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
u8 lcdnum[10]={'0','1','2','3','4','5','6','7','8','9'};
u8 p={' '};
u8 E1,E2,E3,EQ;
u8 blueh ;u8 bluel;
u8 blue1,blue2,blue3;
int red1,red2,red3;
sbit led=P2^0;static unsigned char time1,time2,time3,time4;
unsigned char num = 0;
void delay(u8 c) //误差 0us 1ms 延时;
{
for (; c>0; c--);
}
u8 temp_buf[5];
void Temp_DataPros()
{
short temp;
temp=Ds18b20ReadTemp();
if(temp<0)
{
temp=-temp;
}
temp_buf[0]=temp/100+0x30;
temp_buf[1]=temp%100/10+0x30;
temp_buf[2]='.';
temp_buf[3]=temp%100%10+0x30;
temp_buf[4]='\0'; //显示检测的温度 xx.x
}
void tmtime() interrupt 1
{
TH0=0X3C;
TL0=0XB0;num++;
if(num==20)
{
num = 0;
time4=time4-1;if(IRED==1)
if(time4==0)
{time4=9;time3=time3-1;
if(time3==0){time3=6;time2=time2-1;if(time2==0){time2=9;time1=time1-1;}}
}
}
}
void time0() interrupt 3
{
TR1=0; //设置定时器初值期间,关闭定时器
TH1=(65536-10000)/256;
TL1=(65536-10000)%256;
TR1=1;
PWM2=0;
time++;
if(time<count) //count 为占空比
{
PWM=1;
//输出高电平
}
else
PWM=0;
if(time>=100)
{
time=0;
}}
void fengshan ()
{
unsigned char a;
unsigned char b;
a=gsmg_code[gired_data[2]/16];//将控制码高 4 位转换为数码管段码
b=gsmg_code[gired_data[2]%16];//将控制码低 4 位转换为数码管段码
switch(a)
{
case 0x66:
{a=0x00;
switch(b)
{
case 0x3f: //档位减小
{
red1=red1-1;b=0x00;count=count-10;
gired_data[2]=0;
if(red1<0)
{
red1=0;count=0;
}
}break;
case 0x7d: //时间减少
{time2=time2-1;b=0x00;if(time2==0)
{time2=9;time1=time1-1;}
gired_data[2]=0;
}break;case 0x4f: //档位加大
{
red1=red1+1;b=0x00;
gired_data[2]=0;count=count+10;
if(red1>9)
{red1=0;count=0;
}
}break;
case 0x07: //时间曾大
{ time2=time2+1;b=0x00;
if(time2>=9){time2=0;time1=time1+1;}
gired_data[2]=0;
} break;
case 0x6d: //风扇开关
{ TR1=~TR1;gired_data[2]=0;
}break;
case 0x66: //定时开关 默认关默认时间 10 分钟
{ TR0=~TR0;gired_data[2]=0;
} break;
}
}break;
case 0x3f:
{
if(b==0x07)
{
E1=' ';E2='O',E3='N';
gired_data[2]=0;
eq1=1;}
if(b==0x39)
{
E1='O';E2='F',E3='F'; eq1=0;
}
} break;
}
}
void main()
{
ired_init();//红外初始化
P2=0X00;
SP=0X50;
init();
blue1=blue2=blue3=0;//比分初始化
time1=0,time2=9,time3=5;time4=9;
EA=1;TMOD=0X01;TR0=1;ET0=1;
TH0=0X3C;
TL0=0XB0;
P2=0X00;
Ds18b20Init();
TH1=(65536-100)/256;
TL1=(65536-100)%256;
ET1=1;
TR1=0;//默认风扇开
E1='O';E2='F',E3='F';
while(1){ TR1=0;
Ds18b20ReadTempCom();
Temp_DataPros();
fengshan ();
wc51r(0x80);
wc51ddr('T');wc51ddr('E');wc51ddr('M');wc51ddr('P');wc51ddr(':');wc51ddr(temp_buf[0]);w
c51ddr(temp_buf[1]);wc51ddr(temp_buf[2]);wc51ddr(temp_buf[3]);wc51ddr(p);
wc51ddr(p);wc51ddr(p);wc51ddr('K');wc51ddr(lcdnum[red1]); wc51ddr(p);wc51ddr(p);
wc51r(0xc0);wc51ddr('t');wc51ddr('i');wc51ddr('m');wc51ddr('e');wc51ddr(lcdnum[time1]);
wc51ddr(lcdnum[time2]);wc51ddr(':');wc51ddr(lcdnum[time3]);wc51ddr(lcdnum[time4]);
wc51ddr(p);wc51ddr('E');wc51ddr('Q');wc51ddr(p);wc51ddr(E1);wc51ddr(E2);wc51ddr(E3);
if(eq1==1)
{TR1=1;
if(temp_buf[0]=='2'||temp_buf[0]=='3'||temp_buf[0]=='4'||temp_buf[0]=='5'||temp_buf[0]=
='6'||temp_buf[0]=='7'||temp_buf[0]=='8'||temp_buf[0]=='9')
if(temp_buf[1]=='5'||temp_buf[1]=='6'||temp_buf[1]=='7'||temp_buf[1]=='8'||temp_buf[1]=
='9')
{red1=red1+1;count=count+10;
if(red1>=9)
red1=9;count=90;}
else
red1=count=0;
}
else
TR1=1;
}}
*******************************************************************************/
*******************************************************************************/
PUBLIC.H 文件
#ifndef _public_H
#define _public_H
#include "reg52.h"
typedef unsigned int u16; //对系统默认数据类型进行重定义
typedef unsigned char u8;
typedef unsigned long u32;
void delay_10us(u16 ten_us);
void delay_ms(u16 ms);
#endif
PUBLIC.C 文件
#include "public.h"
/*******************************************************************************
* 函 数 名 : delay_10us
* 函数功能 : 延时函数, ten_us=1 时,大约延时 10us
* 输 入 : ten_us
* 输 出 : 无
*******************************************************************************/
void delay_10us(u16 ten_us)
{
while(ten_us--);
}
/*******************************************************************************
* 函 数 名 : delay_ms
* 函数功能 : ms 延时函数, ms=1 时,大约延时 1ms
* 输 入 : ms: ms 延时时间
* 输 出 : 无
*******************************************************************************/
void delay_ms(u16 ms)
{
u16 i,j;
for(i=ms;i>0;i--)
for(j=110;j>0;j--);
}*******************************************************************************/
*******************************************************************************/
Ired.c 文件
#include "ired.h"
u8 gired_data[4];//存储 4 个字节接收码(地址码+地址反码+控制码+控制反码)
/*******************************************************************************
* 函 数 名 : ired_init
* 函数功能 : 红外端口初始化函数,外部中断 0 配置
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void ired_init(void)
{
IT0=1; //下降沿触发
EX0=1; //打开中断 0 允许
EA=1; //打开总中断
IRED=1; //初始化端口
}
void ired() interrupt 0 //外部中断 0 服务函数
{
u8 ired_high_time=0;
u16 time_cnt=0;
u8 i=0,j=0;
if(IRED==0)
{
time_cnt=1000;
while((!IRED)&&(time_cnt))//等待引导信号 9ms 低电平结束,若超过 10ms 强制退
出
{
delay_10us(1);//延时约 10us
time_cnt--;
if(time_cnt==0)return;
}
if(IRED)//引导信号 9ms 低电平已过,进入 4.5ms 高电平
{
time_cnt=500;
while(IRED&&time_cnt)//等待引导信号 4.5ms 高电平结束,若超过 5ms 强制
退出
{delay_10us(1);
time_cnt--;
if(time_cnt==0)return;
}
for(i=0;i<4;i++)//循环 4 次,读取 4 个字节数据
{
for(j=0;j<8;j++)//循环 8 次读取每位数据即一个字节
{
time_cnt=600;
while((IRED==0)&&time_cnt)//等待数据 1 或 0 前面的 0.56ms 结束,
若超过 6ms 强制退出
{
delay_10us(1);
time_cnt--;
if(time_cnt==0)return;
}
time_cnt=20;
while(IRED)//等待数据 1 或 0 后面的高电平结束,若超过 2ms 强制
退出
{
delay_10us(10);//约 0.1ms
ired_high_time++;
if(ired_high_time>20)return;
}
gired_data[i]>>=1;//先读取的为低位,然后是高位
if(ired_high_time>=8)//如果高电平时间大于 0.8ms,数据则为 1,否
则为 0
gired_data[i]|=0x80;
ired_high_time=0;//重新清零,等待下一次计算时间
}
}
}
if(gired_data[2]!=~gired_data[3])//校验控制码与反码,错误则返回
{
for(i=0;i<4;i++)
gired_data[i]=0;
return;
}
}
}
*******************************************************************************/
*******************************************************************************/
Ired.h 文件#ifndef _ired_H
#define _ired_H
#include "public.h"
//管脚定义
sbit IRED=P3^2;
//声明变量
extern u8 gired_data[4];
//函数声明
void ired_init(void);
#endif
Lcdplus.H 文件
#ifndef _lcdplus_H
#define _lcdplus_H
#include "public.h"
sbit RS = P2^6;
sbit RW = P2^5;
sbit E = P2^7;
void init(void);
void wc51r(u8 i);
void wc51ddr(u8 i);
void fbust(void);
void Lcd1602_Delay1ms(u8 c);
#endif
*******************************************************************************/
*******************************************************************************/
Lcdplus.C 文件
#include"lcdplus.h"
void Lcd1602_Delay1ms(int c) //误差 0us
{
u8 a,b;
for (; c>0; c--)
{
for (b=199;b>0;b--)
{
for(a=1;a>0;a--);
}}
}
void init()
{
wc51r(0x38);
wc51r(0x0c);
wc51r(0x06);
}
void fbusy()
{
P2=0Xff;RS=0;RW=1;
E=0;
E=1;
while(P0&0X80){E=0;E=1;}
}
void wc51r(u8 j)
{
fbusy();
E=0;RS=0;RW=0;
E=1;P0=j;
Lcd1602_Delay1ms(2);E=0;
}
void wc51ddr(u8 j)
{
fbusy();
E=0;RS=1;RW=0;Lcd1602_Delay1ms(2);
E=1;P0=j;E=0;
}
*******************************************************************************/
*******************************************************************************/
Temp.c 文件
#include "temp.h"
/*******************************************************************************
* 函数名 : Delay1ms
* 函数功能 : 延时函数
* 输入 : 无
* 输出 : 无
*******************************************************************************/
void Delay1ms(unsigned int y)
{
unsigned int x;for(y;y>0;y--)
for(x=110;x>0;x--);
}
/*******************************************************************************
* 函数名 : Ds18b20Init
* 函数功能 : 初始化
* 输入 : 无
* 输出 : 初始化成功返回 1,失败返回 0
*******************************************************************************/
unsigned char Ds18b20Init()
{
unsigned int i;
DSPORT=0; //将总线拉低 480us~960us
i=70;
while(i--);//延时 642us
DSPORT=1; //然后拉高总线,如果 DS18B20 做出反应会将在 15us~60us 后
总线拉低
i=0;
while(DSPORT) //等待 DS18B20 拉低总线
{
i++;
if(i>5000)//等待>5MS
return 0;//初始化失败
}
return 1;//初始化成功
}
/*******************************************************************************
* 函数名 : Ds18b20WriteByte
* 函数功能 : 向 18B20 写入一个字节
* 输入 : com
* 输出 : 无
*******************************************************************************/
void Ds18b20WriteByte(unsigned char dat)
{
unsigned int i,j;
for(j=0;j<8;j++)
{
DSPORT=0; //每写入一位数据之前先把总线拉低 1us
i++;
DSPORT=dat&0x01; //然后写入一个数据,从最低位开始
i=6;while(i--); //延时 68us,持续时间最少 60us
DSPORT=1; //然后释放总线,至少 1us 给总线恢复时间才能接着写入第二个数
值
dat>>=1;
}
}
/*******************************************************************************
* 函数名 : Ds18b20ReadByte
* 函数功能 : 读取一个字节
* 输入 : com
* 输出 : 无
*******************************************************************************/
unsigned char Ds18b20ReadByte()
{
unsigned char byte,bi;
unsigned int i,j;
for(j=8;j>0;j--)
{
DSPORT=0;//先将总线拉低 1us
i++;
DSPORT=1;//然后释放总线
i++;
i++;//延时 6us 等待数据稳定
bi=DSPORT; //读取数据,从最低位开始读取
/*将 byte 左移一位,然后与上右移 7 位后的 bi,注意移动之后移掉那位补 0。 */
byte=(byte>>1)|(bi<<7);
i=4; //读取完之后等待 48us 再接着读取下一个数
while(i--);
}
return byte;
}
/*******************************************************************************
* 函数名 : Ds18b20ChangTemp
* 函数功能 : 让 18b20 开始转换温度
* 输入 : com
* 输出 : 无
*******************************************************************************/
void Ds18b20ChangTemp()
{
Ds18b20Init();
Delay1ms(1);Ds18b20WriteByte(0xcc); //跳过 ROM 操作命令
Ds18b20WriteByte(0x44); //温度转换命令
}
/*******************************************************************************
* 函数名 : Ds18b20ReadTempCom
* 函数功能 : 发送读取温度命令
* 输入 : com
* 输出 : 无
*******************************************************************************/
void Ds18b20ReadTempCom()
{
Ds18b20Init();
Delay1ms(1);
Ds18b20WriteByte(0xcc); //跳过 ROM 操作命令
Ds18b20WriteByte(0xbe); //发送读取温度命令
}
/*******************************************************************************
* 函数名 : Ds18b20ReadTemp
* 函数功能 : 读取温度
* 输入 : com
* 输出 : 无
*******************************************************************************/
short Ds18b20ReadTemp()
{
unsigned char temp=0;
unsigned char tmh,tml;
short tem;
Ds18b20ChangTemp(); //先写入转换命令
Ds18b20ReadTempCom(); //然后等待转换完后发送读取温度命令
tml=Ds18b20ReadByte(); //读取温度值共 16 位,先读低字节
tmh=Ds18b20ReadByte(); //再读高字节
if(tmh>7)
{
tmh=~tmh;
tml=~tml;
temp=0;//温度为负
}else
{
temp=1;//温度为正
}
tem=tmh; //获得高八位
tem<<=8;
tem|=tml;//获得底八位
tem=(double)tem*0.625;//转换 放大 10 倍 精度 0.1
if(temp)
return tem; //返回温度值
else
return -tem;
}
*******************************************************************************/
*******************************************************************************/
Temp.h 文件
#ifndef _temp_H_
#define _temp_H_
#include "public.h"
sbit DSPORT=P1^7;
void Delay1ms(unsigned int );
unsigned char Ds18b20Init();
void Ds18b20WriteByte(unsigned char com);
unsigned char Ds18b20ReadByte();
void Ds18b20ChangTemp();
void Ds18b20ReadTempCom();
short Ds18b20ReadTemp();
#endif

到了这里,关于免费开源51单片机个人课程设计--基于stc89c52及红外遥控的测温智能电风扇的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 51单片机步进电机角度控制详解(免费提供代码+仿真)

    我个人认为,步进电机的基本原理和介绍看看其他博主的介绍就好了。我比较希望讲一下我对步进电机的关于自己一种理解方式,可能与真正步进电机的原理差的有点大。下面还是给一下我推荐的一些博主对步进电机的介绍文章。 百度步进电机链接 步进电机驱动及原理—s

    2023年04月18日
    浏览(45)
  • 基于51单片机的数字温度计【开源】

    (1)温度实时显示(LCD2864) (2)温度上限下线调节 (3)万年历功能 (4)超温报警 (5)年月日时分秒可调节 (6)温度测量精度0.0625℃ (7)节日自动判定 STC89c52,DS18B20,DS1302,按键模块。LCD12864 main.c LCD12864.c ( 主要一些延时和LCD12864的驱动) LCD12864.h (主要一些函数的声

    2024年02月10日
    浏览(52)
  • 51单片机项目(9)——基于51单片机的电子琴设计

    简易电子琴设计设计内容: 1.用矩阵键盘代表琴键,至少能弹出8个音符,分别是:音符1.23.4.,5,6,  2.键按下的时间长短表征节拍的长短,用蜂鸣器发出声音 3.数码管显示出当前音符 4.音量可调 (代码及其工程文件放在最后) 电路图如下: 51单片机电子琴是一种基于51单片机(

    2024年02月09日
    浏览(49)
  • 51单片机:设计一单片机双机通信电路

    鱼弦:CSDN内容合伙人、CSDN新星导师、全栈领域优质创作者 、51CTO(Top红人+专家博主) 、github开源爱好者(go-zero源码二次开发、游戏后端架构 https://github.com/Peakchen) 设计一单片机双机通信电路。要求编程实现:甲单片机系统中的按键可以控制乙单片机系统中的数码管(MPX8)动

    2024年02月20日
    浏览(54)
  • 单片机设计基于51单片机的智能风扇控制系统设计与实现

      我们常见的电风扇一般只有四、五个风速档,用的是人工开关,而且并不是每个人家里都会有空调,或者在一些小型的工厂或者一些小型加工厂,这些地方都可能没有配备大型的中央空调系统这些东西,所以这些东西往往都会采用风扇这种小成本的东西来代替,但是不清楚

    2024年02月03日
    浏览(69)
  • 51单片机迷宫小车的设计

    本次迷宫小车设计,使用C51进行编程,实现小车的功能。本次完成的小车功能可分为两大模块,分别是硬件功能和软件功能。 总共有两部分来写,分别为: 硬件功能上实现了小车的底层驱动,如:红外检测,控制电机使小车进行直行,转弯,自动修正、红外的分时检测,发

    2024年02月06日
    浏览(52)
  • 脉冲计数器 单片机课程设计

    利用单片机对单片机实验箱的按键S29发出的负脉冲个数进行加/减计数,计数结果(0~255)在8个LED数码管中的3位进行显示(使用8255进行动态驱动)。 利用拨动开关S26来选择计数的方式。S26接高电平时,进行加法计数。S26接低电平时,进行减法计数;利用拨动开关S27控制计数

    2024年02月04日
    浏览(46)
  • 单片机课程设计波形发生器

    怎么说呢,前面半个月被这个单片机课程设计搞得焦头烂额的,再加上运气属实有点“好”,就脾气有点“暴躁”,好的,也就骂了半天的脏话。有一说一,没有素质确实舒服。 好了,事情目前是过去了,那就好好回顾一下遇到的问题,以及找到了怎样的解决方案,和最后仍

    2024年02月09日
    浏览(52)
  • 基于51单片机的51单片机的LED彩灯霓虹灯控制器(心形流水灯)设计

    基于51单片机的51单片机的LED彩灯霓虹灯控制器(心形流水灯)设计 必看!!视频讲解 基于51单片机的LED彩灯霓虹灯心形流水灯设计 仿真图:proteus8.9以上 程序代码:KEIL4/KEIL5 原理图:AD 设计编号:A0005 结合实际情况,基于51单片机设计一个LED彩灯控制器设计。该系统应满足的功能要

    2024年02月02日
    浏览(50)
  • [免费开源]基于freescale单片机的心电信号采集与处理

     本文的工程可访问:https://gitee.com/pidanQwQ/dsp    (包含两套不同的方案,可自行下载对比)  或者在CSDN中(仅一套):【免费】基于Freescal单片机的心电信号采集与处理资源-CSDN文库 功能要求: ⑴实现ADS1292获取心电信号原始数据,并能通过串口或其他接口传输到PC电脑; ⑵实现

    2024年01月21日
    浏览(78)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包