最全蓝桥杯单片机比赛代码模板

LED灯是低电平点亮(0),蜂鸣器继电器是高电平打开 (1)

继电器是P04端口,开启继电器是P0=0x10;

蜂鸣器是P08端口,开启蜂鸣器是P0=0x80;

按键按下(S5==0)为低电平
int=32位 char=8位 bit=1位
开关标志变量的话,则定义为bit型数据,例如 SMG_flash=1; LED_off_on=0;
计数变量的话,则定义为unsigned int型数据,例如 unsigned int SMG_count=0; unsigned int LED_count=0。普通变量则定义为unsigned char。

{0xbf,0x7f}// - .

{0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};
// 0. 1. 2. 3. 4. 5. 6. 7. 8. 9.

注意变量范围是使用char 还是int (int比char大)

与 & 或 |

0 0 0 0 0 0

0 1 0 0 1 1

1 0 0 1 0 1

1 1 1 1 1 1

0000001004100081100c
0001101015100191101d
00102011061010a1110e
00113011171011b1111f
00011001020100410008
1110e1101d1011b01117

数码管断码,不亮的是1,亮的是0(共阳极连接)

程序框架

#include "reg52.h"
#include "iic.h"//ICC总线底层驱动
#include "ds1302.h"//DS1302实时时钟底层驱动
#include "onewire.h"//DS18B20温度传感器底层驱动


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

系统初始化

void Init_system()
{
	selectHC573(5);      //控制蜂鸣器与继电器
	P0=0x00;
	selectHC573(4);      //控制LED灯
	P0=0xff;
}

延迟函数

//普通延迟函数(int类型)(延迟时间长)  
void delay(unsigned int t)
{
	while(t--);
}
//char类型延迟函数(延迟时间短)
void delay_key(unsigned char t)
{
	while(t--);
}

数码管数字编码

unsigned char code SMG_duanma[18]=
{0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x80,0xc6,0xc0,0x86,0x8e,0xbf,0x7f};
// 0   1    2    3    4    5    6   7    8    9     A   B    C    D     E   F     -    .
unsigned char code SMG_dot[10]=
{0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};
// 0.   1.   2.    3.   4.   5.   6.  7.   8.   9. 

锁存器选择

I/O模式

跳帽J13的23短接

void selectHC573(unsigned char channel)
{
	switch(channel)
	{
		case 4:P2=(P2&0x1f)|0x80; break;  //控制LED灯
		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; break; 
	}
}
MM模式

跳帽J13的12短接

#include "absacc.h"//引用头文件(里面包含需要用到XBYTE关键字)
XBYTE[0x8000]=0x00;   //LED灯        //selectHC573(4); P0=0x00;
XBYTE[0xa000]=0x00;   //蜂鸣器与继电器 //selectHC573(5); P0=0x00;
XBYTE[0xc000]=0x01;   //数码管位选    //selectHC573(6); P0=0x00;
XBYTE[0xe000]=0x00;   //数码管内容    //selectHC573(7); P0=0x00;

LDE独立按键矩阵按键连接

LED灯的连接
sbit L1=P0^0;
sbit L2=P0^1;
sbit L3=P0^2;
sbit L4=P0^3;
sbit L5=P0^4;
sbit L6=P0^5;
sbit L7=P0^6;
sbit L8=P0^7;
独立键盘的连接
sbit S7 = P3^0;
sbit S6 = P3^1;
sbit S5 = P3^2;
sbit S4 = P3^3;
矩阵按键的连接
//4x4矩阵键盘
sfr P4=0xC0;//头文件reg52.h中没有P4接口,所以当用到P4接口时要加上这一句
sbit R1=P3^0;//行(R)
sbit R2=P3^1;
sbit R3=P3^2;
sbit R4=P3^3;
sbit C4=P3^4;//列(C)
sbit C3=P3^5;
sbit C2=P4^2;
sbit C1=P4^4;

//2x2矩阵键盘(左下方2x2矩阵)
sfr P4=0xC0;//头文件reg52.h中没有P4接口,所以当用到P4接口时要加上这一句
sbit R1=P3^2;//行(R)
sbit R2=P3^3;
sbit C2=P4^2;
sbit C1=P4^4;

//2x2矩阵键盘(右下方2x2矩阵)
sbit R1=P3^2;
sbit R2=P3^3;
sbit C2=P3^4;
sbit C1=P3^5;

