当前位置: 首页 > news >正文

51单片机学习第六课---B站UP主江协科技

DS18B20

1、基本知识讲解

 

2、DS18B20读取温度值

main.c

#include<regx52.h>
#include"delay.h"
#include"LCD1602.h"
#include"key.h"
#include"DS18B20.h"float T;
void main ()
{LCD_Init();LCD_ShowString(1,1,"temp");while(1){DS18B20_convert();T=DS18B20_read();if(T<0){LCD_ShowChar(2,1,'-');	//显示负号T=-T;}else{LCD_ShowChar(2,1,'+');	 //显示正号T=T;}LCD_ShowNum(2,2,T,3);	 //显示正整数  ,精度是3,-55~125LCD_ShowChar(2,5,'.');		//显示小数点LCD_ShowNum(2,6,(unsigned long)(T*10000)%10000,4);//显示小数后面的数字,精度是4位 ,0.0623}}

onewire.c

#include<REGX52.h>
sbit onewire_DQ=P3^7;
unsigned char onewire_init()
{ 
unsigned char ackbit;
unsigned char i;onewire_DQ=1;onewire_DQ=0;i = 247;while (--i);		//延时500usonewire_DQ=1;i = 32;			//延时70uswhile (--i);ackbit=onewire_DQ;i = 247;			//延时500us,这里从机拉低60-240us会自动释放总线while (--i);return ackbit;
}
void  onewire_sendbit(unsigned char Bit)
{unsigned char i;onewire_DQ=0;i = 4;while (--i);//延时10usonewire_DQ=Bit;	//如果bit=0,则DQ继续拉低50us,加上前面10us,刚好满足60us.如果bit=1,则DQ相当10us后总线释放,接着继续释放50usi = 24;while (--i);//延时50usonewire_DQ=1;}
unsigned char onewire_receivebit()
{unsigned char i;unsigned char Bit;onewire_DQ=0;i = 2;while (--i);//主机拉低总线5usonewire_DQ=1;i = 2;while (--i);//主机释放总线5usBit=onewire_DQ;//DS18B20将会发送0或1,此时主机读取数据i = 24;while (--i);//延时50usreturn Bit;
}
void  onewire_sendbyte(unsigned char byte)
{
unsigned char i;
for(i=0;i<8;i++)
{onewire_sendbit(byte&(0x01<<i));	//取一位用与
}}
unsigned char onewire_receivebyte()
{
unsigned char i;
unsigned char byte=0x00;
for(i=0;i<8;i++)
{if(onewire_receivebit()){byte=byte|(0x01<<i);	   //取整体用或}
}
return byte;
}

DS18B20.C

#include<regx52.h>
#include"onewire.h"#define  DS18B20_SKIP_ROM       0xCC  
#define  DS18B20_CONVERT_T       0x44	
#define  DS18B20_READ_SCRATCHPAD     0xBEvoid DS18B20_convert()	   
{onewire_init() ;	 //初始化onewire_sendbyte(DS18B20_SKIP_ROM); //跳过ROMonewire_sendbyte(DS18B20_CONVERT_T);	//温度转换
}float DS18B20_read()		
{  unsigned char TLSB,TMSB;int temp;float T;onewire_init() ;onewire_sendbyte(DS18B20_SKIP_ROM);onewire_sendbyte(DS18B20_READ_SCRATCHPAD);//温度读取TLSB=onewire_receivebyte();	 //读取低八位TMSB=onewire_receivebyte();	//读取高八位temp=(TMSB<<8)|TLSB;			//把低八位和高八位整合成一个数T=temp/16.0;					  //由于存储小数的缘故,最低位不是从2的0次方开始,而是2的-4方开始,所以读取的值要除以16return T;
}

3、DS18B20温度告警器

按键K1实现对温度上限值的加加,K2实现对温度上限值的减减,按键K3实现对温度下限值的加加,K4实现对温度下限值的减减,运用at24c02对温度上限值和下限值进行存储。超过上限值LCD1602显示ov:h,低于下限值LCD1602显示ov:l。

main.c

#include<regx52.h>
#include"delay.h"
#include"LCD1602.h"
#include"key.h"
#include"DS18B20.h"
#include"at24c02.h"
#include"timer0.h"
char Tlow,Thigh; //char类型表示数据位-127~128,满足DS18B20的测温范围-55~125
float  T,Tshow;
unsigned char keynum;
void main ()
{  DS18B20_convert();Delay(1000);Thigh=at24c02_readbyte(0); //一开始就读取AT24C02里的数据,这个时候还没有写入Tlow=at24c02_readbyte(1);if(Thigh>125||Tlow<-55||Thigh<=Tlow){ Thigh=25;Tlow=5;}	//读出的数据可能会超出范围,所以当超出范围时,赋初值LCD_Init();Timer0_Init();LCD_ShowString(1,1,"T:");LCD_ShowString(2,1,"TH:");LCD_ShowString(2,9,"TL:");LCD_ShowSignedNum(2,4,Thigh,3);LCD_ShowSignedNum(2,12,Tlow,3);while(1){keynum=key();DS18B20_convert();T=DS18B20_read();if(T<0) {LCD_ShowChar(1,3,'-');Tshow=-T;}//为什么要定一个Tshow,主要是当T为负数时,要转为正数,这样Tshow就始终是正数if(T>0) {LCD_ShowChar(1,3,'+');Tshow=T;} //因为shownum只能显示正整数,而且要显示小数部分,转成正整数方便转换LCD_ShowNum(1,4,Tshow,3);LCD_ShowChar(1,7,'.');	 LCD_ShowNum(1,8,(unsigned long)(Tshow*100)%100,2);if(keynum){if(keynum==1){Thigh++;if(Thigh>125){Thigh=125;}	  //温度上限值不能超过DS18B20的上限}if(keynum==2){Thigh--;if(Thigh<=Tlow)	//温度上限值减减不能减到小于温度下限值{Thigh++;}}if(keynum==3){Tlow++;if(Tlow>=Thigh)  //温度下限值加加不能加到大于温度上限值{Tlow--;}}if(keynum==4){Tlow--;if(Tlow<-55){Tlow=-55;}	   //温度下限值不能超过DS18B20的下限}at24c02_writebyte(0,Thigh);   //记住写入后要延时5msDelay(5);at24c02_writebyte(1,Tlow);Delay(5);LCD_ShowSignedNum(2,4,Thigh,3);LCD_ShowSignedNum(2,12,Tlow,3);
}if(T>Thigh){LCD_ShowString(1,13,"ov:H");}	//实际温度超过设定上限值告警else if(T<Tlow){LCD_ShowString(1,13,"ov:L");}	  //实际温度低于设定下限值告警else{LCD_ShowString(1,13,"    ");}}}void Timer0_Routine()        interrupt 1
{static unsigned  int count;	TL0 = 0x18;				TH0 = 0xFC;count++;
if(count>=20)	
{count=0;key_loop();}}

onewire.c

这里增加一步关闭中断,再打开中断

#include <REGX52.H>
sbit onewire_DQ=P3^7;
unsigned char onewire_init()
{ 
unsigned char ackbit;
unsigned char i;onewire_DQ=1;onewire_DQ=0;EA=0;//单总线计时时不能进入中断,因为延时是us级别,中断之后再返回会计时不准,所以这里要关掉总中断,计时完后再打开。i = 247;while (--i);		//延时500usonewire_DQ=1;i = 32;			//延时70uswhile (--i);ackbit=onewire_DQ;i = 247;			//延时500us,这里从机拉低60-240us会自动释放总线while (--i);EA=1;return ackbit;
}
void  onewire_sendbit(unsigned char Bit)
{unsigned char i;onewire_DQ=0;EA=0;i = 4;while (--i);//延时10usonewire_DQ=Bit;	//如果bit=0,则DQ继续拉低50us,加上前面10us,刚好满足60us.如果bit=1,则DQ相当10us后总线释放,接着继续释放50usi = 24;while (--i);//延时50usEA=1;onewire_DQ=1;}
unsigned char onewire_receivebit()
{unsigned char i;unsigned char Bit;onewire_DQ=0;EA=0;i = 2;while (--i);//主机拉低总线5usonewire_DQ=1;i = 2;while (--i);//主机释放总线5usBit=onewire_DQ;//DS18B20将会发送0或1,此时主机读取数据i = 24;while (--i);//延时50usEA=1;return Bit;
}
void  onewire_sendbyte(unsigned char byte)
{
unsigned char i;
for(i=0;i<8;i++)
{onewire_sendbit(byte&(0x01<<i));	//取一位用与
}}
unsigned char onewire_receivebyte()
{
unsigned char i;
unsigned char byte=0x00;
for(i=0;i<8;i++)
{if(onewire_receivebit()){byte=byte|(0x01<<i);	   //取整体用或}
}
return byte;
}

LCD1602

1、基本知识讲解

2、字符、字符串 

2、LCD1602.c代码

#include<regx52.h>
sbit lcd_RS=P2^6;
sbit lcd_RW=P2^5;
sbit lcd_EN=P2^7;
#define port  P0
void LCD_Delay()	//@12.000MHz  1ms  //延时函数
{unsigned char data i, j;i = 2;j = 239;do{while (--j);} while (--i);
}void lcd_write_command(unsigned char command)	//写命令
{lcd_RS=0;lcd_RW=0;port=command;lcd_EN=1;LCD_Delay();//因为这里E脉冲宽度时间是us级别,而单片机执行一次命令是us级别,所以这里检测不到,所以加延时函数lcd_EN=0;LCD_Delay();}
void lcd_write_Data(unsigned char Data)	 //写数据
{lcd_RS=1;lcd_RW=0;port=Data;lcd_EN=1;LCD_Delay();//因为这里E脉冲宽度时间是us级别,而单片机执行一次命令是us级别,所以这里检测不到,所以加延时函数lcd_EN=0;LCD_Delay();}void lcd_init()		  //初始化
{lcd_write_command(0x38);lcd_write_command(0x0C);lcd_write_command(0x06);lcd_write_command(0x01);
}void LCD_setcursor(unsigned char line,unsigned char column)	  //定义光标位置,在第几行第几列
{if(line==1){lcd_write_command(0x80|column-1);}else{lcd_write_command(0x80|(column-1)+0x40);}
}void LCD_ShowChar(unsigned char line,unsigned char column,unsigned char Char) //显示一个字符
{LCD_setcursor(line,column);lcd_write_Data(Char);
}
void LCD_ShowString(unsigned char line,unsigned char column,unsigned char *String)	//显示字符串
{unsigned char i;LCD_setcursor(line,column);for(i=0;String[i]!='\0';i++)
{
lcd_write_Data(String[i]);
}}
unsigned int pow(x,y)	   //定义一个幂函数	 例如x=6,y=4,则result=1*6*6*6*6=6^4
{unsigned char result=1;unsigned int i;for(i=0;i<y;i++){result*=x;}return result;
}
void LCD_ShowNum(unsigned char line,unsigned char column,unsigned int num,unsigned char length)	//显示十进制数字
{unsigned char i;LCD_setcursor(line,column);for(i=length;i>0;i--){lcd_write_Data(0x30+num/(pow(10,i-1))%10);}}
void LCD_ShowsignNum(unsigned char line,unsigned char column, int num,unsigned char length)//显示有符号十进制数字
{unsigned char i;unsigned int num1;LCD_setcursor(line,column);if(num>=0){lcd_write_Data('+');num1=num;}else{lcd_write_Data('-');num1=-num;//有符号int的负数最小值为-32768,正数最大值为32767,取反会超出范围,所以定义一个无符号int   num1}for(i=length;i>0;i--){lcd_write_Data(0x30+num1/(pow(10,i-1))%10);
}
}
void LCD_ShowHexNum(unsigned char line,unsigned char column, unsigned int num,unsigned char length)	 //显示十六进制数
{unsigned char i;unsigned char SingleNum;LCD_setcursor(line,column);for(i=length;i>0;i--){SingleNum=num/(pow(16,i-1))%16;if(SingleNum<10){lcd_write_Data(0x30+SingleNum); }else{{lcd_write_Data(0x41+SingleNum-10); }}}}
void LCD_ShowBinNum(unsigned char line,unsigned char column, unsigned int num,unsigned char length)	//显示二进制数
{unsigned char i;LCD_setcursor(line,column);for(i=length;i>0;i--){lcd_write_Data(0x30+num/(pow(2,i-1))%2);}}

 main.c

#include<regx52.h>
#include"LCD1602.h"
#include"delay.h"
void main ()
{lcd_init();LCD_ShowChar(2,4,'A');
//   LCD_ShowString(1,3,"hello");LCD_ShowNum(2,6,66,2);LCD_ShowsignNum(2,10,-77,2);
//   LCD_ShowHexNum(1,8,0x55,2);LCD_ShowBinNum(1,1, 0x55,8);LCD_ShowString(1,16,"welcome to my home!");
while(1)
{lcd_write_command(0x1c);	//流动字幕,移屏Delay(500);		
}}

直流电机

1、基本知识讲解

 

2、LED呼吸灯

main.c

#include<regx52.h>sbit LED=P2^0;void Delay(unsigned int ms)
{while(ms--);}
void main ()
{while(1)
{
unsigned char i,t;
for(i=100;i>0;i--){for(t=0;t<20;t++){	LED=0;Delay(i);LED=1;Delay(100-i);}}
for(i=0;i<100;i++){for(t=0;t<20;t++){	LED=0;Delay(i);LED=1;Delay(100-i);}}}
}

 3、直流电机调速

按K1键实现电机的调速,并在数码管上显示档数。

main.c

#include<regx52.h>
#include"key.h"
#include"nixie.h"
#include"Timer0.h"
sbit motor=P1^0;
unsigned char counter,compare,keynum,speed;void main ()
{Timer0_Init();while(1){keynum=key();if(keynum==1){speed++;speed%=4;if(speed==0){ compare=0;}if(speed==1){ compare=5;}if(speed==2){ compare=50;}if(speed==3){ compare=100;}}nixie (0,speed);}
}void Timer0_Routine()        interrupt 1
{TL0 = 0x9C;				TH0 = 0xFF;counter++;counter%=100;if(counter<compare){motor=1;}else{motor=0;}}

ps:对达林顿管还不是很清楚

相关文章:

  • 读数据湖仓04数据架构与数据工程
  • SkyWalking 自定义链路追踪
  • 【ShuQiHere】从机器语言到汇编语言:深入理解 LC-3 编程 ️
  • 矩阵学习过程中的一些思考
  • 万界星空科技铜拉丝行业MES系统,实现智能化转型
  • 7天的Django实战学习计划
  • ECharts 快速使用
  • mybatisplus的查询,分页查询,自定义多表查询,修改的几种写法
  • class 030 异或运算的骚操作
  • 汽车总线之---- LIN总线
  • Python 解析 html
  • QT:模仿QQ界面(9.28)
  • 各种图形的打印
  • 车辆重识别(2020NIPS去噪扩散概率模型)论文阅读2024/9/27
  • 深信服校招面试总结
  • 【399天】跃迁之路——程序员高效学习方法论探索系列(实验阶段156-2018.03.11)...
  • 2018一半小结一波
  • Akka系列(七):Actor持久化之Akka persistence
  • Apache Zeppelin在Apache Trafodion上的可视化
  • ES10 特性的完整指南
  • Fabric架构演变之路
  • Quartz实现数据同步 | 从0开始构建SpringCloud微服务(3)
  • Spring核心 Bean的高级装配
  • Webpack4 学习笔记 - 01:webpack的安装和简单配置
  • 闭包,sync使用细节
  • 解析 Webpack中import、require、按需加载的执行过程
  • 前端每日实战:61# 视频演示如何用纯 CSS 创作一只咖啡壶
  • 前言-如何学习区块链
  • 收藏好这篇,别再只说“数据劫持”了
  • 提醒我喝水chrome插件开发指南
  • 译有关态射的一切
  • 用mpvue开发微信小程序
  • 《TCP IP 详解卷1:协议》阅读笔记 - 第六章
  • 翻译 | The Principles of OOD 面向对象设计原则
  • ​configparser --- 配置文件解析器​
  • # linux从入门到精通(三)
  • #### golang中【堆】的使用及底层 ####
  • #宝哥教你#查看jquery绑定的事件函数
  • $.ajax,axios,fetch三种ajax请求的区别
  • $.proxy和$.extend
  • (done) 声音信号处理基础知识(2) (重点知识:pitch)(Sound Waveforms)
  • (TOJ2804)Even? Odd?
  • (二)c52学习之旅-简单了解单片机
  • (分布式缓存)Redis持久化
  • (含笔试题)深度解析数据在内存中的存储
  • (利用IDEA+Maven)定制属于自己的jar包
  • (杂交版)植物大战僵尸
  • (转)Windows2003安全设置/维护
  • .net core MVC 通过 Filters 过滤器拦截请求及响应内容
  • .NET Core 和 .NET Framework 中的 MEF2
  • .NET Core使用NPOI导出复杂,美观的Excel详解
  • .net 受管制代码
  • .NET关于 跳过SSL中遇到的问题
  • .NET基础篇——反射的奥妙
  • .NET是什么