备战蓝桥杯单片机倒数第五天 各个模块

备战蓝桥杯单片机倒数第五天 各个模块,第1张

今天去白嫖了学校发的一块板子,把常用模块的代码敲一遍再熟悉一下

关于BCD码加减那里是借鉴了博主自由学者亻伊宸

使用P4端口的话要定义一下(使用reg52.h头文件的话)P4=0xc0;

unsigned char duanma[10] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
unsigned char duanmadot[10] = {0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};				
 //由duanma高四位减去8得到
unsigned char Writeaddr [7] = {0x80,0x82,0x84,0x86,0x88,0x8a,0x8c};
unsigned char Readaddr [7] = {0x81,0x83,0x85,0x87,0x89,0x8b,0x8d};
unsigned char Timer[7] = {0x00};//秒 分 时 日 月 周 年 

锁存器和板子初始化省略
PCF8591 数模转换 读取电压值
//读取电位器Rb2(03)或者光敏电阻rd1(01)
void ReadRd1 ()
{
	IIC_Start();
	IIC_SendByte(0x90);
	IIC_WaitAck();
	IIC_SendByte(0x03);	
	IIC_WaitAck();

   	IIC_Start();
	IIC_SendByte(0x91);
	IIC_WaitAck();
	rb2 = IIC_RecByte();
	IIC_SendAck(1);
	IIC_Stop();
}

void PCFADC ()
{
	IIC_Start();
	IIC_SendByte(0x90);
	IIC_WaitAck();
	IIC_SendByte(0x43);	
	IIC_WaitAck();

   	IIC_Start();
	IIC_SendByte(0x91);
	IIC_WaitAck();
	rb2 = IIC_RecByte();	//(用的时候*1.961)   
	IIC_SendAck(1);
	IIC_Stop();	
}

void PCFDAC (uchar dat)
{
	IIC_Start();
	IIC_SendByte(0x90);
	IIC_WaitAck();
	IIC_SendByte(0x40);	
	IIC_WaitAck();
	IIC_SendByte(dat);	    //输入255对应输出为5V
	IIC_WaitAck();
	IIC_Stop();	
}
AT24c02 E2PROM掉电存储
uchar Read24c02 (unsigned char addr)
{
	unsigned char temp;

	IIC_Start();
	IIC_SendByte(0xa0);
	IIC_WaitAck();
	IIC_SendByte(addr);	
	IIC_WaitAck();

   	IIC_Start();
	IIC_SendByte(0xa1);
	IIC_WaitAck();
	temp = IIC_RecByte();
	IIC_SendAck(1);
	IIC_Stop();
	
	return temp;		
}

void Write24c02 (unsigned char addr,unsigned char dat)		//注意两次写入之间要延时1000(int型的);还要注意写入和读取出来的数据都是小于255,否则需要先除以一个数变小
{
	IIC_Start();
	IIC_SendByte(0xa0);
	IIC_WaitAck();
	IIC_SendByte(addr);	
	IIC_WaitAck();
	IIC_SendByte(dat);
	IIC_WaitAck();
	IIC_Stop();		
}
DS1802 测量实时温度的
void Read_Temp ()	  //如果读取的温度有问题,那么应该将onewire.c中的延时时间统一扩大10倍
{
	unsigned char LSB;
	unsigned char MSB;

	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0x44);
	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0xbe);
	
	LSB = Read_DS18B20();
	MSB = Read_DS18B20();
	tem = (MSB << 8) | LSB;
	
	if ((tem & 0xf800) == 0x0000)	  
	{
		tem = tem >> 4;
	}
	
	精确到小数点后几位
	if ((temp & 0xf800) == 0x0000)
	{
		temp = temp >> 4;//先把小数位都移走
		temp = temp * 10;
		temp = temp + (LSB & 0x0f) * 0.0625 * 10;  //扩大十倍后的整数部分加上小数部分(小数部分每一个数表示0.0625 C)
	}
}

DS1302时钟
void Write_Timer ()					//需要Writeaddr[7]、Readaddr[7]、Timer[7]三个数组		  //Timer[7]用数码管显示的需要/16,因为1302是以十六进制进行存储的
{
	unsigned char i;
	Write_Ds1302_Byte(0x8e,0x00);
	for (i = 0;i <= 7;i++)
	{
		Write_Ds1302_Byte(Writeaddr[i],Timer[i]);		
	}
	Write_Ds1302_Byte(0x8e,0x80);	
}

void Read_Timer ()
{
    unsigned char i;
	for (i = 0;i <= 7;i++)
	{
		Timer[i] = Read_Ds1302_Byte(Readaddr[i]);		
	}	
}