LED灯

依次点亮与熄灭
void LEDrunning()
{
	unsigned char i;
	for(i=0;i<=8;i++)
	{
		selectHC573(4);  //控制LED灯
		P0=0xff<<i;      //<<左移运算符,将P0从11111111,设置到00000000
		delay(60000);
		selectHC573(0);
	}
	for(i=0;i<=8;i++)
	{
		selectHC573(4);  //控制LED灯
		P0=~(0xff<<i);
		delay(60000);
		selectHC573(0);
	}	
}
LED闪烁五秒后停止

单个LED以0.1秒为间隔闪烁5s后熄灭

void Init_T0()
{
	TMOD=0x01;              //也就是二进制0001,定时器0定时功能,16位模式
	TH0=(65535-10000)/256;  //0.1秒
	TL0=(65535-10000)%256;
	EA=1;                   //总中断打开
	ET0=1;                  //定时中断使能
	TR0=1;                  //启动定时器
}
bit LED_k=0;//控制数LED开关的标志变量,表示闹铃响起
bit LED_f=0;//控制数LED闪烁的标志变量,当LED_f=1的时候,表示LED等亮起
unsigned int LED_c=0;//控制LED的计数变量变量,LED闪烁的周期为0.1秒,闪烁的时间为5秒
void Service_T0() interrupt 1
{
	TH0=(65535-10000)/256;        //0.01秒
	TL0=(65535-10000)%256;
	if(LED_k==1)
	{
		LED_c++;
		if(LED_c % 10 == 0)    //0.1秒
		{
			LED_f=~LED_f;      //LED闪烁
			if(LED_c>=500)     //持续5秒关闭所有标志
			{
				LED_k=0;
				LED_f=0;
				LED_c=0;
			}
		}
	}
}
//当需要LED闪烁时候,打开LED开关,即LED_k=1;
//LED_f控制某个特定LED的闪烁

数码管

单个数码管动态显示
void DisSMG_bit(unsigned char dat,unsigned char pos)
{
	selectHC573(6);  //数码管位选
	P0=0x01<<pos;
	selectHC573(7);  //数码管内容
	P0=dat; 
	delay(500);      //数码管动态显示需要的延迟函数
	selectHC573(0);
}
数码管统一操作函数
void DisSMG_all(unsigned char dat)//在某些数码管动态后统一关闭数码管
{
	selectHC573(6);  //数码管位选
	P0=0xff;
	selectHC573(7);  //数码管内容
	P0=dat;
	selectHC573(0);
}
数码管动态显示
void DisSMG()
{
	if(SMG_stat==0)
	{
		DisSMG_bit(SMG_duanma[0],0);         
	}
	if(SMG_stat==1)
	{
		DisSMG_bit(SMG_duanma[1],0);       
	}
	if(SMG_stat==2)
	{
		DisSMG_bit(SMG_duanma[2],0);         
	}
	DisSMG_all(0xff);                     //统一关闭数码管
}
数码管闪烁

符号“-”一秒闪烁一次

//在定时器中设置SMG_f 1秒反转一次
if(SMG_f==1)
{
	DisSMG_bit(SMG_duanma[16],2);
}
//当SMG_f==0时候数码管不显示

时分秒一秒闪烁一次

//SMG_flash=1本身就为1,而且无论什么情况下,SMG_flash一直是1、0、1、0的变化
//四个相或,只要有一个为1最后结果就为1,当SMG_flash在1、0变化时候,这个if条件判断也在1、0之间变换
//k7为0时钟显示,k7为1设置时,k7为2设置分,k7为3设置秒
//在定时器中设置SMG_f 1秒反转一次
if(((k7==1)&(SMG_f==1))|(k7==0)|(k7==2)|(k7==3))//时闪烁
{
	DisSMG_bit(SMG_duanma[Timer[2]/16],0);
	DisSMG_bit(SMG_duanma[Timer[2]%16],1);
}  
DisSMG_bit(SMG_duanma[16],2);
if(((k7==2)&(SMG_f==1))|(k7==0)|(k7==1)|(k7==3))//分闪烁
{
	DisSMG_bit(SMG_duanma[Timer[1]/16],3);
	DisSMG_bit(SMG_duanma[Timer[1]%16],4);
}	
DisSMG_bit(SMG_duanma[16],5);		
if(((k7==3)&(SMG_f==1))|(k7==0)|(k7==2)|(k7==1))//秒闪烁
{
	DisSMG_bit(SMG_duanma[Timer[0]/16],6);
	DisSMG_bit(SMG_duanma[Timer[0]%16],7);
}
数码管计数显示
if(times>999)
{
	DisSMG_bit(SMG_duanma[(times/1000)%10],5);
}
if(times>99)
{
	DisSMG_bit(SMG_duanma[(times/100)%10],5);
}
if(times>9)
{
	DisSMG_bit(SMG_duanma[(times/10)%10],6);
}				
DisSMG_bit(SMG_duanma[times%10],7);

