zoukankan      html  css  js  c++  java
  • STC11F04E——电子工艺实习

    这几天做了一下电子工艺实习,焊接了PCB然后烧写了相应的程序,现在将实验过程记录下来。

    声明1:我是一个单片机小白,下面有任何说的不对的地方,恳请各位指正,谢谢。
    声明2:我将控制位选的4个三极管更换了,程序由原来的位选高电平选中,换成了位选低电平选中,在此声明。
    声明3:这款PCB还实现了超声波测距、数码管滚动显示学号等功能,请见另一篇博客,代码详见GitHub

    我已将该项目上传到GitHub,项目地址为: STC11F04E项目。 代码开源,欢迎测试

    一、实验平台介绍

      本次实验使用的PCB是老师自己画的,老师给了一张并不清晰的原理图截图,如下图所示。可以看到,这块PCB能实现三个功能:使用DS1302显示时间、使用DS18B20显示温度以及使用HC-SR04进行超声波测距(原理图上没有画,实际上它是与DS1302复用了IO和2SLCK引脚),数值显示都是用数码管。实验用到的主控芯片是:STC11F04E
    在这里插入图片描述

    图1 原理图

      焊接完成后大概长这样:
    在这里插入图片描述

    图2 正面

    在这里插入图片描述

    图3 背面

    二、功能实现

    2.1 数码管驱动

    2.1.1 原理

      点亮单个数码管只需要给数码管的公共端接高电平(低电平),然后再给需要点亮的那一段接低电平(高电平)就可以了,其中“给需要点亮的那一段接低电平(高电平)”的过程称为“段选”。点亮多个数码管时,不仅需要选择点亮哪一段,还需要告诉单片机你选中的是哪个数码管,称为“位选”。数码管静态显示就是通过“位选”选中,然后“段选”点亮某些数码管。动态显示就是位选和段选切换的快一些,快到我们的眼睛察觉不到动态变化,就可以显示任意数字组合了。

    2.1.2 共阴还是共阳

      点亮每个数码管之前,都需要知道你的数码管是共阴的还是共阳的,这样才能点亮。测试的方法就是给公共端一个高电位,其他端口给个低点位,如果有一段被点亮了,说明这个数码管是共阳的,否则就是共阴的数码管。
    在这里插入图片描述

    图4 数码管测试

      上面是利用Arduino的3.3V和GND接口,测试数码管的过程,可以看到本次实验使用的5611BH数码管是共阳的数码管。

    2.1.3 编写驱动程序

      先看一下这部分的原理图
    在这里插入图片描述

    图5 数码管部分原理图

      可以看到原理图中控制位选的是P1.0~P1.3这四个IO口,控制数码管段选的是74HC164这个芯片。

    • (1)位选部分
        刚才已经测量过,实验使用的数码管是一个共阳的数码管,所以位选选中的话就需要给每一个公共端高电平。公共端连结了一个三极管,三极管的基极连结P1口,射级连结了VCC,集电极连结数码管的公共端。因此,想要选中某一个数码管,只需使位选P1口输出高电平即可。
    • (2)段选部分
        段选控制部分用到了一个74HC164芯片,这个芯片的特点就是“串行输入、并行输出”,相当于一个8bit的移位寄存器。AB是数据输入端,它会在时钟的上升沿输入数据;CLK是时钟信号输入;MR是复位端,将它接高电平使能;Q0~Q7是数据并行输出端,会将8Bit的数据并行输出。使用这个74HC164芯片,可以减少单片机IO口的占用,仅使用两个IO口就可以控制一个数码管了。
    • (3)程序编写
        程序就不详细解释了,我在程序里写了很多注释,现在直接贴上主要部分的代码。
    /**********************************************************
    *  函数名称:74HC164发送Byte函数
    *  日期:2019-9-29
    *  姓名:ZhangHJ
    *  说明:74HC164移位寄存器输入一字节数据发给寄存器
    ***********************************************************/
    void SendByte_74HC164(uchar byte)
    {
    	uchar num,c;
    	num=tab[byte];
    	for(c=0; c<8; c++)
    	{
    		DAT=num&0x01;			// P3^0 --> 0000 000x
    		CLK=0;					// 制造一个上升沿
    		CLK=1;
    		num>>=1;				// 将数据发送到寄存器
    	}
    }
    

      上面贴出来的是74HC164发送数据的函数,也就是数码管段选的函数。位选控制的话,直接将P1口全部选中就可以了。
      这部分做完后,现在板子可以实现4位数码管同时点亮的功能了,如下图所示。拍照可能数码管不太清楚,但实际看着效果可以。
    在这里插入图片描述

    图6 数码管静态显示效果

    点击查看静态显示的展示效果视频

    2.1.4 数码管动态显示

      上面做完之后,就已经实现了数码管的静态显示,也就是4个数码管只能同时显示同一个数,要实现动态显示,就需要对数码管的位选进行详细的控制。
    (1)动态原理
      一般来说,动态显示的流程是:

    循环进行:

    1. 关闭位选(位选都不选中)
    2. 开启段选(74HC164向寄存器传送数据)
    3. 开启位选(选中要显示的数码管)
    4. 关闭段选(清空段选数据,防止残影)
    5. 关闭位选(防止残影)

      下面就根据这个顺序写一些数码管的动态显示程序。
    (2)程序编写
      同样只贴出重要的代码,工程文件我上传到了GitHub,会在文末给出。

    /**********************************************************
    *  函数名称:按字节控制数码管动态显示函数
    *  日期:2019-9-30
    *  姓名:ZhangHJ
    *  说明:实现4个数码管显示 1234 的效果
    * 		数码管引脚低电平有效,首先关闭位选信号,然后给寄存器发送数据(开启段选),
    *		开启位选控制并延时一段时间以显示数字,最后关闭位选信号清屏.
    ***********************************************************/
    void test_light_byte()
    {
    		P1 |= 0x0f;							// 关掉位选
    		SendByte_74HC164(1);				// 开启段选
    		P1 &= 0xf7;							// 开启位选
    		delay_ms(DELAY_TIME);				// 延时显示
    		P1 |= 0x0f;							// 关掉位选
    		
    		SendByte_74HC164(2);
    		P1 &= 0xfB;
    		delay_ms(DELAY_TIME);
    		P1 |= 0x0f;
    		
    		SendByte_74HC164(3);
    		P1 &= 0xfD;
    		delay_ms(DELAY_TIME);
    		P1 |= 0x0f;
    
    		SendByte_74HC164(4);
    		P1 &= 0xfe;
    		delay_ms(DELAY_TIME);
    }
    

      上面的方法是同时控制1Byte的P1口的高低电平,实现位选控制,同样可以直接使用位控制,来控制数P1的某一个端口,下面给出代码。

    /**********************************************************
    *  函数名称:按位控制数码管动态显示函数
    *  日期:2019-9-30
    *  姓名:ZhangHJ
    *  说明:实现4个数码管显示 4321 的效果
    * 		数码管引脚高电平有效,首先设置各位段选信号,然后给寄存器发送数据
    *		延时一段时间实现数字显示,最后清除段选信号清屏.
    ***********************************************************/
    void test_light_bit()
    {
    		DPY0 = ON;
    		DPY1 = OFF;
    		DPY2 = OFF;
    		DPY3 = OFF;
    		SendByte_74HC164(1);
    		delay_ms(DELAY_TIME);
    		SendByte_74HC164(10);
    	
    		DPY0 = OFF;
    		DPY1 = ON;
    		DPY2 = OFF;
    		DPY3 = OFF;
    		SendByte_74HC164(2);
    		delay_ms(DELAY_TIME);
    		SendByte_74HC164(10);
    	
    		DPY0 = OFF;
    		DPY1 = OFF;
    		DPY2 = ON;
    		DPY3 = OFF;
    		SendByte_74HC164(3);
    		delay_ms(DELAY_TIME);
    		SendByte_74HC164(10);
    		
    		DPY0 = OFF;
    		DPY1 = OFF;
    		DPY2 = OFF;
    		DPY3 = ON;
    		SendByte_74HC164(4);
    		delay_ms(DELAY_TIME);
    		SendByte_74HC164(10);
    }
    

      差不多的流程,同样能实现数码管的动态显示控制。动态显示做完之后,这四个数码管就能显示不同的数字了,效果如下图所示。
    在这里插入图片描述

    图7 数码管动态显示效果

    点击查看数码管动态显示的效果视频

      可以看到,在按键按下后,显示的4321是有残影的。这是因为按位操作显示4321的函数,没有严格按照动态显示的顺序进行编写,没有关闭位选。就先这样吧,不再改了。
      数码管能做到这里基本就算完事了,接下来进行DS18B20温度传感器的控制。

    2.2 DS18B20 温度传感器驱动

    2.2.1 原理

      DS18B20是一个常见的温度传感器,特点就是“单总线数据传输”。因为它只有一个数据引脚,要实现单片机之间的数据读取、写入、初始化等操作,时序就非常重要了。非常非常非常重要(重要的事情说三遍)。其他内容看一下资料就好了,资料在我的GitHub里面也有。

    2.2.2 程序编写

      我们想实现的功能是将DS18B20的温度数值,显示在这4个数码管上。数码管已经玩过了,下面就列举一下DS18B20的驱动程序。

    /**********************************************************
    *  函数名称:发送复位和初始化命令函数 dsinit
    *  修改日期:2019-9-9
    *  修改人:ZhangHJ
    *  说明:1. 对于单片机: 单片机首先发出480-960us的低电平脉冲,
    *			释放总线为高电平(上拉电阻拉高),在随后的480us进行检测,
    *			如果出现低电平,说明器件应答正常.B
    *		2. 对于DS18B20: 上电后就检测是否有480/960us的低电平脉冲,
    *			如果有低电平,在总线释放之后,等待15-60us,
    *			将电平拉低60-240us,告诉主机已经准备好.
    ***********************************************************/
    uchar dsreset(void)					// send reset and initialization command
    {
      uint i;
      DS = 0;							// 先将端口拉低
      i=120;							// 维持低电平状态480us~960us
      while(i>0)i--;
      DS = 1;							// 然后释放总线(将总线拉高),若DS18B20做出反应,将会将在15us~60us后将总线拉低
    	
    	i = 0;
    	while(DS)						// 在DS高电平时等待
    	{
    		i++;
    		if(i > 50000)				// 等待时间大于60us,说明响应失败
    		{
    			return 0;
    		}
    	}
    	return 1;
    }
    

      上面这个程序是DS18B20的初始化函数,也就是说,DS18B20在于单片机进行通信之前,需要跟单片机告诉一声,单片机于DS18B20之间建立通信连接之后,才能进行整行的通信。这也是单总线通信的特点。
      大概的通信过程是:

    1. 对于单片机: 单片机首先发出480-960us的低电平脉冲,释放总线为高电平(上拉电阻拉高),在随后的480us进行检测,如果出现低电平,说明器件应答正常。
    2. 对于DS18B20: 上电后就检测是否有480/960us的低电平脉冲,如果有低电平,在总线释放之后,等待15-60us,将电平拉低60-240us,告诉主机已经准备好。

      单片机与DS18B20之间建立通信连接(DS18B20初始化)完成后,单片机想读取DS18B20的寄存器中的数据,还需要写一个读取数据的函数,下面贴出代码。

    /**********************************************************
    *  函数名称:读1bit数据函数
    *  修改日期:2019-9-9
    *  修改人:ZhangHJ
    *  说明:1.首先单片机端口拉低 >1us,
    *		2.然后释放总线,拉高总线,
    *		3.等待>15微秒,是为了让 DS18B20 数据稳定,
    *		4.读取DS数据,
    *		5.接下来进行延时等待采样周期完成。
    *	详见DS18B20资料2.8.3.1读/写时间片
    ***********************************************************/
    bit tmpreadbit(void)				// read a bit data
    {
    	uint i;
    	bit dat;						// 定义位数据 (dat = 0 or 1)
    	DS = 0;							// 先将端口拉低
    	_nop_();						// 延时 2us ,要求至少保持1us
    	DS = 1;							// 再将端口拉高
    	i=8;while(i>0)i--;				// 等待DS数据稳定,要求的至少延时15us以上
    	dat = DS;						// 数据传输
    	i=15;while(i>0)i--;				// 等待数据采样周期完成,要求不低于60us
    	return (dat);
    }
    

      上面这个函数,是单片机读取DS18B20一位数据的函数。这个函数的时序要求很严格,这些操作的时间一定要按要求,否则程序将不能正常运行。函数具体的过程也不说了,注释里都有。现在这个函数是读取1bit数据的函数,要想实现1Byte的读取,只需将这个函数循环8次,加上数据移位操作就可以了,代码就不贴了。
      上面已经算是单片机可以读取到DS18B20的数据了,但是DS18B20它是怎样得到温度数值的呢?这涉及到了对DS18B20 的寄存器写指令的操作,举个例子,单片机往DS18B20里面写入一字节的指令0x44,18B20就会进行进行一次温度转换。这些操作指令在DS18B20的手册里面都有,我们也不用记住,到时候直接手册就行。所以现在需要写一个写操作的函数,用来给DS18B20写指令,下面贴出代码。

    /**********************************************************
    *  函数名称:写入1Byte数据函数
    *  修改日期:2019-9-11
    *  修改人:ZhangHJ
    *  说明:1.将对待写入数据dat进行位操作,将dat末位数值赋值给位数据testb
    *		2.通过判断testb得到写 0 还是写 1
    *		3.若是写 0 操作,将 DS 拉低,进行>60us的延时,再将DS拉高,进行>1us的延时
    *		4.若是写 1 操作,将 DS 拉低,进行15~60us的延时,再将DS拉高,进行>60us的延时
    *		5.循环执行2、3、4操作8次,写入1字节数据
    *	详见18B20资料“2.8.3.1读/写时间片”章节
    ***********************************************************/
    void tmpwritebyte(uchar dat)   		//write a byte to ds18b20
    {
      uint i;
      uchar j;
      bit testb;
      for(j=1;j<=8;j++)
      {
        testb = dat&0x01;
        dat = dat>>1;
        if(testb)     					// write 1
        {
          DS=0;
          i=8;while(i>0)i--;;			// 延时要求15~60us内
          DS=1;
          i=15;while(i>0)i--;			// 要求不低于60us
        }
        else
        {
          DS = 0;       				// write 0
          i=15;while(i>0)i--;
          DS = 1;
          i++;i++;
        }
      }
    }
    

      写操作同样对时序也是非常非常严格,按手册要求才行。具体的过程同样也没啥可说的,注释里也有。这样就可以对DS18B20写入操作命令,指示DS18B20干活了。

    /**********************************************************
    *  函数名称:18B20温度转换完整过程函数
    *  修改日期:2019-9-11
    *  修改人:ZhangHJ
    *  说明:1.首先进行18B20初始化
    *		2.进行适当延时
    *		3.发送跳过光刻ROM指令
    *		4.发送RAM指令,进行温度转换
    *		5.读取两个8位数据,放到16位寄存器 temp 中
    *		6.将读取到的二进制数据(默认为正数),转换为十进制数据
    *		7.返回温度数据
    *	详见18B20资料“2.8.3.1存储器操作命令”章节
    ***********************************************************/
    uint tmp()								// get the temperature
    {
      float tt;
      uchar high,low;
    	//P1 |= 0x0f;
      while(dsreset() == 0)
    	{
    		SendByte_74HC164(0);
    		P1 &= 0xfB;
    	}
      delay(1);
    	//tmpchange();
      tmpwritebyte(0xCC);					// 跳过 ROM 操作
      tmpwritebyte(0xBE);					// 读暂存寄存器
      low=tmpread();
      high=tmpread();
      temp=high;
      temp<<=8;								// two byte compose a int variable
      temp=temp|low;
      tt=temp*0.0625;
      temp=tt*10+0.5;
      return temp;
    }
    

      上面的函数就是DS18B20温度转换的完整过程,因为涉及到了一些寄存器的操作,温度数值转换的操作,我也没深入研究,也不说啥了。想要知道原理的话可以看一看DS18B20的手册。
      现在已经能够实现读取DS18B20温度数值的功能了,只要将温度转换之后的数值,显示到数码管上就完事了。数码管那一部分就不贴代码了,跟动态显示差不太多。效果如下图所示。
    在这里插入图片描述

    图8 温度显示效果

    点击查看DS18B20温度传感器测试视频

    2.3 DS1302时钟模块

    2.3.1 原理

      DS1302是一个常见的时钟芯片,它可以可提供秒、分、时、日、星期、月和年的时间记录,同时还有每月多少天的自动调整,还具有闰年补偿功能。嗯,功能多到我们都用不着哈?。这东西拿来做一个万年历还行,但是我的PCB上面只有4个数码管,一次也显示不全,还不如只用“时分”功能来得方便。
      DS1302的封装就长这样:
    在这里插入图片描述

    图9 DS1302时钟芯片

    Vcc2是它的主电源,Vcc1是它的备用电源
    X1、X2是晶振的输入端
    SCLK是时钟的输入端
    CE是片选使能

      在芯片手册里有要求,外接的晶振是标准的32.768KHz,按要求外接一个就行了。SCLK接单片机的引脚,因为这个芯片在读写操作时需要进行时钟的控制(在时钟上升沿写入数据;在时钟下降沿读数据),所以接到单片机上给它造上升沿和下降沿。CE是片选使能,在时序图里面可以看到,要进行读写操作时,CE必须要是高电平。低电平的CE会禁止读写操作,终止数据的传输。
    在这里插入图片描述

    图10 DS1302时序图

    2.3.2 程序编写

      DS1302这个芯片操作还是比较方便的,这个芯片因为是专门用来当时钟的芯片,所以对他的访问也无非就只有“写入初始时间”和“读取时间”。
      对于写入初始时间来说,也就是往DS1302寄存器里写入数据而已;对于读取时间来说,需要你提供一个地址,用来告诉单片机你想访问DS1302的哪个寄存器,然后单片机就会去DS1302这个寄存器里面取值,经过数值转换后,就成了我们想要的时间数值。
      DS1302的寄存器也有点意思,因为它是专门的时钟芯片,所以寄存器也是很好理解。
    在这里插入图片描述

    图11 DS1302寄存器

      首先来进行写命令函数的编写,下面贴出代码。

    /**********************************************************
    *  函数名称:DS1302写操作函数
    *  日期:2019-10-4
    *  姓名:ZhangHJ
    *  说明:写操作包含两个参数,add表示要写入的地址;wdata表示要写入的数据
    *		1. 读写操作需要先将RST拉高才能进行
    *		2. 先写入控制字节,在时钟上升沿串行写入数据
    *		3. 再写入数据字节,同样在时钟上升沿写入数据
    *		4. 最后拉低RST禁止数据传输
    ***********************************************************/
    void DS1302Write(uchar add,uchar wdata)
    {
    	uchar a;
    	//wdata = hex(wdata);				// 转换为BCD码
    	RST=0;								// 拉低RST引脚,终止数据传输
    	SCLK=0;								// 拉低SCLK引脚,清零时钟线
    	RST=1;								// 拉高RST引脚,所有数据传输都要拉高RST脚,启动控制逻辑
    	//先写入控制字节
    	for(a=0; a<8; a++)
    	{
    			IO= add & 0x01;				// IO引脚准备好要写入的1位数据
    			SCLK=1;						// SCLK上升沿,1位数据从IO脚写入,低位先写入
    			add>>=1;					// 数据右移1位
    			SCLK=0;						// 拉低SCLK,为下次写入准备,循环8次写入1字节
    	}
    	//再写入数据字节
    	for(a=0; a<8; a++)
    	{
    			IO= wdata & 0x01;
    			SCLK=1;
    			wdata>>=1;
    			SCLK=0;
    	}
    	RST=0;								// 数据传输完拉低RST
    }  
    

      写入数据也是串行写入的,可以依照时序图进行该函数的编写。另外读命令函数也贴出代码。

    /**********************************************************
    *  函数名称:DS1302读操作函数
    *  日期:2019-10-4
    *  姓名:ZhangHJ
    *  说明:读操作只需一个参数,即需要读取的寄存器地址add
    *		1. 首先需要将需要读取的地址(1Byte)写入寄存器,在上升沿进行写入操作
    *		2. 之后读取该地址中的数据,在下降沿读取数据
    *		3. 最后返回读取到的1Byte数据
    ***********************************************************/ 
    uchar DS1302Read(uchar add)
    {
    	uchar a, rdata=0;
    	RST = 0;									// 拉低RST引脚,终止数据传输
    	SCLK = 0;									// 拉低SCLK引脚,清零时钟线
    	RST = 1;									// 拉高RST引脚,启动控制逻辑
    	//发送控制字节
    	for(a=0; a<8; a++)
    	{
    		SCLK = 0;
    		IO = add & 0x01;
    		SCLK = 1;								// 制造一个上升沿,写入地址
    		add >>= 1;
    	}
    	//读1字节数据
    	for(a=0; a<8; a++)
    	{
    		SCLK = 1;
    		rdata >>= 1;
    		SCLK = 0;								// 制造一个下降沿,读取数据
    		if(IO)
    		{										// 如果读到1
    			rdata |= 0x80;						// 把最高位置为1,记录到rdata中
    		}
    	}
    	RST=0;										// 拉低RST
    	//return dec(d);        					// 读取的数据转换成十进制
    	return rdata;
    }
    

      读命令也是依照时序图就可以编写出来,方便理解。
      现在读写指令都编写完成了,基本上DS1302的功能就可以实现了。其他的数码管显示、初始时间设置等等,就不再说了,直接看GitHub。效果如下图所示。
    在这里插入图片描述

    图12 时间显示效果

    点击查看DS1302时钟芯片测试视频

    2.4 代码整合

      现在已经实现了数码管显示、DS1302获取时间、DS18B20获取温度这三个功能了,只要将代码整合一下就能烧到单片机中了。具体的整合过程也不再赘述了,只贴一下最终的主函数。

    // 主函数功能:默认显示时间(初始化时间为“2019年10月4日18:55:00”),按住INT0按键时,会显示温度
    void main()
    {
    	uchar a;
    	ds1302_init();								// DS1302日期初始化
    	while(1)
    	{
    		// 时间显示
    		read_time();							// DS1302读取当前时间
    		Display_Time();							// 显示当前时间
    		// 按键处理
    		if (KEY == 0)
    		{
    			delay(5);
    			while(KEY == 0)						// 按键消抖
    			{
    				// 温度显示
    				tmpchange();					// 首次温度转换
    				for(a=50;a>0;a--)				// 延时,保持连续显示
    				{
    					Display_Tmp(tmp());			// 进行温度转换和数值显示
    				}
    			}
    		}
    	}
    }
    

      主函数实现的功能就是,在单片机上电后,进行一次时钟芯片的初始化,设置初始时间,然后循环进行时间的显示。当INT0按键被按下时,会进行温度转换,显示实时温度。
    点击查看代码整合视频

    三、设想

      现在单片机能实现两个功能:温度显示、时间显示 。但是时间的显示是通过DS1302时钟芯片来实现的,这就有一些缺点。比如我可能需要在初始化时钟芯片时写入初始化的时间,这就显得不太合适;同时,由于单片机晶振和外部晶振的问题,可能导致时间不准确,过一段时间还得手动校时,这也很不方便。
      比较好的解决办法是将单片机联网,在网络获取时间后写入DS1302,每隔一段时间进行一次自动校时,这样就解决了时间不准确的问题。然而单片机自身不能联网,需要通过其他方式接入网络。ESP8266就是一款小巧的WiFi模块,通过单片机与ESP8266的通信,可以将网络时间传输到单片机中。
      ESP8266可以通过AT指令的方式,与单片机进行数据通信;同时,它自身的WiFi功能还能通过网络GET请求获取到NTP服务器的精确时间,通过串口传给单片机进行校时。
      目前我已实现使用ESP8266获取到网络时间的功能,我是用TTL连接的电脑,用串口助手给ESP8266发送AT指令,通过GET请求获取到了NTP服务器的时间,如下图9所示。
      在GET请求到的数据中,可以看到date1就是我们想要的时间,而且还是UTC +8.00的东八区时间,用起来会更方便了。
      我现在是使用串口与ESP8266通信,需要实现的单片机与ESP8266的通信,与这种方式差不多,所以实现起来还是可行的。
    在这里插入图片描述

    图13 串口助手

    四、总结

      以前玩过Arduino、树莓派,现在看来Arduino,它的IDE是很方便,适合初学者;而树莓派因为能搭载Linux所以功能太强大,跟电脑差不多了。还是单片机好玩,因为在学习单片机的过程中,才能真正理解每一个器件是如何工作的,学习工程中需要了解很多底层的知识才能玩转。
      单片机一开始上手都不知道怎么烧程序,后来查阅资料之后才慢慢了解。另外就是DS18B20 时序很重要。。。因为我花了很长时间才把它玩起来,让人头大。

    五、资料

    5.1 本项目GitHub地址

    https://github.com/ZHJ0125/STC11F04E

    5.2 参考资料

    (1)74HC164

    74hc164中文资料汇总(74hc164引脚图及功能_特性参数及典型应用电路) - 全文 - 电子发烧友网
    74HC164_中文资料_价格_官方数据手册_STMICROELECTRONICS - 万联芯城
    51单片机74HC164串口控制数码管显示
    74HC164控制数码管显示 - 恶魔的旋律 - ITeye博客
    74HC164驱动程序实例(C语言版子程序或汇编版子程序)-百合电子工作室
    STC Micro STC11F04E - PDF Datasheet - STC In Stock | lcsc.com
    74HC164 - ztm521的专栏 - CSDN博客

    (2)AT89C2051

    AT89C2051-24SU_引脚图_电路图(2/10)_ATMEL - 万联芯城
    AT89C2051-24PC 89C2051-24PC 价格

    (3)DS18B20

    单片机练习 - DS18B20温度转换与显示 - MK2 - 博客园
    16.4 温度传感器 DS18B20 - 单片机教程(三) - 极客学院Wiki
    关于DS18B20温度传感器的时序详解及代码分析 - Kk_01110001B的博客 - CSDN博客
    51单片机的几种精确延时 - feike24的博客 - CSDN博客

    (4)DS1302

    51单片机操作DS1302时钟芯片 - 柚柚控 - ITeye博客
    51单片机DS1302实时时钟驱动程序 - Line - CSDN博客

    (5)ESP8266

    ESP8266-01 固件更新过程 - qq_31310793的博客 - CSDN博客
    工具 | 乐鑫
    v1.1.1 · GitBook

    使用ESP8266 NodeMCU从NTP服务器获取日期和时间
    ESP8266 NTP时钟| 坚果与伏特杂志
    认识ESP8266 | 坚果与伏特杂志
    带OLED的最简单ESP8266本地时间互联网时钟:4个步骤(带图片)

    51单片机利用8266获取网络时间 - weixin_42757674的博客 - CSDN博客

    STC: 1T 8051 单片机创新者, ISP/IAP 技术创新者
    三极管是如何导通的? - 知乎

  • 相关阅读:
    poj 2054 Color a Tree(贪婪)
    Restful 和 Jersey介绍(Web Service )
    Android异步载入全解析之使用多线程
    50个Android开发技巧(11 为文字加入特效)
    HDU 4424 Conquer a New Region 最大生成树
    Spring通过工厂创建实例的注意事项
    配置rhel 6.4(64位)安装使用syslog-ng 3.5
    虚拟机上网设置
    Java学习——何为JNDI
    Swift初体验 (一)
  • 原文地址:https://www.cnblogs.com/ZHJ0125/p/12904509.html
Copyright © 2011-2022 走看看