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

包含多个头文件,各位在复现时可创建新文件然后复制代码即可。
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
我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co
我将应用程序升级到Rails4,一切正常。我可以登录并转到我的编辑页面。也更新了观点。使用标准View时,用户会更新。但是当我添加例如字段:name时,它不会在表单中更新。使用devise3.1.1和gem'protected_attributes'我需要在设备或数据库上运行某种更新命令吗?我也搜索过这个地方,找到了许多不同的解决方案,但没有一个会更新我的用户字段。我没有添加任何自定义字段。 最佳答案 如果您想允许额外的参数,您可以在ApplicationController中使用beforefilter,因为Rails4将参数
说在前面这部分我本来是合为一篇来写的,因为目的是一样的,都是通过独立按键来控制LED闪灭本质上是起到开关的作用,即调用函数和中断函数。但是写一篇太累了,我还是决定分为两篇写,这篇是调用函数篇。在本篇中你主要看到这些东西!!!1.调用函数的方法(主要讲语法和格式)2.独立按键如何控制LED亮灭3.程序中的一些细节(软件消抖等)1.调用函数的方法思路还是比较清晰地,就是通过按下按键来控制LED闪灭,即每按下一次,LED取反一次。重要的是,把按键与LED联系在一起。我打算用K1来作为开关,看了一下开发板原理图,K1连接的是单片机的P31口,当按下K1时,P31是与GND相连的,也就是说,当我按下去时
目录前言滤波电路科普主要分类实际情况单位的概念常用评价参数函数型滤波器简单分析滤波电路构成低通滤波器RC低通滤波器RL低通滤波器高通滤波器RC高通滤波器RL高通滤波器部分摘自《LC滤波器设计与制作》,侵权删。前言最近需要学习放大电路和滤波电路,但是由于只在之前做音乐频谱分析仪的时候简单了解过一点点运放,所以也是相当从零开始学习了。滤波电路科普主要分类滤波器:主要是从不同频率的成分中提取出特定频率的信号。有源滤波器:由RC元件与运算放大器组成的滤波器。可滤除某一次或多次谐波,最普通易于采用的无源滤波器结构是将电感与电容串联,可对主要次谐波(3、5、7)构成低阻抗旁路。无源滤波器:无源滤波器,又称
项目介绍随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱小学生兴趣延时班预约小程序的设计与开发被用户普遍使用,为方便用户能够可以随时进行小学生兴趣延时班预约小程序的设计与开发的数据信息管理,特开发了小程序的设计与开发的管理系统。小学生兴趣延时班预约小程序的设计与开发的开发利用现有的成熟技术参考,以源代码为模板,分析功能调整与小学生兴趣延时班预约小程序的设计与开发的实际需求相结合,讨论了小学生兴趣延时班预约小程序的设计与开发的使用。开发环境开发说明:前端使用微信微信小程序开发工具:后端使用ssm:VU
我在我的项目中有一个用户和一个管理员角色。我使用Devise创建了身份验证。在我的管理员角色中,我没有任何确认。在我的用户模型中,我有以下内容:devise:database_authenticatable,:confirmable,:recoverable,:rememberable,:trackable,:validatable,:timeoutable,:registerable#Setupaccessible(orprotected)attributesforyourmodelattr_accessible:email,:username,:prename,:surname,:
我正在尝试创建密码规则来设计可恢复的密码更改。我通过passwords_controller.rb做了一个父类(superclass),但我需要在应用规则之前检查用户角色,但我所拥有的只是reset_password_token。 最佳答案 假设您的模型是用户:User.with_reset_password_token(your_token_here)Source 关于ruby-on-rails-设计通过reset_password_token获取用户,我们在StackOverflow
我已经使用Apartment设置了一个Rails5应用程序(1.2.0)和Devise(4.2.0)。由于某些DDNS问题,应用只能在app.myapp.com下访问(请注意子域app)。myapp.com重定向到app.myapp.com。我的用例是每个注册该应用的用户(租户)都应该通过他们的子域(例如tenant.myapp.com)访问他们的特定数据。用户不应限定在其子域内。基本上应该可以从任何子域登录。重定向到租户的正确子域由ApplicationController处理。根据Devise标准,登录页面位于app.myapp.com/users/sign_in。这就是问题开始的
我在关注RyanbatesRailsCast的devise和omniauth(第235集-devise-and-omniauth-revised)。当我尝试使用Twitter登录时,标题中不断出现错误。defself.new_with_session(params,session)ifsession["devise.user_attributes"]new(session["devise.user_attributes"],without_protection:true)do|user|user.attributes=paramsuser.valid?end完整跟踪:C:/Ruby20
前面一篇关于智能合约翻译文讲到了,是一种计算机程序,既然是程序,那就可以使用程序语言去编写智能合约了。而若想玩区块链上的项目,大部分区块链项目都是开源的,能看得懂智能合约代码,或找出其中的漏洞,那么,学习Solidity这门高级的智能合约语言是有必要的,当然,这都得在公链``````以太坊上,毕竟国内的联盟链有些是不兼容Solidity。Solidity是一种面向对象的高级语言,用于实现智能合约。智能合约是管理以太坊状态下的账户行为的程序。Solidity是运行在以太坊(Ethereum)虚拟机(EVM)上,其语法受到了c++、python、javascript影响。Solidity是静态类型