按键

独立按键的扫描
void scan_key()
{
	if(S7==0) 
	{
		delay_key(20);  //此方法可以防止干扰 
		if(S7==0)
		{
			while(S7==0)
			{
	     		//按键不松开,S7一直为0,一直执行while语句,当S7按键松开,S7为1,才会执行下一条语句
			}
            
		}
	}
	if(S6==0)
	{
		//.....	
	}
}
//这里的else必须加上,不然程序会一直往下走,走了一圈,然后回到原本位置
if(SMG_stat==0)
{
	SMG_stat=1;
}
else if(SMG_stat==1)
{
	k5=0;
	SMG_stat=2;
}
else if(SMG_stat==2)
{
	SMG_stat=0;
}
矩阵按键的扫描

4x4矩阵键盘

void scan_key()
{
	R1=0;           //扫描第一行,其他行都为零
	R2=R3=R4=1;
	C1=C2=C3=C4=1;
	if(C1==0)       //C1==0时就是按下第一行第一列的时
	{
		delay_key(20);
		if(C1==0)
		{
			while(C1==0) 
			{		
			}
	
		}
	}
	if(C2==0)  //按下第一行第二列的时
	{
		//.....	
	}
	if(C3==0)  //按下第一行第三列的时
	{
		//.....	
	}
	if(C4==0)  //按下第一行第四列的时
	{
		//.....	
	}
	
	R2=0;           //扫描第二行,其他行都为零
	R1=R3=R4=1;
	C1=C2=C3=C4=1;
	//········
}

2x2矩阵键盘

void scankey()
{
	R1=0;           //扫描第一行,其他行都为零
	R2=1;
	C1=C2=1;
	if(C1==0)
	{
		delay_key(20);
		if(C1==0)
		{
			while(C1==0)
			{
			}			
		}
	}
	if(C2==0)
	{
		//.....	
	}
	
	R2=0;           //扫描第二行,其他行都为零
	R1=1;
	C1=C2=1;
	//......
}
按键的长按与短按
unsigned char k4=0;  //S4按键按下标志位,1表示按键按下
void Init_T0()
{
	TMOD=0x01;               
	TH0=(65535-10000)/256;   //0.01s
	TL0=(65535-10000)%256;
	EA=1;                    
	ET0=1;                  
	TR0=1;                  
}
unsigned int count=0;       
void Service_T0() interrupt 1
{
	TH0=(65535-10000)/256;  //0.01s
	TL0=(65535-10000)%256;
	if(k4==1)       //在按键按下期间进行计数
	{
		count++;    //按键按下的持续时间
	}
}

void scan_key
{
    if(S4==0)
    {
        delay_key(50);
        if(S4==0)
        {
        	count=0;       //从头开始计数
        	k4=1;          //S4按下标志位
        	while(S4==0)
        	{
        		DisSMG();
        	}
        	k4=0;           //按键松开
        	if(count>100)   //表示按下超过1s
        	{
        		//长按相应操作
        	}
        	else            //按下不超过1s
        	{
        		//短按相应操作
        	}
        }
    }
}

外部中断0

//初始化函数
void Init_INT0()
{
	EA=1;   //打开总中断
	EX0=1;  //打开外部中断使能
	IT0=1;  //选择外部中断0为下降沿出发,当IT0=0时选项低电平触发
}
//中断服务函数
void Service_INT0() interrupt 0
{
	//编写中断服务逻辑代码
}

定时器0

