“玩板”+再次把玩人生中的第一块开发板
<div class='showpostmsg'> 本帖最后由 gaoyang9992006 于 2020-2-16 12:59 编辑<p> 说起这块板子,已经是十年前的事情, 十年前我刚到哈尔滨上学,在电子大世界买了一块开发板51开发板。从此开始了我的单片机学习之路。毕业后的若干年,他一直躺在我家的一个箱子里,近期由于病毒原因,导致只能憋在家里,最近天气突变,就想要不做个温湿度计,用于测量卧室内的温湿度,以便知道是不是该开空调了,或者该关空调了。</p>
<p>把开发板找到,还找到了一块LCD1602,经过测试,1602已经只剩下右边一小半可以显示了,估计老化严重了。还找到一个AM2301温湿度传感器。非常完美,可以工作了。</p>
<p> </p>
<p> </p>
<p></p>
<p>这就是我那块开发板,当时花了12元。只有最小系统。我还以为我买到便宜了呢。。。</p>
<p> </p>
<p></p>
<p>这是ISP编程器,用于烧录AT89S52的单片机。当时花了45元,其实贵了,老板还问我去其他家打听过价格没,我说没有。。</p>
<p>然后就给了我这个价格。</p>
<p> </p>
<p></p>
<p>这个是后来在二手市场淘的,忘了是多少钱了。</p>
<p></p>
<p>这是室内的自然温湿度,还是比较干燥的,北方嘛,昨天下雨了,今天打晴天,比较冷。早晨外面还结冰了。</p>
<p>用手捂住看看能否有变化</p>
<p></p>
<p>变化明显,因为有个外壳,所以升温比较慢,更容易测环境温度,不会受局部温度影响太大。</p>
<p><br />
接下来就是分享源码和工程了。非常有参考意义。因为我是分头文件编写的。可以直接拿走使用,移植到其他51工程里非常容易。</p>
<p><br />
<br />
<b><font color="#5E7384">此内容由EEWORLD论坛网友<font size="3">gaoyang9992006</font>原创,如需转载或用于商业用途需征得作者同意并注明出处</font></b></p>
</div><script> var loginstr = '<div class="locked">查看本帖全部内容,请<a href="javascript:;" style="color:#e60000" class="loginf">登录</a>或者<a href="https://bbs.eeworld.com.cn/member.php?mod=register_eeworld.php&action=wechat" style="color:#e60000" target="_blank">注册</a></div>';
if(parseInt(discuz_uid)==0){
(function($){
var postHeight = getTextHeight(400);
$(".showpostmsg").html($(".showpostmsg").html());
$(".showpostmsg").after(loginstr);
$(".showpostmsg").css({height:postHeight,overflow:"hidden"});
})(jQuery);
} </script><script type="text/javascript">(function(d,c){var a=d.createElement("script"),m=d.getElementsByTagName("script"),eewurl="//counter.eeworld.com.cn/pv/count/";a.src=eewurl+c;m.parentNode.insertBefore(a,m)})(document,523)</script> <p>LCD1602.C 是主要文件,main函数也在这个里面了。方便LCD1602测试,也可以直接剪切到另外一个文件。 </p>
<pre>
<code class="language-cpp">#include"LCD1602.h"
#include"AM2301.h"
void delay(unsigned int j)
{
for(; j>0; j--);
}
void LCD1602CheckBusy(void)
{
unsigned char tem;
LCD1602_RS_Low();
LCD1602_RW_High();
LCD1602_EN_Low();
while(1)
{
LCD1602_DATA_BUS=0xFF;
LCD1602_EN_High();
// tem=LCD1602_DATA_BUS;
LCD1602_READ_DATA(tem,LCD1602_DATA_BUS);
LCD1602_EN_Low();
if((tem&0x80)==0) break;
}
}
void LCD1602WriteCom(unsigned char com)
{
LCD1602CheckBusy();
LCD1602_RS_Low();
LCD1602_RW_Low();
LCD1602_EN_Low();
// LCD1602_DATA_BUS=com;
LCD1602_READ_DATA(LCD1602_DATA_BUS,com);
delay(2);
LCD1602_EN_High();
delay(2);
LCD1602_EN_Low();
}
void LCD1602WriteData(unsigned char dat)
{
LCD1602CheckBusy();
LCD1602_RS_High();
LCD1602_RW_Low();
LCD1602_EN_Low();
// LCD1602_DATA_BUS=dat;
LCD1602_READ_DATA(LCD1602_DATA_BUS,dat);
delay(2);
LCD1602_EN_High();
delay(2);
LCD1602_EN_Low();
}
void LCD1602Init(void)
{
LCD1602_EN_Low();
LCD1602WriteCom(0x38);
LCD1602WriteCom(0x0c);
LCD1602WriteCom(0x06);
LCD1602WriteCom(0x01);
LCD1602WriteCom(0x80);
}
/*
void LCD1602DispString(unsigned char addr,unsigned char *str)
{
unsigned char i=0;
LCD1602WriteCom(addr);
while(*str>0)
{
LCD1602WriteData(*str++);
delay(10);
}
}
*/
/*写1位数字到指定的位置。参数:位置,1位字符*/
void LCD1602Disp1(unsigned char addr,unsigned char num)
{
LCD1602WriteCom(addr);
LCD1602WriteData(num);
delay(2);//延时13+11*2 us,35us.
}
void main(void)
{
unsigned int shidu,wendu;
LCD1602Init();
{
// LCD1602DispString(0x80,"ABCDEFGHIJKLMNO");
// LCD1602DispString(0xC0,"123456789012345");
// LCD1602Disp1(0x8F,'0'+3);
// LCD1602Disp1(0xCF,':');
}
while(1)
{
Read_Sensor(); // 读取传感器数据
shidu=Sensor_Data;
shidu<<=8;
shidu=shidu|Sensor_Data;
wendu=Sensor_Data;
wendu<<=8;
wendu=wendu|Sensor_Data;
LCD1602Disp1(0x8B,'0'+shidu/100);
LCD1602Disp1(0x8C,'0'+shidu%100/10);
LCD1602Disp1(0x8D,'.');
LCD1602Disp1(0x8E,'0'+shidu%100%10);
LCD1602Disp1(0x8F,'%');
if(wendu&0x8000)
{
LCD1602Disp1(0xCA,'-');
wendu=wendu&0x7FFF;
}
else
LCD1602Disp1(0xCA,'+');
LCD1602Disp1(0xCB,'0'+wendu/100);
LCD1602Disp1(0xCC,'0'+wendu%100/10);
LCD1602Disp1(0xCD,'.');
LCD1602Disp1(0xCE,'0'+wendu%100%10);
LCD1602Disp1(0xCF,'C');
}
}</code></pre>
<p> </p>
<p>这个是LCD1602.h文件,定义了管教的分配,只要修改这个文件就可以在51工程里轻松移植到其他管脚去。 </p>
<pre>
<code class="language-cpp">#include <AT89X52.h>
#include<intrins.h>//包含_nop_()函数定义的头文件
#define LCD1602_DATA_BUS P0
sbit LCD1602_RS=P2^0;
sbit LCD1602_RW=P2^1;
sbit LCD1602_EN=P2^2;
#define LCD1602_RS_High() LCD1602_RS=1
#define LCD1602_RS_Low()LCD1602_RS=0
#define LCD1602_RW_High() LCD1602_RW=1
#define LCD1602_RW_Low()LCD1602_RW=0
#define LCD1602_EN_High() LCD1602_EN=1
#define LCD1602_EN_Low()LCD1602_EN=0
/*从b里读数据写到a. 例如:tem=LCD1602_DATA_BUS;可以写作LCD1602_READ_DATA(tem,LCD1602_DATA_BUS);*/
#define LCD1602_READ_DATA(a_addr,b_addr) a_addr=b_addr
/*延时函数,延时时间=13+11*j,例如当j=17时,延时为200us*/
void delay(unsigned int j);
/*写指令函数。参数:指令*/
void LCD1602WriteCom(unsigned char com);
/*写数据函数。参数:写入数据*/
void LCD1602WriteData(unsigned char dat);
/*初始化函数。参数:无*/
void LCD1602Init(void);
/*检查忙指令。参数:无*/
void LCD1602CheckBusy(void);
/*写字符串。参数:地址(第一行0x80~0x8F,第二行0xC0~0xCF),字符串*/
void LCD1602DispString(unsigned char addr,unsigned char *str);
/*写1位数字到指定的位置。参数:位置,1位字符*/
void LCD1602Disp1(unsigned char addr,unsigned char num);</code></pre>
<p> </p>
<p>这个是AM2301.h</p>
<p>定义了端口和存储温湿度的数组,只要包含这个文件,并调用读取函数就行了,然后从数组了读取转换结果用于显示。 </p>
<pre>
<code class="language-cpp">//AM2301
#include <AT89X52.h>
#include<intrins.h>//包含_nop_()函数定义的头文件
//读传感器 端口位定义,可修改
sbit AM2301_PIN = P2^3;
// 变量定义
unsigned char Sensor_Data={0x00,0x00,0x00,0x00,0x00};
unsigned char Sensor_Check; //校验和
unsigned char Sensor_AnswerFlag;//收到起始标志位
unsigned char Sensor_ErrorFlag; //读取传感器错误标志
unsigned intSys_CNT;
/********************************************\
|* 功能: 延时 晶振为12M时 *|
|*t = 1 为 20us然后成倍增加10us左右 *|
\********************************************/
void Delay_N10us(unsigned char t)
{
while(t--)
{
_nop_();
}
}
/********************************************\
|* 功能: 延时 晶振为12M时 *|
|* 延时大约 1ms *|
\********************************************/
void Delay_N1ms(unsigned int t)
{
unsigned int i;
unsigned int j;
for(j=t;j>0;j--)
for(i=124;i>0;i--);//延时大约 1ms
}
/********************************************\
|* 功能: 读传感器发送的单个字节 *|
\********************************************/
unsigned char Read_SensorData(void)
{
unsigned char i,cnt;
unsigned char buffer,tmp;
buffer = 0;
for(i=0;i<8;i++)
{
cnt=0;
while(!AM2301_PIN) //检测上次低电平是否结束
{
if(++cnt >= 300)
{
break;
}
}
//延时Min=26us Max50us 跳过数据"0" 的高电平
Delay_N10us(2); //延时30us
//判断传感器发送数据位
tmp =0;
if(AM2301_PIN)
{
tmp = 1;
}
cnt =0;
while(AM2301_PIN) //等待高电平 结束
{
if(++cnt >= 200)
{
break;
}
}
buffer <<=1;
buffer |= tmp;
}
return buffer;
}
/********************************************\
|* 功能: 读传感器 *|
\********************************************/
unsigned char Read_Sensor(void)
{
unsigned char i;
//主机拉低(Min=800US Max=20Ms)
AM2301_PIN = 0;
Delay_N1ms(2);//延时2Ms
//释放总线 延时(Min=30us Max=50us)
AM2301_PIN = 1;
Delay_N10us(1);//延时30us
//主机设为输入 判断传感器响应信号
AM2301_PIN = 1;
Sensor_AnswerFlag = 0;// 传感器响应标志
//判断从机是否有低电平响应信号 如不响应则跳出,响应则向下运行
if(AM2301_PIN ==0)
{
Sensor_AnswerFlag = 1;//收到起始信号
Sys_CNT = 0;
//判断从机是否发出 80us 的低电平响应信号是否结束
while((!AM2301_PIN))
{
if(++Sys_CNT>300) //防止进入死循环
{
Sensor_ErrorFlag = 1;
return 0;
}
}
Sys_CNT = 0;
//判断从机是否发出 80us 的高电平,如发出则进入数据接收状态
while((AM2301_PIN))
{
if(++Sys_CNT>300) //防止进入死循环
{
Sensor_ErrorFlag = 1;
return 0;
}
}
// 数据接收 传感器共发送40位数据
// 即5个字节 高位先送5个字节分别为湿度高位 湿度低位 温度高位 温度低位 校验和
// 校验和为:湿度高位+湿度低位+温度高位+温度低位
for(i=0;i<5;i++)
{
Sensor_Data = Read_SensorData();
}
}
else
{
Sensor_AnswerFlag = 0; // 未收到传感器响应
}
return 1;
} </code></pre>
<p> </p>
<p>等我再翻翻,如果找到个合适的显示器,或者无线模块,准备做个联网的,可以手机APP查看测量结果。</p>
<p>厉害</p>
<p>厉害的,感觉动手能力蛮强的</p>
页:
[1]