当前位置: 首页> 娱乐> 明星 > 关于电子工程的学术论坛_室内装修设计费取费标准_奶茶软文案例300字_合肥百度网站排名优化

关于电子工程的学术论坛_室内装修设计费取费标准_奶茶软文案例300字_合肥百度网站排名优化

时间:2025/7/10 11:18:02来源:https://blog.csdn.net/m0_63874207/article/details/146258321 浏览次数:1次
关于电子工程的学术论坛_室内装修设计费取费标准_奶茶软文案例300字_合肥百度网站排名优化

一、STC89C51RC/RD+系列单片机结构

        STC89C51RC/RD+系列单片机的内部结构框图如下图所示。STC89C51RC/RD+单片机中包含中央处理器(CPU)、程序存储器(Flash)、数据存储器(SRAM)、定时/计数器、UART串口、I/O接口、EEPROM、看门狗等模块。STC89C51RC/RD+系列单片机几乎包含了数据采集和控制中所需的所有单元模块,可称得上一个片上系统。  

单片机最小应用系统:

二、单片机程序实践

1.点亮LED灯

包含51单片机的头文件:#include ”reg52.h“

查询51单片机硬件原理图,可知LED灯由P2的8个引脚位控制。引脚输出电平为0,对应LED灯点亮,引脚输出电平为1,对应LED灯熄灭。从而控制P2引脚的输出电平就可以控制各个LED的亮灭。

#include "reg52.h"			
#include <intrins.h>	void Delay1ms(unsigned int time)		//@12.000MHz
{unsigned char i, j;while(time--){i = 2;j = 239;do{while (--j);} while (--i);}
}void led_on(unsigned char led)
{P2 = ~led;
}void main()
{unsigned int i;while(1){	    unsigned char led = 0x07;for(i=0;i<6;i++)	 //将led左移{led_on(led << i);Delay1ms(1000);	}led = led << 5;for(i=0;i<6;i++)	//将led右移{led_on(led >> i);Delay1ms(1000); }}	
}	
2、获取按键的状态

根据原理图所示,K1~K4对应P1引脚的高4位,K5对应P3引脚的第6位即P35

检测引脚电平,如果是低电平,则说明该引脚对应的KEY被按下

按键初始化:将5个按键的引脚电平设置为高电平,表示没有被按下

读取按键状态:读取相应引脚的状态,判断按键是否被按下

按键状态读取中,消抖很重要,以下是按键消抖的原因:

         当用户按下或释放按键时,由于机械弹性的作用,会产生短暂的不稳定接触,称为抖动。这种抖动可能导致单片机或处理器错误地多次读取按键动作,从而产生错误的信号。因此,消除这种抖动是确保按键准确读取的关键。

#include <reg51.h>
#include "key.h"
#include "delay.h"void key_init(void)
{P1 |= (0xF << 4);P3 |= (1 << 5);
}unsigned char key_status(void)
{unsigned char num = 0;if(0 == (P1 & (1 << 4))){delayms(10);if(0 == (P1 & (1 << 4))){while(!(P1 & (1 << 4)));delayms(10);if(P1 & (1 << 4))num = 1;}		}	else if(0 == (P1 & (1 << 5))){delayms(10);if(0 == (P1 & (1 << 5))){while(!(P1 & (1 << 5)));delayms(10);if(P1 & (1 << 5))num = 2;}}else if(0 == (P1 & (1 << 6))){delayms(10);if(0 == (P1 & (1 << 6))){while(!(P1 & (1 << 6)));delayms(10);if(P1 & (1 << 6))num = 3;}}						else if(0 == (P1 & (1 << 7))){delayms(10);if(0 == (P1 & (1 << 7))){while(!(P1 & (1 << 7)));delayms(10);if(P1 & (1 << 7))num = 4;}}						else if(0 == (P3 & (1 << 5))){delayms(10);if(0 == (P3 & (1 << 5))){while(!(P3 & (1 << 5)));delayms(10);if(P3 & (1 << 5))num = 5;}}return num;
}
3、数码管

每个数码管由abcdefg以及dp  8个段控制显示的内容,只需要控制8个段的电平输出,就可以改变显示内容。所使用的单片机数码管是共阴极数码管,因此高电平使对应段亮。

根据原理图可知,P1引脚控制数码管的段选,P1的低4位控制4个数码管的位选(即控制哪个数码管亮,哪个数码管灭)

#include <reg51.h>
#include "nixietube.h"
#include "delay.h"void seg_select(unsigned char seg)
{unsigned char array[] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f,0x40,0};if(seg <= 11){P0 = array[seg];}
}void pos_select(unsigned char pos)
{if(pos <= 4){P1 = (1 << (pos -1));}
}void display_num(int num)
{int flag = 0;if(num >= 0){if(0 == num / 1000){display(11,4);}else{display(num / 1000, 4);flag = 1;}num = num % 1000;if(0 == num / 100 && flag == 0){display(11,3);}else{display(num / 100, 3);flag = 1;}num = num % 100;if(0 == num / 10 && flag == 0){display(11,2);}else{display(num / 10, 2);flag = 1;}num = num % 10;display(num,1);}else{num = -num;num = num % 1000;if(0 == num / 100){display(11,3);}else{display(num / 100, 3);if(0 == flag){display(10,4);}flag = 1;}num = num % 100;if(0 == num / 10 && flag == 0){display(10,2);}else{display(num / 10, 2);if(0 == flag){display(10,3);		}		flag = 1;}num = num % 10;display(num,1);if(num != 0 && flag == 0){display(10,2);}}}void display(unsigned char seg,unsigned char pos)
{pos_select(pos);seg_select(seg);delayms(5);seg_select(10);
}
4、UART串口通信