//初始化函数 
void Init_T0()
{
	TMOD=0x01;               //也就是二进制0001,定时器0定时功能,16位模式
	TH0=(65535-50000)/256;   //0.05秒 
	TL0=(65535-50000)%256;
	EA=1;                    //总中断打开
	ET0=1;                   //定时中断使能
	TR0=1;                   //启动定时器
}
//中断服务函数
unsigned int count=0;       //计数
void Service_T0() interrupt 1
{
	TH0=(65535-50000)/256; //0.05s
	TL0=(65535-50000)%256;
	count++;
	//编写中断服务函数逻辑代码
}

PWM调波

unsigned char PWM_c=0;    //PWM计数
unsigned char PWM_t=20;   //占空比,20表示20%
unsigned char PWM_f=1;    //PWM输出表示位,1表示开始输出,0表示停止输出
void Init_T0()
{
	TMOD=0x01;
	TH0=(65535-100)/256;  //0.0001s
	TL0=(65535-100)%256;
	TR0=1;
	ET0=1;
	EA=1;
}
void service_T0() interrupt 1
{
	TH0=(65535-100)/256;
	TL0=(65535-100)%256;

	PWM_c++;
	if(PWM_c>=PWM_t)
	{
		PWM_f=0;    //0表示停止输出
	}
	if (PWM_c>=100)
	{
		PWM_f=1;    //1表示开始输出
		PWM_c=0;
	}
}
//按下按键调整对应占空比PWM_t
//在PWM_out()函数中设置在PWM_f=1时进行相应输出(LED灯、蜂鸣器等),在PWM_f=0时停止相应输出

555模块

//J13中NAL与P34短接,调整Rb3即可调整555定时器的频率
void Init_T()
{
	TH0=0xff;                 //定时器0用作计数,8位重装模式
	TL0=0xff;
	TH1=(65535-50000+1)/256;  //定时器1用作计数,定时时间位50ms(0.05s)
	TL1=(65535-50000+1)%256;
	TMOD=0x16;                //0001 0110
	EA=1;
	ET0=1;
	ET1=1;	
	TR1=1;
	TR0=1;
}
unsigned int count_f=0;      //记录脉冲个数
unsigned int count_c=0;      //计数
unsigned int dat_f=0;        //从count_f中提取的脉冲个数
void service_T0() interrupt 1   //计算脉冲个数
{
	 count_f++;
}
void service_T1() interrupt 3   //定时1s
{
	TH1=(65535-50000+1)/256;
	TL1=(65535-50000+1)%256;
	count_c++;
	if(count_c==20)         //此时为1s
	{
		dat_f=count_f;     //取出上秒频率总数
		count_f=0;         //清零,计算下一秒的频率//此时上一秒的频率储存在dat_f中
		count_c=0;
	}
}
//dat_f就是测得的555模块的频率,后在数码管中显示出来即可

超声波测距

#include "intrins.h"//需要用到_nop_()

sbit TX=P1^0;
sbit RX=P1^1;

unsigned int distance=0;
void delay12us()            //@12.000MHz 延时12us
{
	unsigned char i;
	_nop_();
	_nop_();
	i = 33;
	while (--i);
}
void Send_wave()              //产生8个40KHx超声波信号
{
	unsigned char i;
	for(i = 0; i < 8; i++)
	{
		TX = 1;
		delay12us();	
		TX = 0;
		delay12us();
	}
}
void Measure_Distance()	       //超声波测距
{
	unsigned int time = 0;
	TMOD &= 0x0f;	            //定时器1模式0,13位,最大8192个计数脉冲					
	TH1 = 0x00;										
	TL1 = 0x00;		
	
	Send_wave();		        //发送超声波信号							
	TR1 = 1;            //启动定时器						
	while((RX == 1) && (TF1 == 0));    //等待超声波信号返回或者等到测量超出范围
	TR1 = 0;            //停止定时器				
	if(TF1 == 0)	            //正常测量范围							
	{
		time = TH1;									
		time = (time << 8) | TL1;		
		distance = ((time / 10) * 17) / 100 + 3;
	}
	else                        //超出测量范围			
	{
		TF1 = 0;
		distance = 999;
	}
}
//distance就是测量出的距离,当超过测量范围的时候,distance=999

串口通信

sfr AUXR=0x8e; //新增辅助寄存器,reg52.h头文件没有,是蓝桥杯板子专有的

