51单片机应用

  从上个寒假开始就接触学习stc89c52,到现在也有七八个月了。虽然做过的东西不算多,但感觉总有很多模块是经常要用到的,无论是测试的时候,还是作品成型的时候。但是,在做一个新的作品的时候,除了学习一些新模块,很多都是在重复着之前的工作。郁闷的是,虽然是之前测试通过的模块,调试还是会费很多时间。所以,就有了把各个模块封装整理成最小最简单的函数的想法,以后要用的时候,直接调用就行了。这样就可以不必浪费时间在一些不必要的时间上。

延时篇

  不要求特别精确的时候可以用,在根据时序图写程序也可以用。

void delayms(uint xms)	//毫秒级的
{
	uint i,j;
	for(i=xms;i>0;i--)		      //i=xms即延时约xms毫秒
		for(j=110;j>0;j--);
}            
//晶振为11.0592Mhz

void delayus(uint xus)  //微秒级
{
   uint i,j;
for(i=xms;i>0;i--) //i=xms即延时约xms毫秒
        nop();
}
//晶振为11.0592Mhz

显示篇

  led:这个是最简单的了,led串个电阻,一端接VCC,另一端接IO口,当给低电平时,灯就亮了。如果说在上机位写程序是从Hollow world开始的话,那么单片机就是从点亮第一个发光二极管开始的。用led,最常用来的就是用来检测其他模块能否正常工作了,比如说,红外遥控,为确保能直观看到这个模块是否正常,用led来检测是最好不过了。

sbit led1=P1^0;
  led1=0;

  

  lcd1602:因为一般从其他模块的得到数据,要显示出来,一般习惯用液晶屏来显示。用1602也比较简单,不过缺点是占到的IO口太多了,3个控制线+8个信号线。在51上就占了11/36。不过用来测试还是比较方便的。

sbit rs=P1^0;
sbit rw=P1^1;
sbit E=P2^5;    //根据原理图改

void WriteCom(uchar j)	 //写指令
{	
	rs=0;
	rw=0;
	E=0;		  //使能端需要一个高脉冲
	P0=j;		 //数据码输入端,这时写的是指令
	delayms(5);
	E=1;
	delayms(5);
	E=0;		
}

void WriteData(uchar a)	  //写数据
{
	rs=1;
	rw=0;
	P0=a;		 //写的是字
	E=0;		 //使能端也是高脉冲
	delayms(5);
    E=1;
	delayms(5);
	E=0;
}

void InitLCD()		//显示模式及光标的等设置
{
		WriteCom(0x38);//显示模式设置		
		WriteCom(0x0c);	//显示开/关及光标设置00001DC  //D=0、1:关、开显示;C=0、1:关、开光标;B=0、1:不显示、开光标闪烁。
      	        WriteCom(0x01);	// 显示清屏
		WriteCom(0x06);	//		  
}

void display(uchar rol, uchar num,uchar dat)  //行数,列数,数据
{
	if(rol == 1)
	{
		WriteCom(0x80+num);
		WriteData(0x30+dat);
	}
	if(rol == 2)
	{
		WriteCom(0x80+0x40+num);
		WriteData(0x30+dat);
	}
	
}


void dis_dy(uchar rol, float t)  //要怎么显示,具体在这里改。主函数中调用这个就行.在这里是显示x.xxxx
{
	mm=t/1024*5*10000;
	shuzi1=mm/10000;
	shuzi2=mm/1000%10;
	shuzi3=mm/100%10;	
	shuzi4=mm/10%10;
	shuzi5=mm%10;

	display(rol, 4,shuzi1);
	WriteData('.');
	display(rol, 6,shuzi2);
	display(rol, 7,shuzi3);
	display(rol, 8,shuzi4);
	display(rol, 9,shuzi5);
}

  数码管:

 

传感器篇

  就现在接触传感器来,感觉传感器分为三种,一是:传感器芯片连电位器,再连接到一个电压比较器,通过比较输出,高低电平。比如,智能小车检测黑线循迹用的TCRT5000,检测人体有无的红外热释探头;二是“含有处理器”的传感器,他们可以看做是和在单片机进行通信,在单片机给他进行操作后,传感器将检测到的数值一位一位的传给单片机,然后单片机再一位位的处理,得到要检测的值。比如单总线连接的dht11,ds18b20等;三是,不同数值就有不同的电压输出,这种传感器要经过AD转化,和公式转化,才能得具体数值,比如检测CO的MQ-5。检测角度的角度传感器等等。

  其中第一种是电平输出的基本就不需要代码的,第二种,看时序图,移位是关键,但一般常见的传感器,网上或商家的资料是很多的,主要是要看懂。因为可能例程是添加了很多其他你不用用到的东东。或者在一些时间延时上,不同处理器的时间也是不同,从51移植到其他单片机,就需要改动了。第三种主要就是在AD转化上。

  ds18b20温度检测部分代码:

////////////////////18B20程序//////////////////////////	stc12系列的   
void ds18b20_Reset(void)    //18B20复位,初始化函数
{
	unsigned char x = 0;
	DQ = 1;
	delayxus(60);
	DQ = 0;
	delayxus(240);
	delayxus(240);
	DQ = 1;
	delayxus(80);	
	x = DQ;
	delayxus(120);
}


uchar ds18b20_ReadByte(void)
{
	unsigned char i = 0;
	unsigned char dat = 0;
	for(i = 0;i < 8;i ++)
	{	
		DQ = 0;
		dat >>= 1;
		delayxus(1);
		DQ = 1;
		delayxus(1);
		if(DQ) 
		dat |= 0x80;
		delayxus(60);
	}
	return (dat);
}

void ds18b20_WriteByte(unsigned char dat)   //向18B20写一个字节数据
{
  unsigned char i = 0;
  for(i = 0;i < 8;i ++)
  {
    DQ = 0;
	DQ = dat&0x01;
	delayxus(1);
	delayxus(60);
	DQ = 1;
	dat >>= 1;
	delayxus(1);
  }
}

ReadTemperature(void)       //读取寄存器中存储的温度数据 数据类型是整形,为当前温度的10倍。
{
  	unsigned int a = 0;
	unsigned int b = 0;
	unsigned int temp = 0;
	float tt = 0;
	ds18b20_Reset();
	ds18b20_WriteByte(0xCC);
	ds18b20_WriteByte(0x44);
	ds18b20_Reset();
	ds18b20_WriteByte(0xCC);
	ds18b20_WriteByte(0xBE);
	a = ds18b20_ReadByte();
	b = ds18b20_ReadByte();
 	temp=b;
 	temp<<=8;            //两个字节组合为1个字
    temp=temp|a;
    f_temp=temp*0.0625;      //温度在寄存器中为12位 分辨率位0.0625°
    temp=f_temp*10+0.5;    //乘以10表示小数点后面只取1位,加0.5是四舍五入
    f_temp=f_temp+0.05; 
    return temp;         //temp是整型

}

  AD检测例程加显示//stc12内部自带AD

 

通讯篇

     两个但单片机通过RXD,TXD通讯;

     红外遥控;

 

 

 

  

  

原文地址:https://www.cnblogs.com/pxshin/p/2668607.html