//时钟BCD码加
unsigned char BCD_add(uchar dat)
{
	dat = dat + 1;
	switch (dat)
	{
		case 10:dat = 16;break;
		case 26:dat = 32;break;
		case 42:dat = 48;break;
		case 58:dat = 64;break;
		case 74:dat = 80;break;
		case 90:dat = 0;break;	
	}
	return dat;
}

//时钟BCD码减
unsigned char BCD_minus(uchar dat)
{
	dat = dat - 1;
	switch (dat)
	{
		case -1:dat =89;break;
		case 79:dat = 73;break;
		case 63:dat = 57;break;
		case 47:dat = 41;break;
		case 31:dat = 25;break;
		case 15:dat = 9;break;	
	}
	return dat;
}

定时器
T1(16位计时)定时100us
T0(8位自动重装计数)用作NE555 NE555用跳帽连接P34(T0),然后用定时器的T0计数功能
void InitTime ()
{
	TMOD = 0x16;

	TH1 = (65535 - 100) / 256;
	TL1 = (65535 - 100) % 256;
	TH0 = 0xff;
	TL0 = 0xff;
	
	TR0 = 1;
	TR1 = 1;
	ET0 = 1;
	ET1 = 1;
	EA = 1;	
}

void ServiceT0 () interrupt 1
{

}

void ServiceT1 () interrupt 3
{
	TH1 = (65535 - 100) / 256;
	TL1 = (65535 - 100) % 256;
	
	count++;
	if (count >= 10000)
	{
		
		count = 0;
		
	}

	//数码管实现秒闪
	count++;
	if (count >= 10000)
	{
		count = 0;
		smg_f = ~smg_f;
	}
	
	//pwm脉宽调制					   
	pwm_c ++;
	if (pwm_c >= pwm_t)
	{
		pwm_f = 0;
		if (pwm_c >= 100)
		{
			pwm_c = 0;
			pwm_f = 1;
		}
	}	
}
外部中断
void InitINT0 ()
{
	IT0 = 1;
	EX0 = 0;
	EA = 1;	
}

void ServiceINT0 () interrupt 0
{
		
}
串口通信 大概率不考
void InitUart ()
{
	TMOD = 0x21;
	TH1 = 0xfd;					   //只能用T1口
	TL1 = 0xfd;
	TR1 = 1;
	ES = 1;
	EA = 1;

	AUXR = 0x00;
	SCON = 0x50;
}

void ServiceUart ()	interrupt 4
{
	if (RI == 1)
	{
		command = SBUF;
		RI = 0;
	}
}

void SendByte (uchar dat)
{
	SBUF = dat;
	while (TI == 0);
	TI = 0;
}

void SendString (uchar* addr)
{
	uchar i = 0;
	while (*addr != '\0')
	{
		SendByte(*addr);
		addr = addr + 1;
	}
}

void ExecuteCommand ()
{
	if (command != 0x00)
	{
		switch (command & 0xf0)
		{
			case: 0xa0:
				//
				command = 0x00;
				break;
			case: 0xb0:
				//
				command = 0x00;
				break;
				//...
		}
	}
}

数码管和按键不写了,关键是逻辑
超声波 要用到"intrins.h"头文件
void Delay12us()		//@12.000MHz				  //烧录软件生成的软件精准延时函数(stc_Y5)
{
	unsigned char i;

	_nop_();
	_nop_();
	i = 33;
	while (--i);
}

void SendWave ()									  //40KHZ,8组方波脉冲,TX发射
{
	uchar i;
	for (i = 0;i < 8;i++)
	{
		TX = 1;
		Delay12us();
		TX = 0;
		Delay12us();
	}
}

void DistanceMeasure ()								//定时器TH0,TL0从空开始计时
{
	TMOD &= 0x0f;	//TMOD = 0x00;
	TH1 = 0x00;		//定时器0也可以,到时候根据需要选择即可
	TL1 = 0x00;
	//ET1 = 1;
	//EA = 1;

	SendWave ();

	TR1 = 1;
	while ((RX == 1) && (TF1 == 0));  //如果没有溢出也没有接收到那就一直等,RX为低有效
	TR1 = 0;

	if (TF1 == 1)
	{
		distance = 999;
		TF1 = 0;					 //溢出之后要把标志位恢复
	}
	else 
	{
		time = (TH1 << 8) | TL1;
		distance = time * 0.0172;	   //0.0172cm/us (来回)
	}
}

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/564743.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-06
下一篇 2022-04-06

发表评论

登录后才能评论

评论列表(0条)

保存