void Init_uart()
{
	TMOD=0x20;  //定时器1工作模式为自动重装
	TH1=0xfd;   //设置波特率为9600
	TL1=0xfd;   //11.0592或者12HM的12分频
	TR1=1;      //启动定时器1
	
	SCON=0x50;  //八位工作模式,允许接收
	AUXR=0x00;  //辅助寄存器
	ES=1;       //使能串口中断
	EA=1;       //使能串口中断
}

//发送单个字节
void Send_byte(unsigned char dat)
{
	SBUF=dat;      //将数据放入SBUF缓冲器
	while(TI==0);  //等待发送完成,发送完成后TI=1;
	TI=0;          //清除发送完成标志
}
//发送字符串,在c中字符串就是指针
void Send_string(unsigned char *str)//*str是指针
{
	while(*str!='\0')        //字符串中的字符从第一位一个个发送,直到发送到最后一个字符\0时停止发送
	{              
		Send_byte(*str++);   //指针指向下一个字符
	}
}

unsigned char urdat;
void Service_uart() interrupt 4
{
	if(RI==1)               //判断是否接收到完整数据
	{
		RI=0;               //清除接受完成标志
		urdat=SBUF;         //如果要根据接受的信号做出相应反应则对urdat进行判断
		Send_byte(urdat);   //发送urdat
	}	
}
//后面就可以使用Send_byte()和sendstring(),发送字节或者发送字符串

DS1302时间显示

unsigned char Write_DS1302_add[3]={0x80,0x82,0x84};
unsigned char Read_DS1302_add[3]={0x81,0x83,0x85};
                      //  秒   分   时  星期   日   月   年  
unsigned char Timer[3]={0x55,0x59,0x23};  

void Init_DS1302()
{
	char i;
	Write_Ds1302_Byte(0x8e,00);    //打开寄存器写保护功能,允许向内存写入地址
	for(i=0;i<3;i++)//i根据情况调整  //写入七个字节时间参数
	{
		Write_Ds1302_Byte(Write_DS1302_add[i],Timer[i]);//写入时间
	}
	Write_Ds1302_Byte(0x8e,80);    //恢复寄存器的写保护,禁止向内存写入数据
}

void Read_time()
{
	char i;
	for(i=0;i<3;i++)//i根据情况调整  //读取7个字节的实时时间
	{
		Timer[i]=Read_Ds1302_Byte(Read_DS1302_add[i]);//读出此时的时间
	}
}
//Timer[i]就是读取后的时间,随后利用数码管的动态显示,在数码管中显示出来(秒分时的十位与个位除以16)

从DS1302中读出来的时间十BCD码格式的,在进行按键设置的时候,要将BCD转换为十进制数后再更新然后再转回BCD码。(BCD——十进制——加加减减——BCD)

unsigned char BCDtoTEN(unsigned char dat)//BCD转十进制
{
	dat = (dat/16)*10 + dat%16; 
	return dat;
}
unsigned char TENtoBCD(unsigned char dat)//十进制转BCD
{
	dat = (dat/10)*16 + dat%10; 
	return dat;
}
unsigned char timeradd(unsigned char dat)//将BCD转为十进制后加一后再转回BCD
{
	dat=BCDtoTEN(dat);
	dat=dat++;
	dat=TENtoBCD(dat);
	return dat;
}
unsigned char timermiuns(unsigned char dat)//将BCD转为十进制后减一后再转回BCD
{
	dat=BCDtoTEN(dat);
	dat=dat--;
	dat=TENtoBCD(dat);
	return dat;
}

if(k7==1)//时钟加一
{
	Timer[2]=timeradd(Timer[2]);
	if(Timer[2]>=TENtoBCD(24))
	{
		Timer[2]=0;
	}
}
if(k7==1)//时钟减一
{
	Timer[2]=timermiuns(Timer[2]);
	if(Timer[2]<=0)
	{
		Timer[2]=TENtoBCD(23);//十:23
	}
}	
//如果只是单独的设置闹铃,显示的数不是从DS1302中提取出来的,则和BCD码没有关系
//而且定义闹铃的时候直接就是clock[3]={0,0,0};//无需加上0x

DS18B20温度读取

unsigned int temper=0;  //定义一个存放温度得变量
void DisSMG(); 