SCON:设置SM0 = 0、SM1 = 1,使用8位UART模式,波特率可变;设置REN = 1,允许串行接收

PCON(波特率选择):设置SMOD = 1,使串行口1、2、3的波特率加倍

设置串口中断:将ES串口中断置1打开,EA总中断置1打开

设置定时器:

将TMOD.7  TMOD.6  定时器1的M0,M1 置0,表示打开定时器1,将定时器1/计数器1用作定时器

设置M1、M0 为 1 0,表示8位自动装载定时器,当溢出时将TH1存放的值自动装入TL1

设置定时器/计数器中断控制:设置TR1为1,TMOD.7为0,TR1要为1才能开始计数

void uart_init(void)
{//SM0 = 0, SM1 = 1 时为方式1:8位UART,波特率可变SCON &= ~(1 << 7);  // 将SM0 置0SCON |= (1 << 6);  // 将SM1 置1SCON |= (1 << 4); //  将REN 置1,表示允许串行接收//波特率选择PCON |= (1 << 7); //将SMOD 设置为1,方式1、2、3的波特率加倍//设置串口中断IE |= (1 << 7) | (1 << 4); 	 //将ES串口中断置1打开,EA总中断置1打开//设置定时器TMOD &= ~(0xf << 4); //将TMOD.7  TMOD.6  定时器1的M0,M1 置0,表示打开定时器1,将定时器1/计数器1用作定时器,TMOD |= (0x02 << 4); //设置M1、M0 为 1 0,表示8位自动装载定时器,当溢出时将TH1存放的值自动装入TL1TL1 = 243;		   //设置波特率4800TH1 = 243;TCON |= (1 << 6); //设置TR1为1,TMOD.7为0,TR1要为1才能开始计数
}void uart_send(const unsigned char * dat, int len)
{int i = 0;for(i = 0; i < len; i++)	 {SBUF = dat[i];			 //将要发送的数据存入串口的缓存区中while(!(SCON & (1 << 1)));			//TI位,发送中断请求标志位,为1时表示数据发送完毕TI = 0;							   //将TI位手动置0}
}unsigned char dat[24] = {0};			   //定义存放数据的数组
unsigned char pos = 0;void uart_handler(void)  interrupt 4 
{if(RI)								   //判断接收中断请求标志位,为1时表示有数据发送过来,接收数据{									   //将串口缓存区中收到的数据放入dat中dat[pos++] = SBUF;RI = 0;							   //手动将RI置0,等待下一个数据的发送if(pos == 24)					   //防止对数组dat的越界访问{pos = 23;}}
}unsigned char uart_recv(unsigned char * buf)
{unsigned char ret = 0;unsigned char i = 0;for(i = 0; i < pos; i++)    {buf[i] = dat[i];		//将接收的数据放入buf中}ret = i;for(i = 0; i < pos; i++){dat[i] = 0;			   //清空dat}pos = 0;				   return ret;
}

5、DS18B20温度传感器的配套使用

模块简介:

        DS1820数字温度计提供9位温度读数,指示器件的温度。信息经过单线接口送入DS1820或从DS1820送出,因此从中央处理器到DS1820仅需连接一条线(和地)。读、写和完成温度变换所需的电源可以由数据线本身提供,而不需要外部电源。因为每一个DS1820有唯一的系列号(silicon1serialnumber),因此多个DS1820可以存在于同一条单线总线上。这允许在许多不同的地方放置温度灵敏器件。此特性的应用范围包括HVAC环境控制,建筑物、设备或机械内的温度检测,以及过程监视和控制中的温度检测。

特性简介:

        

引脚排列及说明:

 

 读写时序图说明:

主机读‘1’的时序以及读‘0’的时序:

DS18B20初始化:根据模块时序图,配合对应时间的延时,向模块发出初始化信号

向DS18B20写数据:按照时序图,进行延时和电平的转换,向模块写1或者写0

从DS18B20读取数据:按照时序图,进行延时和电平转换,判断模块发送的数据是1还是0

#include <reg51.h>
#include <intrins.h>
#include "delay.h"
#include "DS18B20.h"sbit DQ = P3^7;unsigned char DS18B20_init()
{char ack;DQ = 1;				   //拉高P3.7引脚delay10us(100);DQ = 0;				   //按照协议,拉低电平,给出初始化的信号delay10us(72);DQ = 1;				   //拉高电平delay10us(18);ack = DQ;			   //将DS18B20返回的信号接收delay10us(32);return ack;			   //返回收回的信号,可由此判断初始化成功与否
}void DS18B20_write(unsigned char dat)
{unsigned char i = 0;for(i = 0; i < 8; i++)			   //1bit 1bit的向传感器发送数据{if(dat & (1 << i))			   //判断发送位的数据为1还是为0{//write 1DQ = 0;					   //为1,按照协议拉高电平_nop_();_nop_();				   //延时2usDQ = 1;					   //拉高电平delay10us(5);}else{// write 0DQ = 0;						//为0,先拉低电平delay10us(5);				//延时DQ = 1;						//拉高电平_nop_();_nop_();}}
}unsigned char DS18B20_read(void)
{unsigned char dat = 0;unsigned char i = 0;for(i = 0; i < 8; i++)			//按位接收传感器返回的数据{DQ = 0;						//按照协议,拉低电平_nop_();_nop_();					//延时两秒DQ = 1;						//重新拉高电平if(DQ == 1)				{dat = dat | (1 << i);	  //收到的为1,将接受的数据放置到相应的位上}delay10us(4);}return dat;					   //返回收到的数据
}short get_temp()
{unsigned char th = 0;unsigned char tl = 0;unsigned char ack = 0;short temp = 0;ack = DS18B20_init();				   //初始化传感器if(1 == ack){return 0xfff;}DS18B20_write(0xcc);				  //初始化成功,向传感器发送信号DS18B20_write(0x44);delayms(1000);ack = DS18B20_init();				  //初始化传感器if(1 == ack){return 0xfff;}DS18B20_write(0xcc);				  //成功则发送信号DS18B20_write(0xbe);tl = DS18B20_read();				  //读取传感器返回的数据,先放入低8位th = DS18B20_read();				  //读取传感器返回的数据,放入高8位temp = (th << 8) | tl;				  //将高9位和低8位合成一个short数据return temp;						  //返回接收到的温度数据
}

5、自定义协议

协议格式:帧头、数据长度、数据、校验和、帧尾

#include <reg51.h>
#include "pack.h"unsigned char check_sum(unsigned char * dat,unsigned char len)
{unsigned char sum = 0;int i = 0;for(i = 0; i < len; i++){sum += dat[i];		  //计算数据位的总和,作为校验位的数据}return sum;
}unsigned char package(unsigned char * dat, unsigned char len, unsigned char * outdat)
{int i = 0;int j =   0;outdat[i++] = FRAME_HEAD;		  //放入帧头outdat[i++] = len;				  //放入数据长度for(j = 0; j < len; j++){outdat[i++] = dat[j];			   //放入数据}outdat[i++] = check_sum(dat,len);		   //计算校验和并放入帧数据中outdat[i++] = FRAME_TAIL;				   //放入帧尾return i;								  //返回一帧数据的长度
}unsigned char data_transfor(data_type * datatype,unsigned char * dat)
{int i = 0;if(datatype->t_flag == 1){dat[i++] = 0x01;dat[i++] = (datatype->temp) >> 8;dat[i++] = datatype->temp;}if(datatype->h_flag == 1){dat[i++] = 0x02;dat[i++] = (datatype->humi) >> 8;dat[i++] = datatype->humi;}	if(datatype->l_flag == 1){dat[i++] = 0x03;dat[i++] = (datatype->light) >> 8;dat[i++] = datatype->light;}return i;	
}unsigned char package1(unsigned char * dat,unsigned char len,unsigned char * outdat)
{int i = 0;int j = 0;outdat[i++] = FRAME_HEAD;outdat[i++] = len;for(j = 0; j < len; j++){outdat[i++] = dat[j];}outdat[i++] = check_sum(dat,len);		   //计算校验和并放入帧数据中outdat[i++] = FRAME_TAIL;return i;
}
关键字:关于电子工程的学术论坛_室内装修设计费取费标准_奶茶软文案例300字_合肥百度网站排名优化

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: