蓝桥杯自学(模块化代码)

 记录一下自己的学习过程

共阳数码管段码表

#include "reg52.h"
#include "ds1302.h"
#include "iic.h"

//定时器辅助寄存器
sfr AUXR = 0x8e; //串口通信时会用到

//独立按键
sbit S4 = P3^3;
sbit S5 = P3^2;
sbit S6 = P3^1;
sbit S7 = P3^0;

//矩阵键盘
sfr P4 = 0xC0;  //52的头文件没有P4口,需要我们自己定义

sbit R1 = P3^0;
sbit R2 = P3^1;
sbit R3 = P3^2;
sbit R4 = P3^3;

sbit C1 = P4^4;
sbit C2 = P4^2;
sbit C3 = P3^5;
sbit C4 = P3^4;

//0~9,A-F,“-”,“.”
unsigned char code SMG_Duanma[18]=
		{0xc0,0xf9,0xa4,0xb0,0x99,0x92,
		0x82,0xf8,0x80,0x90,0x88,0x80,
		0xc6,0xc0,0x86,0x8e,0xbf,0x7f};
		
//锁存器的选择 传参4是LED小灯接口,5是蜂鸣器继电器,6是数码管位置,7是数码管显示的数值
void SelectHC573(unsigned char channel)
{
	switch(channel)
	{
		case 4:
			P2 = (P2 & 0x1f) | 0x80;
		break;
		case 5:
			P2 = (P2 & 0x1f) | 0xa0;
		break;	
		case 6:
			P2 = (P2 & 0x1f) | 0xc0;
		break;	
		case 7:
			P2 = (P2 & 0x1f) | 0xe0;
		break;	
		case 0:
			P2 = (P2 & 0x1f) | 0x00;
	}

}
//==============================================//

//*****************初始化函数****************//
void InitSystem()
{
	SelectHC573(4);
	P0 = 0xff;
	SelectHC573(5);
	P0 = 0x00;
	SelectHC573(0);
}
//==============================================//

//*****************PCF8591****************//
//读取电位器Rb2(03)或者光敏rd1
void ReadRd1()
{
	IIC_Start();
	IIC_SendByte(0x90);
	IIC_WaitAck();
	IIC_SendByte(0x30);
	IIC_WaitAck();
	
	IIC_Start();
	IIC_SendByte(0x91);
	IIC_WaitAck();
	rb2 = IIC_RecByte();
	IIC_SendAck(1);
	IIC_Stop();
}
//==============================================//

//*****************PCF实现D/A、A/D************//
void PCFADC()
{
	IIC_start();
	IIC_SendByte(0x90); //     9是1001为固定部分  后面可编程部分0写1读
	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(unsigned char dat)
{
	IIC_Start();
	IIC_SendByte(0x90);
	IIC_WaitAck();
	IIC_SendByte(0x40);
	IIC_WaitAck();
	IIC_SendByte(dat);   //输入255对应输出为5V
	IIC_WaitAck();
	IIC_Stop();
}
//==============================================//

//*****************AT24C02*********************//
unsigned char 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(注意Delay的必须是uint类型的);还要注意写入和读取出来的数据都是小于255,否则需要处理才能写入
{
	IIC_Start();
	IIC_SendByte(0xa0);
	IIC_WaitAck();
	IIC_SendByte(addr);
	IIC_WaitAck();
	IIC_SendByte(dat);
	IIC_WaitAck();
	IIC_Stop();	
}
//==============================================//


//*******************DS18B20*******************//
void Read_Temp() //当显示出现错误时,可能是底层代码函数提供的频率为12MHZ,而开发板的频率为1MHZ,所以把底层驱动代码所有延时函数时间扩大10倍或者12倍
{
	unsigned char LSB; //低八位
	unsigned char MSB; //高八位
	
	init_ds18b20();
	Write_DS18B20(0xcc);//跳过row字节
	Write_DS18B20(0x44);//装换温度
	Delay_OneWire(80);//延时 等待温度转换完成
	
	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0xbe);//存储温度
	
	
//  <1> CCH:跳过ROM指令,忽略64位ROM地址,直接向DS18B20发起各种温度转换指令。
// <2> 44H:温度转换指令,启动DS18B20进行温度转换,转换时间最长为500ms(典型值为200ms),结果保存在高速RAM中。
// <3> BEH:读暂存器指令,读取高速暂存存储器9个字节的内容。
	
	LSB = Read_DS18B20(); //低八位先出来
	MSB = Read_DS18B20();  //高八位后出来
	init_ds18b20();       //DS18B20复位,停止温度读取
	tem = MSB & 0x0f;    //去掉MS BYTE前的SSSS
	tem = (tem << 8) | LSB; //将低八位和高八位合并
	
	if ((tem & 0xf800) == 0x0000)	 //判断温度正负,高五位为符号位 0为正 1为负
	{
		tem = tem >> 4; //相当于*0.0625  为什么右移四位相当于*0.0625
	}
	
	//国赛可能需要精确到小数点后几位
	/*if ((temp & 0xf800) == 0x0000)
	{
		temp = temp >> 4;//先把小数位都移走
		temp = temp * 10;
		temp = temp + (LSB & 0x0f) * 0.0625 * 10;	 //扩大十倍后的整数部分加上小数部分(小数部分每一个数表示0.0625 C)
	}*/	
}
//============================================================//
	
//*******************DS1302******************//
void Write_Timer()
{
	unsigned char i;
	Write_Ds1302_Byte(0x80,0x00);
	for(i = 0;i<=7;i++)
	{
		Write_Ds1302_Byte(Writeaddr[i],Timer[i]);
	}
	Write_Ds1302_Byte(0x80,0x80);	
}