void Read_temper()
{
	unsigned char LSB,MSB; //定义两个变量接收温度低八位与高八位
	
	init_ds18b20();        //初始化DS18B20
	DisSMG();			   //动态刷新数码管
	
	Write_DS18B20(0xcc);   //跳过rom指令
	Write_DS18B20(0x44);   //转换温度,启动DS18B20进行温度转换,结果保存在高速RAM中
	DisSMG();			   //动态刷新数码管
	
	init_ds18b20();        //初始化DS18B20
	DisSMG();			   //动态刷新数码管
	
	Write_DS18B20(0xcc);   //跳过ROM指令,忽略64位ROM地址,直接向DS18B20发起温度转换指令
	Write_DS18B20(0xbe);   //读数据指令,读取高速暂存存储器9个字节的内容
	DisSMG();			   //动态刷新数码管
	
	LSB=Read_DS18B20();    //读取温度低八位
	MSB=Read_DS18B20();    //读取温度高八位
	temper=MSB;              //先把高八位赋给temp
	temper=(temper<<=8)|LSB; //将temp左移八位,将低八位空出来后或上LSB组成16位温度数据
	
	//保留整数部分
	temper=temper*0.0625;
	
	//保留一位小数
	temper=temper*0.0625*10;
	
	//保留二位小数
	temper=temper*0.0625*100;	
	
    DisSMG();
}
//temper就是读取后的温度,随后利用数码管的动态显示,在数码管中显示出来

PCF8591

光敏电阻电压AD
unsigned int lingt=0;
void Read_lignt()
{
	I2CStart();        //IIC总线起始信号
	I2CSendByte(0x90); //PCF8951的写设备地址
	I2CWaitAck();      //等待从机应答
	I2CSendByte(0x01); //写入PCF8591的控制字节, 光敏传感器接到AIN1,通道1;控制寄存器应写入:0x01
	I2CWaitAck();      //等待从机应答
	I2CStop();         //IIC总线停止信号
	
	DisSMG();
	
	I2CStart();              //IIC总线起始信号
	I2CSendByte(0x91);       //PCF8951的读设备地址
	I2CWaitAck();            //等待从机应答
	lignt=I2CReceiveByte();  //读取PCF8591通道3的数据
	lignt=lignt*1.961;
	I2CSendAck(1);           //产生非应答信号
	I2CStop();               //IIC总线停止信号
}
//lignt就是读取后的光敏电阻电压,随后利用数码管的动态显示,在数码管中显示出来
可变电阻电压AD
unsigned int rb2 = 0;	
void Read_rb2()
{
	I2CStart();         //IIC总线起始信号
	I2CSendByte(0x90);  //PCF8951的写设备地址
	I2CWaitAck();       //等待从机应答
	I2CSendByte(0x03);  //写入PCF8591的控制字节,电位器Rb2接到AIN3,通道3;控制寄存器应写入:0x03
	//没有DAC都用0x03,当题目中又DAC则用0x43
	I2CWaitAck();       //等待从机应答
	I2CStop();          //IIC总线停止信号

	DisSMG();

	I2CStart();          //IIC总线起始信号
	I2CSendByte(0x91);   //PCF8951的读设备地址
	I2CWaitAck();        //等待从机应答
	rb2=I2CWaitAck();    //读取PCF8591通道3的数据
	rb2=rb2*1.961;
	I2CSendAck(1);       //产生非应答信号
	I2CStop();           //IIC总线停止信号
}
//rb2就是读取后的电阻电压,随后利用数码管的动态显示,在数码管中显示出来
//看要求是电压显示几位小数,显示5V是显示50还是500
DAC电压输出
unsigned  int VANI3=0;
void Read_VANI3()
{
	I2CStart();
	I2CSendByte(0x90);
	I2CWaitAck();
	I2CSendByte(0x43);    //有DAC输出则需要用43
	I2CWaitAck();
	I2CStop();
	
	DisSMG();
	
	I2CStart();
	I2CSendByte(0x91);
	I2CWaitAck();
	VANI3=I2CReceiveByte();
	VANI3=VANI3*1.961;
	I2CSendAck(1);
	I2CStop();
}

void Read_DAC(unsigned char dat)
{
	I2CStart();
	I2CSendByte(0x90);
	I2CWaitAck();
	I2CSendByte(0x43);
	I2CWaitAck();
	I2CSendByte(dat);
	I2CWaitAck();
	I2CStop();
}
//纯DAC输出 后面要输出什么直接Read_DAC(dat);(数据就可以);

DAC数据输出

在这里插入图片描述