void Read_Timer()
{
unsigned char i;
	for(i = 0;i <= 7;i++)
	{	
		Timer[i] = Read_Ds1302_Byte(Readaddr[i]);	
	}
}
//时钟BCD码加
uchar BCD_add(unsigned char 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码减
uchar BCD_minus(unsigned char 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自动输出一定频率的信号到SIGNAL引脚,用跳帽连接P34(T0),然后用定时器的T0计数功能
void InitTime()
{
	TMOD = 0x16;
	
	TH1 = (65535-100)/256;
	TL1 = (65535-100)%256;
	TH0 = 0xff;
	TH1 = 0xff;
	
	TR0 = 1;
	TR1 = 1;
	ET0 = 1;
	ET1 = 1;
	EA = 1;	
}

void ServiceT0() interrupt 1
{
	f_c++;
}

void ServiceT1() interrupt 3
{
	TH1 = (65535-100)/256;
	TL1 = (65535-100)%256;
	
	count++;
	if(count >= 10000)
	{
		dat_f = f_c;
		count = 0;
		f_c= 0;
	}
	//数码管实现秒闪
	count++;
	if (count >= 10000)
	{
		count = 0;
		smg_f = ~smg_f;
	}
	
	//pwm脉宽调制					   //共一百份,下面的函数给pwm_t赋值,pwm_f作为控制开关
	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;
	TL1 = 0xfd;
	TR1= 1;
	ES = 1;	
	EA = 1; 
	
	AUXR = 0x00;
	SCON = 0x50;
}

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

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

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

}

void ExecuteCommand ()//这个函数是用来判断啥的????????
{
	if (command != 0x00)
	{
		switch (command & 0xf0)
		{
			case: 0xa0:
				//
				command = 0x00;
				break;
			case: 0xb0:
				//
				command = 0x00;
				break;
				//...
		}
	}
}

//============================================================//


//*******************数码管******************//
void Delay_SMG(unsigned int t)
{
	while(t--);
}

void ShowSMG_Bit(unsigned char value,unsigned char pos)
{
	SelectHC573(7);
	P0 = 0xff;
	SelectHC573(6);
	P0 = 0x01 << pos-1;
	SelectHC573(7);
	P0 = value;
	SelectHC573(0);
}

void ShowALlSMG(unsigned char dat)
{
	SelectHC573(6);
	P0 = 0xff;
	SelectHC573(7);
	P0 = dat;
}

void ShowSMG() //这个函数是用来干嘛的
{
if (k4 == 0)
	{
		ShowSMG_Bit(1,0xc1);
		Delay_SMG (500);
		ShowSMG_Bit(6,duanmadot[dat_u / 100]);
		Delay_SMG (500);
		ShowSMG_Bit(7,duanma[(dat_u / 10) % 10]);
		Delay_SMG (500);
		ShowSMG_Bit(8,duanma[dat_u % 10]);
		Delay_SMG (500);	
	}
	else if (k4 == 1)
	{
		ShowSMG_Bit(1,0x8e);
		Delay_SMG (500);
		if (dat_f > 99999)
		{
			ShowSMG_Bit(3,duanma[(dat_f / 100000) % 10]);
			Delay_SMG (500);	
		}
		if (dat_f > 9999)
		{
			ShowSMG_Bit(4,duanma[(dat_f / 10000) % 10]);
			Delay_SMG (500);	
		}
		if (dat_f > 999)
		{
			ShowSMG_Bit(5,duanma[(dat_f / 1000) % 10]);
			Delay_SMG (500);
		}
		if (dat_f > 99)
		{
			ShowSMG_Bit(6,duanma[(dat_f / 100) % 10]);
			Delay_SMG (500);
		}
		if (dat_f > 9)
		{
			ShowSMG_Bit(7,duanma[(dat_f / 10) % 10]);
			Delay_SMG (500);
		}
		ShowSMG_Bit(8,duanma[(dat_f / 1) % 10]);
		Delay_SMG (500);	
	}
	All_SMG(0xff);	
}
//============================================================


//*************************独立按键*********************
void Dealy(unsigned char t)
{
	while(t--);
}

void ScanKeys()
{
	if(S4 == 0)
	{
	Delay(500);
		if(S4 == 0)
		{
		while(S4 == 0)
			{
				//
			
			}
		}
	
	}
	
	if(S5 == 0)
	{
	Delay(500);
		if(S5 == 0)
		{
		while(S5 == 0)
			{
				//
			
			}
		}
	
	}	
	
	if(S6 == 0)
	{
	Delay(500);
		if(S6 == 0)
		{
		while(S6 == 0)
			{
				//
			
			}
		}
	
	}	
	
	if(S7 == 0)
	{
	Delay(500);
		if(S7 == 0)
		{
		while(S7 == 0)
			{
				//
			
			}
		}
	
	}	
	
}
//===================================================


//*******************矩阵键盘***************************
void ScanKeysMulti()
{
	R1 = 0;
	R2 = R3 = R4 = 1;
	C1 = C2 = C3 = C4 =1;
	if(C1 == 0)
	{
	 //S7
	}
	else if(C2 == 0)
	{
	 
	}
	else if(C3 == 0)
	{
	 
	}	
	else if(C4 == 0)
	{
	 
	}	
	
	R2 = 0;
	R1 = R3 = R4 = 1;
	C1 = C2 = C3 = C4 =1;
	if(C1 == 0)
	{
	 
	}
	else if(C2 == 0)
	{
	 
	}
	else if(C3 == 0)
	{
	 
	}	
	else if(C4 == 0)
	{
	 
	}		
	
//.........
	
}

//*********************超声波************************
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 (来回)
	}
}

void Delay (uchar n)								  //多次显示,效果更好一点
{
	while (n--)
	{
	   ShowSMG ();
	}
}
//=========================================================

void main()
{
while(1)
{}
}











评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值