当输出关系如上图所示时候输出函数如下(不需要数码管显示)

distance是两位数字

void DAC_out()
{
	if(ceju_k==1)
	{
		if(distance<=20)
		{
			Read_DAC(255/5);     //此时输出电压是1
		}
		else if(distance>20&&distance<80)
		{
			Read_DAC((255/5)*(1/15)*(distance-3));
		}
		else if(distance>80)
		{
			Read_DAC(255/5*5);   //此时输出电压是5
		}
	}
	if(ceju_k==0)
	{
		Read_DAC(0);
	}
}

在这里插入图片描述

当输出关系如上图所示时候输出函数如下(需要数码管显示)

temper是四位数字,所以要temper/100

DAC_dat是数码管显示中的数值

void DAC_out()
{
	if(K5_mode==1)
	{
		if(temper<=2000)
		{
			Read_DAC_dat(255/5);   //此时输出电压是1
			DAC_dat=100;           //输出电压1.00
		}
		else if(temper<=4000&&temper>=2000)
		{
			Read_DAC_dat((255/5)*0.15*((temper/100)-2));
			DAC_dat=(0.15 * (temper/100) - 2) * 100;
		}
		else if(temper>=4000)
		{
			Read_DAC_dat(255/5*4);  //此时输出电压是4
			DAC_dat=400;            //输出电压4.00
		}
	}
}

24C02储存器

//24C02储存器写操作
void Write_24C02(unsigned char add,unsigned char dat)
{
	I2CStart();		     //IIC总线起始信号	
	I2CSendByte(0xa0);   //24C02的写设备地址,写操作地址则为:0xa0
	I2CWaitAck();		 //等待从机应答	
	I2CSendByte(add); 	 //内存字节字节
	I2CWaitAck(); 		 //等待从机应答	
	I2CSendByte(dat); 	 //写入目标数据
	I2CWaitAck();		 //等待从机应答	
	I2CStop();		     //IIC总线停止信号	
}
//24C02储存器读操作
unsigned char Read_24C02(unsigned char add)
{
	unsigned char temp;   //进行一个伪写操作
	I2CStart();		      //IIC总线起始信号			
	I2CSendByte(0xa0);    //24C02写设备地址
	I2CWaitAck();		  //等待从机应答	
	I2CSendByte(add); 	  //内存自己地址
	I2CWaitAck(); 		  //等待从机应答

	I2CStart();		         //IIC总线起始信号			
	I2CSendByte(0xa1);       //24C02读设备地址
	I2CWaitAck();		     //等待从机应答	
	temp = I2CReceiveByte(); //读取目标数据
	I2CSendAck(1); 	         //产生非应答信号		
	I2CStop();		         //IIC总线停止信号
	return temp;
}
//将某个数据写入24c02:Write_24C02(地址,数据);
//将写入24c02的数据读出来:Read_24C02(地址);
//如若要断电后存储数据,则在对应数据更新时就可以将数据写入,后在main函数中while函数前读取。

底层驱动程序文件

iic.h
#ifndef _IIC_H
#define _IIC_H

void I2CStart(void); 
void I2CStop(void); 
unsigned char I2CWaitAck(void); 
void I2CSendAck(unsigned char ackbit);
void I2CSendByte(unsigned char byt);
unsigned char I2CReceiveByte(void); 

#endif
iic.c
#include "reg52.h"
#include "iic.h"
#include "intrins.h"

sbit sda=P2^1;
sbit scl=P2^0;
ds1302.h
#ifndef __DS1302_H
#define __DS1302_H

void Write_Ds1302(unsigned  char temp);
void Write_Ds1302_Byte( unsigned char address,unsigned char dat );
unsigned char Read_Ds1302_Byte ( unsigned char address );

#endif
ds1302.c
#include "reg52.h"
#include "intrins.h"
#include "ds1302.h"

sbit SCK=P1^7;		
sbit SDA=P2^3;		
sbit RST = P1^3;
onewire.h
#ifndef __ONEWIRE_H
#define __ONEWIRE_H

#include "reg52.h"

bit init_ds18b20(void);
void Write_DS18B20(unsigned char dat);
unsigned char Read_DS18B20(void);

#endif
onewire.c
#include "reg52.h"
#include "onewire.h"

sbit DQ = P1^4; 
  • 72
    点赞
  • 115
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值