单片机11-13

news2024/9/28 3:23:54

目录

蜂鸣器

蜂鸣器播放按键提示音

蜂鸣器播放音乐

AT24C02(IIC)总线

AT24C02数据存储

AT24C02秒表(定时器扫描按键)

DS18B20温度传感器(单总线)

温度显示

温度报警器


蜂鸣器

蜂鸣器播放按键提示音

Buzzer.c
 

#include <REGX52.H>
#include "INTRINS.h"
#include "Delay.h"
//蜂鸣器端口
sbit Buzzer = P2^5;
	
	/**
  * @brief  蜂鸣器私有延迟函数,延时500us
  * @param  无
  * @retval 无
  */
	void Buzzer_Delay500us()		//@11.0592MHz
{
	unsigned char i;

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

/**
  * @brief  蜂鸣器发生持续时间
  * @param  ms	发声时长
  * @retval 无
  */
void Buzzer_Time(unsigned int ms)
{
		unsigned int i;
	for(i = 0;i < ms *2;i++)//这里个人理解是持续时间(循环次数),如果要持续ms这么久
	//下面做一次就过去500us(0.5ms),要过去1000ms,则需要2000次,所以要*2
				{
					Buzzer = !Buzzer;
					Buzzer_Delay500us();//发出1000Hz频率声音
					//因为周期为1000微秒,即T = 0.001s,频率f = 1/T	,f = 1kHz
				}
}

main.c

#include <REGX52.H>
#include "Delay.h"
#include "Key.h"
#include "Nixie.h"
#include "Buzzer.h"

unsigned char KeyNum;


void main(){
		Nixie(1,0);
	while( 1 ){
		KeyNum = Key();
		
		if(KeyNum){
			
			Buzzer_Time(1000);//响的时间
			Nixie(1,KeyNum);
			
		}
	}

}
蜂鸣器播放音乐
#include <REGX52.H>
#include "Delay.h"
#include "Timer0.h"

sbit Buzzer = P2^5;

//播放速度,值为四分音符的时长(ms)
#define SPEED	500

//音符与索引对应表,P:休止符,L:低音,M:中音,H:高音,下划线:升半音符号#
#define P	0
#define L1	1
#define L1_	2
#define L2	3
#define L2_	4
#define L3	5
#define L4	6
#define L4_	7
#define L5	8
#define L5_	9
#define L6	10
#define L6_	11
#define L7	12
#define M1	13
#define M1_	14
#define M2	15
#define M2_	16
#define M3	17
#define M4	18
#define M4_	19
#define M5	20
#define M5_	21
#define M6	22
#define M6_	23
#define M7	24
#define H1	25
#define H1_	26
#define H2	27
#define H2_	28
#define H3	29
#define H4	30
#define H4_	31
#define H5	32
#define H5_	33
#define H6	34
#define H6_	35
#define H7	36

//索引与频率对照表
unsigned int FreqTable[]={
	0,
	63628,63731,63835,63928,64021,64103,64185,64260,64331,64400,64463,64528,
	64580,64633,64684,64732,64777,64820,64860,64898,64934,64968,65000,65030,
	65058,65085,65110,65134,65157,65178,65198,65217,65235,65252,65268,65283,
};

//曲谱以及持续时长
unsigned char code Music[]={
	P,4,
	P,4,
	P,4,
	M6,2,
	M7,2,
	
	H1,4+2,
	L7,2,
	H1,4,
	H3,4,
	
	M7,4+4+4,
	M3,2,
	M3,2,
	
	M6,4+2,
	
};

unsigned char FreqSelect,MusicSelect;

void main(){
	
	Timer0Init();
	
	while( 1 ){
		if(Music[MusicSelect] != 0xFF)
		{
			FreqSelect=Music[MusicSelect];
			MusicSelect++;
			Delay(SPEED/4*Music[MusicSelect]);
			MusicSelect++; 
			TR0 = 0;//关闭定时器
			Delay(5);
			TR0 = 1;//重启定时器
		}
		else
		{
			TR0 = 0;
				while(1);
		}
	}

}

void Timer0_Routine() interrupt 1{
	
	if(FreqTable[FreqSelect] != 0)
{
	TL0 = FreqTable[FreqSelect]%256;
	TH0 = FreqTable[FreqSelect]/256;
		Buzzer = !Buzzer;
}
	
	
}

AT24C02(IIC)总线

AT24C02数据存储

I2C.c(结合时序结构图进行理解)

#include <REGX52.H>

 sbit I2C_SCL = P2^1;
 sbit I2C_SDA = P2^0;
 
 /**
  * @brief  I2C开始
  * @param  无
  * @retval 无
  */
 void I2C_Start(void)//起始条件
{
		I2C_SDA = 1;//初始化
		I2C_SCL = 1;//初始化
		I2C_SDA = 0;//SCL处于高电平期间拉低进行操作
		I2C_SCL = 0;//准备发送字节
}

/**
  * @brief  I2C停止
  * @param  无
  * @retval 无
  */
	void I2C_Stop(void)//终止条件
	{
		I2C_SDA = 0;//可能为1/0,保证为0进行操作
		I2C_SCL = 1;//高电平期间
		I2C_SDA = 1;//由低到高
		
	}
	
	/**
  * @brief  I2C发送一个字节
  * @param  Byte 	要发送的字节
  * @retval 无
  */
	void I2C_SendByte(unsigned char Byte)//发送一个字节
	{
		unsigned char i;
		for( i = 0; i<8; i++)
			{
				I2C_SDA = Byte & (0x80 >> i);//取出各位数据
				I2C_SCL = 1;//准备放入数据,拉高SCL
				I2C_SCL = 0;//马上拉低也能读到数据,准备放入下一位数据
				
			}
	}
	
	/**
  * @brief  I2C接收一个字节
  * @param  无
  * @retval Byte 接收到的一个字节数据
  */
	unsigned char I2C_ReceiveByte(void)
	{
		unsigned char i,Byte;
		I2C_SDA = 1;//释放总线
		
		for( i=0;i<8;i++)
		{
			I2C_SCL = 1;//进行拉高读取
			if(I2C_SDA)
				{
					Byte |= (0x80 >> i);//对八位进行相或运算Byte读出是几就是几
				}
			I2C_SCL = 0;//一位读取完毕,重置SCL,
		}

		return Byte;
	
	}
	
	/**
  * @brief  I2C发送应答
  * @param  AckBit 应答位,0为应答,1为非应答
  * @retval 无
  */
	void I2C_SendAck(unsigned int AckBit)
	{
			I2C_SDA = AckBit;
			I2C_SCL = 1;//拉高进行发送
			I2C_SCL = 0;//发送完成,恢复
	}
	
	/**
  * @brief  I2C接收应答位
  * @param  无
  * @retval AckBit 0为应答,1为非应答
  */
	unsigned char I2C_ReceiveAck(void)
	{
		unsigned char AckBit = 0;
		
		I2C_SDA = 1;//释放总线
		I2C_SCL = 1;//拉高进行接收
		
		AckBit = I2C_SDA;//将发送过来的数据存储
		
		I2C_SCL = 0;//结束接收
		
		return AckBit;
	}

AT24C02.c(结合数据帧最后一张ppt进行理解)

#include <REGX52.H>
#include "I2C.H"

#define AT24C02_ADDRESS		0xA0

/**
  * @brief  AT24C02写入一个字节
  * @param  WorkAddress 要写入字节的地址
  * @param  Data 要写入的数据
  * @retval 无
  */
void AT24C02_WriteByte(unsigned char WorkAddress,Data)//字节写
	{
		unsigned char Ack;
		I2C_Start();//开始
		I2C_SendByte(AT24C02_ADDRESS);//SLAVEADRESS + w,从机地址
		I2C_ReceiveAck();//从机RA
		I2C_SendByte(WorkAddress);//写入字地址
		I2C_ReceiveAck();//从机RA
		I2C_SendByte(Data);//写入数据
		I2C_ReceiveAck();//从机RA
		I2C_Stop();//停止
	}
	
	
	/**
  * @brief  AT24C02读取一个字节
  * @param  WorkAddress 要读取字节的地址
  * @retval Data 读出的数据
  */
unsigned char AT24C02_ReadByte(unsigned char WorkAddress)//随机读
	{
		unsigned char Data;
		
		I2C_Start();//开始
		I2C_SendByte(AT24C02_ADDRESS);//SlaveAdress+W
		I2C_ReceiveAck();//RA
		I2C_SendByte(WorkAddress);//输入字地址
		I2C_ReceiveAck();//RA
		
		I2C_Start();//开始
		I2C_SendByte(AT24C02_ADDRESS | 0x01);//SlaveAdress+R
		I2C_ReceiveAck();//RA
		Data = I2C_ReceiveByte();//接收一个字节数据
		I2C_SendAck(1);//SA,结束接收
		I2C_Stop();//结束
		
		return Data;
	}

main.c

#include <REGX52.H>
#include "Delay.h"
#include "AT24C02.h"
#include "Key.h"
#include "LCD1602.h"

unsigned char KeyNum;
unsigned int Num;

void main(){
	
	LCD_Init();
	LCD_ShowNum(1,1,Num,5);

	while( 1 ){
		KeyNum = Key();
		if(KeyNum == 1)//按下显示+1
			{
				Num++;
				LCD_ShowNum(1,1,Num,5);
			}
		if(KeyNum == 2)//按下显示-1
		{
			Num--;
			LCD_ShowNum(1,1,Num,5);
		}
		if(KeyNum == 3)//存储当前显示数据
		{
			AT24C02_WriteByte(0,Num%256);//存储低位
			Delay(5);
			AT24C02_WriteByte(1,Num/256);//存储高位
			Delay(5);
			LCD_ShowString(2,1,"Write ok");
			Delay(1000);
			LCD_ShowString(2,1,"        ");
		}
		if(KeyNum == 4)//读出内部存储的数据
		{
			Num = AT24C02_ReadByte(0);//取出低位
			Num |= (AT24C02_ReadByte(1) << 8);取出高位并将其合并
			LCD_ShowNum(1,1,Num,5);
			LCD_ShowString(2,1,"Read ok");
			Delay(1000);
			LCD_ShowString(2,1,"        ");
		}
	}

}
AT24C02秒表(定时器扫描按键)

main.c

#include <REGX52.H>
#include "Delay.h"
#include "Key.h"
#include "Nixie.h"
#include "Timer0.h"
#include "I2C.h"
#include "AT24C02.h"
 
 unsigned char KeyNum ;
 unsigned char Min,Sec,MiNiSec;
  unsigned char RunFlag ;
	 
void main(){
	Timer0_Init();
	while( 1 ){
		KeyNum = Key();
			if(KeyNum == 1){//暂停
				RunFlag = !RunFlag; 
			}
			if(KeyNum == 2){//清零
				Min = 0;
				Sec = 0;
				MiNiSec = 0;
			}
			if(KeyNum == 3){//写入
				AT24C02_WriteByte(0,Min);
				Delay(5);//写周期
				AT24C02_WriteByte(1,Sec);
				Delay(5);
				AT24C02_WriteByte(2,MiNiSec);
				Delay(5);
			}
			if(KeyNum == 4){//读出
				Min = AT24C02_ReadByte(0);
				Sec = AT24C02_ReadByte(1);
				MiNiSec = AT24C02_ReadByte(2);
			}
		
			NiXie_SetBuf(1,Min / 10);//分高位
			NiXie_SetBuf(2,Min % 10);//分低位
			NiXie_SetBuf(3,10);//显示 -
			NiXie_SetBuf(4,Sec / 10);//秒高位
			NiXie_SetBuf(5,Sec % 10);//秒低位
			NiXie_SetBuf(6,10);//显示 -
			NiXie_SetBuf(7,MiNiSec / 10);
			NiXie_SetBuf(8,MiNiSec % 10);
	}

}

void Sec_Loop(void)//越界判断及处理
{
	if(RunFlag)//判断运行状态
	{
			MiNiSec ++;
		if(MiNiSec >= 100)
		{
			MiNiSec = 0;
			Sec ++;
			if(Sec >= 60)
			{
				Sec = 0;
				Min ++;
				if(Min >= 60)
				{
					Min = 0;
				}
			}
		}
	}
	

}


void Timer0_Routine() interrupt 1{
	static unsigned int T0Count1,T0Count2,T0Count3;
	T0Count1 ++;
	
	
	TL0 = 0x18;		//设置定时初值
	TH0 = 0xFC;		//设置定时初值(1ms)

	if( T0Count1 >= 20 ){//每隔20ms,扫描按键
		T0Count1 = 0;
		Key_Loop();
	}

	T0Count2 ++;
	if( T0Count2 >= 2 ){//每隔2ms,调用显示
		T0Count2 = 0;
		NiXie_Loop();
	}
	
	T0Count3 ++;
	if( T0Count3 >= 10 ){//每隔10ms,秒表进行运行自增
		T0Count3 = 0;
		Sec_Loop();
	}
}

Key.c

#include <REGX52.H>
#include "Delay.h"

unsigned char Key_KeyNum;

/**
  * @brief  获取独立按键键码
  * @param  无
  * @retval 按下按键的键码,范围 0~4,无按键按下时,返回值为0
  */
unsigned char Key(void)
{
	unsigned char Temp = 0;
	Temp = Key_KeyNum;
	Key_KeyNum = 0;
	
	return Temp; 
}

/**
  * @brief  判断按下哪个按键
  * @param  无
  * @retval 无
  */
unsigned char Key_GetState(viod){
	unsigned char KeyNum = 0;
	
	if(P3_1 == 0){ KeyNum = 1;}
	if(P3_0 == 0){ KeyNum = 2;}
	if(P3_2 == 0){ KeyNum = 3;}
	if(P3_3 == 0){ KeyNum = 4;}
	return KeyNum;

}
	void Key_Loop(void)
{
	static unsigned char NowState , LastState;
	LastState = NowState;
	NowState = Key_GetState();
	if(LastState == 1 && NowState == 0)//按下按键1后松手
	{
		 Key_KeyNum = 1;
	}
	if(LastState == 2 && NowState == 0)//按下按键2后松手
	{
		 Key_KeyNum = 2;
	}
	if(LastState == 3 && NowState == 0)//按下按键3后松手
	{
		 Key_KeyNum = 3;
	}
	if(LastState == 4 && NowState == 0)//按下按键4后松手
	{
		 Key_KeyNum = 4;
	}
}

NiXie.c

#include <REGX52.H>
#include "Delay.h"

unsigned char NiXie_Buf[9] = {0,10,10,10,10,10,10,10,10};
//初始化显示
unsigned char NixieTable [] = {0x3F,0x06,0x5B,0x4F,0x66,
	0x6D,0x7D,0x07,0x7F,0x6F,0x40};
//数字显示,以及 ‘-’ 显示

void NiXie_SetBuf(unsigned char Location,Number)
{
	NiXie_Buf[Location] = Number;//设置显示数字
}
void NiXie_Scan(unsigned char Location,Number){//检测哪个管亮以及亮多少
	
	P0 = 0x00;
	switch(Location){//位选
		case 1:
			P2_4 = 1;P2_3 = 1;P2_2 = 1;break;
		case 2:
			P2_4 = 1;P2_3 = 1;P2_2 = 0;break;
		case 3:
			P2_4 = 1;P2_3 = 0;P2_2 = 1;break;
		case 4:
			P2_4 = 1;P2_3 = 0;P2_2 = 0;break;
		case 5:
			P2_4 = 0;P2_3 = 1;P2_2 = 1;break;
		case 6:
			P2_4 = 0;P2_3 = 1;P2_2 = 0;break;
		case 7:
			P2_4 = 0;P2_3 = 0;P2_2 = 1;break;
		case 8:
			P2_4 = 0;P2_3 = 0;P2_2 = 0;break;
	}
	P0 = NixieTable[Number];//段选
	
}

void NiXie_Loop(void)//这个函数中不能出现delay函数
{
	static unsigned char i = 1;
	
 	NiXie_Scan(i,NiXie_Buf[i]);//不断扫描八个显示管
	i++;
	if(i>=9){i=1;}

}

DS18B20温度传感器(单总线)

温度显示

OneWire.c

#include <REGX52.H>

sbit OneWire_DQ = P3^7;

/**
  * @brief  初始化单总线
  * @param  无
  * @retval 无
  */
unsigned char OneWire_Init(void)
{
	unsigned char AckBit,i;//应答位
	OneWire_DQ = 1;//初始化为高再拉低
	OneWire_DQ = 0;//拉低进入初始化状态
	
	i = 227;while (--i);//延迟500us
	
	OneWire_DQ = 1;//释放总线
	i = 29;while (--i);//延迟70us
	
	AckBit = OneWire_DQ;
	i = 227;while (--i);//延迟500us(超过480us即可)

	return AckBit;
}

/**
  * @brief  单总线传输一位数据
  * @param  Bit 被传输的一位数据
  * @retval 无
  */
void OneWire_SendBit( unsigned char Bit)
{
	unsigned char i;
	OneWire_DQ = 0;//直接拉低,初始化后是高
	i = 4;while (--i);//延时10us
	OneWire_DQ = Bit;//读取典型值
	i = 22;while (--i);//延时50us
	OneWire_DQ = 1;//完成后拉高
}

/**
  * @brief  接收一位数据
  * @param  无
  * @retval Bit	接收到的一位数据
  */
unsigned char OneWire_ReceiveBit(void)
{
	unsigned char Bit,i;
	
	OneWire_DQ = 0;
	i = 2;while (--i);//延时5us
	OneWire_DQ = 1;
	i = 2;while (--i);//延时5us
	Bit = OneWire_DQ;
	i = 22;while (--i);//延时50us,完成后总线应为1
	return Bit;
}

/**
  * @brief  传输一个字节
  * @param  Byte	被传输的字节
  * @retval 无
  */
void OneWire_SendByte(unsigned char Byte)
{
	unsigned char i;
	for( i=0;i<8;i++)
	{
		OneWire_SendBit(Byte & (0x01 << i));//从最低位开始传输
	}
}

/**
  * @brief  接收一个字节
  * @param  无
  * @retval Byte	接收到的字节
  */
unsigned char OneWire_ReceiveByte(void)
{
	unsigned char i;
	unsigned char Byte = 0x00;
	for( i=0;i<8;i++)
	{
		if(OneWire_ReceiveBit()){Byte |= (0x01<<i);}	//从最低位开始接收,有1则入
	
	}
	return Byte;
}

DS18B20.c

#include <REGX52.H>
#include "OneWire.h"

#define DS18B20_SKIP_ROM		0xCC
#define DS18B20_CONVERT_T		0x44
#define DS18B20_READ_SCRATCHPAD		0xBE

/**
  * @brief  转变温度
  * @param  无
  * @retval 无
  */
void DS18B20_ConvertT(void)//温度变换
{
	OneWire_Init();//初始化
	
	OneWire_SendByte(DS18B20_SKIP_ROM);//跳过ROM指令
	OneWire_SendByte(DS18B20_CONVERT_T);//开始温度变换
}

/**
  * @brief  读取温度
  * @param  无
  * @retval T 浮点型温度数据
  */
float DS18B20_ReadT(void)//温度读取,负数的温度是以补码形式存储的
{
	unsigned char TLSB,TMSB;
	int Temp;
	float T;
	
	OneWire_Init();//初始化

	OneWire_SendByte(DS18B20_SKIP_ROM);//跳过ROM指令
	OneWire_SendByte(DS18B20_READ_SCRATCHPAD);//读暂存器
	
	TLSB = OneWire_ReceiveByte();//低位
	TMSB = OneWire_ReceiveByte();//高位
	
	Temp = (TMSB << 8) | TLSB; //合并高低位并强转为有符号类型,有移位相当于扩大16倍
	T = Temp / 16.0;//还原并防止精度损失
	
	return T;
}
	

main.c

#include <REGX52.H>
#include "LCD1602.h"
#include "Delay.h"
#include "DS18B20.h"

float T;

void main(){
	
	LCD_Init();
	LCD_ShowString(1,1,"Temperature:");
	
	
	while( 1 ){
		DS18B20_ConvertT();//转变温度
		T = DS18B20_ReadT();//读取温度
		
		if(T < 0)
		{
			LCD_ShowChar(2,1,'-');
			T = -T;//转为正值,进行显示
		}else
		{
			LCD_ShowChar(2,1,'+');
		}
		LCD_ShowNum(2,2,T,3);//整数部分
		LCD_ShowChar(2,5,'.');
		LCD_ShowNum(2,6,(unsigned long)(T*10000) % 10000,4);//小数部分
	}

}
温度报警器

OneWire.c

#include <REGX52.H>

sbit OneWire_DQ = P3^7;

/**
  * @brief  初始化单总线
  * @param  无
  * @retval 无
  */
unsigned char OneWire_Init(void)
{
	unsigned char AckBit,i;//应答位
	EA = 0;//防止延时被打断,屏蔽中断
	OneWire_DQ = 1;//初始化为高再拉低
	OneWire_DQ = 0;//拉低进入初始化状态
	
	i = 227;while (--i);//延迟500us
	
	OneWire_DQ = 1;//释放总线
	i = 29;while (--i);//延迟70us
	
	AckBit = OneWire_DQ;
	i = 227;while (--i);//延迟500us(超过480us即可)

	EA = 1;//执行完成后,将计时器还原
	return AckBit;
}

/**
  * @brief  单总线传输一位数据
  * @param  Bit 被传输的一位数据
  * @retval 无
  */
void OneWire_SendBit( unsigned char Bit)
{
	unsigned char i;
	EA = 0;//防止延时被打断,屏蔽中断
	OneWire_DQ = 0;//直接拉低,初始化后是高
	i = 4;while (--i);//延时10us
	OneWire_DQ = Bit;//读取典型值
	i = 22;while (--i);//延时50us
	OneWire_DQ = 1;//完成后拉高
	EA = 1;//执行完成后,将计时器还原
}

/**
  * @brief  接收一位数据
  * @param  无
  * @retval Bit	接收到的一位数据
  */
unsigned char OneWire_ReceiveBit(void)
{
	unsigned char Bit,i;
	EA = 0;//防止延时被打断,屏蔽中断
	
	OneWire_DQ = 0;
	i = 2;while (--i);//延时5us
	OneWire_DQ = 1;
	i = 2;while (--i);//延时5us
	Bit = OneWire_DQ;
	i = 22;while (--i);//延时50us,完成后总线应为1
	EA = 1;//执行完成后,将计时器还原
	return Bit;
}

/**
  * @brief  传输一个字节
  * @param  Byte	被传输的字节
  * @retval 无
  */
void OneWire_SendByte(unsigned char Byte)
{
	unsigned char i;
	for( i=0;i<8;i++)
	{
		OneWire_SendBit(Byte & (0x01 << i));//从最低位开始传输
	}
}

/**
  * @brief  接收一个字节
  * @param  无
  * @retval Byte	接收到的字节
  */
unsigned char OneWire_ReceiveByte(void)
{
	unsigned char i;
	unsigned char Byte = 0x00;
	for( i=0;i<8;i++)
	{
		if(OneWire_ReceiveBit()){Byte |= (0x01<<i);}	//从最低位开始接收,有1则入
	
	}
	return Byte;
}

main.c

#include <REGX52.H>
#include "DS18B20.h"
#include "LCD1602.h"
#include "AT24C02.h"
#include "Delay.h"
#include "Key.h"
#include "Timer0.h"

float T,TShow;//温度与显示温度
char TLow,THigh;//低阈值,高阈值
unsigned char KeyNum;//获取到的键码

void main(){
	DS18B20_ConvertT();
	Delay(1000);
	THigh = AT24C02_ReadByte(0);//读取内部存储的高阈值
	TLow = AT24C02_ReadByte(1);//读取内部存储的低阈值
	
	if(THigh > 125 || TLow < -55 || THigh <= TLow)
	{
		THigh = 20;
		TLow = 15;
	}
	
	LCD_Init();
	LCD_ShowString(1,1,"T:");
	
	LCD_ShowString(2,1,"TH:");
	LCD_ShowString(2,9,"TL:");
	
	LCD_ShowSignedNum(2,4,THigh,3);
	LCD_ShowSignedNum(2,12,TLow,3);
	
	Timer0_Init();
	
	
	while( 1 ){
		KeyNum = Key();
		
		/*温度读取及显示*/
		DS18B20_ConvertT();
		T = DS18B20_ReadT();
		
		if(T < 0)//零下
		{
			LCD_ShowChar(1,3,'-');
			TShow = -T;//转为正值
		}else
		{
			LCD_ShowChar(1,3,'+');
			TShow = T;
		}
		LCD_ShowNum(1,4,TShow,3);//整数部分
		LCD_ShowChar(1,7,'.');
		LCD_ShowNum(1,8,(unsigned long)(T*100)%100,2);//小数部分
		
		/*阈值判断及显示*/
		if(KeyNum)
			{
					if(KeyNum == 1)//增加高阈值
				{
					THigh++;
					if(THigh > 125)
					{THigh = 125;}
				}
				if(KeyNum == 2)//降低高阈值
				{
					THigh--;
					if(THigh <= TLow)
					{THigh ++;}
				}
				if(KeyNum == 3)//增加低阈值
				{
					TLow++;
					if(TLow >= THigh)
					{TLow -- ;}
				}
				if(KeyNum == 4)//降低低阈值
				{
					TLow--;
					if(TLow < -55)
					{TLow = -55;}
				}
			
				LCD_ShowSignedNum(2,4,THigh,3);
				LCD_ShowSignedNum(2,12,TLow,3);
			
				AT24C02_WriteByte(0,THigh);//写入高阈值
				Delay(5);//写周期
				AT24C02_WriteByte(1,TLow);//写入低阈值
				Delay(5);//写周期
			}

		if(T > THigh)
		{
			LCD_ShowString(1,13,"OV:H");
		}else if(T < TLow)
		{
			LCD_ShowString(1,13,"OV:L");
		}else
		{
			LCD_ShowString(1,13,"OV: ");
		}
	}
}

//中断函数
void Timer0_Routine() interrupt 1{
	static unsigned int T0Count;
	T0Count ++;
	TL0 = 0x18;		//设置定时初值
	TH0 = 0xFC;		//设置定时初值
	if( T0Count >= 20 ){
		T0Count = 0;
		Key_Loop();
	}

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1414470.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ElasticSearch7.7.1集群搭建

前言 Elasticsearch&#xff08;ES&#xff09;是一个基于Apache Lucene的分布式、高扩展、近实时的搜索引擎&#xff0c;主要用于海量数据快速存储、实时检索、高效分析的场景。通过简单易用的RESTful API&#xff0c;Elasticsearch隐藏了Lucene的复杂性&#xff0c;使得全文搜…

kali系统下多版本JDK共存

0、前言 从上周末到这周都在做RCE(Remote Command/Code Execute&#xff0c;远程命令执行或者代码执行 )相关漏洞复现&#xff0c;像log4j2漏洞在复现过程用到的JDK有特定版本要求&#xff0c;我的kali虚拟机默认是JDK11&#xff0c;而我又不希望直接删除JDK11&#xff0c;可多…

Vue2:通过代理服务器解决跨域问题

一、场景描述 现在的项目大多数是前后端分离的。Vue前端项目通过ajax去请求后端接口的时候&#xff0c;会有同源策略的限制。从而产生跨域问题。 二、基本概念 1、什么是同源策略&#xff1f; 就是前端服务和后端服务的协议名&#xff0c;IP或主机名&#xff0c;端口号不完…

Linux进程间通信(IPC)机制之一:管道(Pipes)详解

&#x1f3ac;慕斯主页&#xff1a;修仙—别有洞天 ♈️今日夜电波&#xff1a;Nonsense—Sabrina Carpenter 0:50━━━━━━️&#x1f49f;──────── 2:43 &#x1f504; ◀️ ⏸ ▶️ …

Maven讲解

介绍 Maven是一个流行的构建工具和项目管理工具&#xff0c;它主要用于Java项目的构建、依赖管理和项目报告生成。Maven通过提供一致的项目结构、自动化的构建过程和强大的依赖管理&#xff0c;简化了项目的开发和维护过程。 下面是一些Maven的主要特点和用途&#xff1a; 项…

设计模式—行为型模式之责任链模式

设计模式—行为型模式之责任链模式 责任链&#xff08;Chain of Responsibility&#xff09;模式&#xff1a;为了避免请求发送者与多个请求处理者耦合在一起&#xff0c;于是将所有请求的处理者通过前一对象记住其下一个对象的引用而连成一条链&#xff1b;当有请求发生时&am…

Java设计模式-外观模式(11)

大家好,我是馆长!今天开始我们讲的是结构型模式中的外观模式。老规矩,讲解之前再次熟悉下结构型模式包含:代理模式、适配器模式、桥接模式、装饰器模式、外观模式、享元模式、组合模式,共7种设计模式。。 外观模式(Decorator Pattern) 定义 外观(Facade)模式一种通…

【活动回顾】CSDN 成都城市开发者社区年度聚会 - 圆满结束!

文章目录 前言一、活动介绍二、精彩分享内容2.1、《COC 成都社区情况和活动介绍》2.2、《2023 年你最关注的话题》2.3、《紧跟技术潮流》2.4、《2024 年抓住技术新红利》2.5、一起干饭啦2.6、合影留念 三、亚马逊云科技 User Group3.1、社区介绍3.2、持续招募3.3、微信交流群 总…

css3表格练习

1.效果图 2.html <div class"line"></div><h3>获奖名单</h3><!-- 表格 cellspacing内边距 cellpadding外边距--><table cellspacing"0" cellpadding"0" ><!-- thead表头 --><thead><tr>…

【JavaEE】网络原理: 网络编程套接字(概念)

目录 1.什么是网络编程 2.网络编程中的基本概念 2.1发送端和接收端 2.2请求和响应 2.3客户端和服务端 3.Socket套接字 4.Socket编程注意事项 1.什么是网络编程 网络编程&#xff0c;指网络上的主机&#xff0c;通过不同的进程&#xff0c;以编程的方式实现网络通信 (…

程序员的平均结婚年龄

关于程序员的平均结婚年龄&#xff0c;根据之前的信息&#xff1a; 一项对全球10000名在职程序员的调查数据显示&#xff0c;程序员第一次结婚的平均年龄是39.43周岁。而在中国的部分地区&#xff0c;如北京等地&#xff0c;程序员群体中普遍反映的结婚年龄是在30岁左右。 程序…

Title: 提升大型语言模型在知识图谱完成中的性能

基本信息 论文题目: Making Large Language Models Perform Better in Knowledge Graph Completion Making Large Language Models Perform Better in Knowledge Graph Completion (arxiv.org)https://arxiv.org/pdf/2310.06671.pdf 作者: Yichi Zhang, Wen Zhang 机构: Col…

25考研政治备考计划

各位小伙伴大家好&#xff0c;今天给大家分享的是25考研政治复习备考计划。 政治没有基础阶段&#xff0c;直接就是强化&#xff0c;强化的内容也就是听课&#xff0c;刷题。 【时间安排】 *7-9月中 徐涛老师或腿姐强化课&#xff0c;推荐刷肖1000 *9月中-10月中 背腿姐的背…

文件上传之大文件分块上传进度控制处理

在分块上传内容结束以后的事件监听&#xff0c;我们会实现 unlinkSync 删除临时文件操作&#xff0c;那么试想一下&#xff0c;在这个事件监听中&#xff0c;我们是否可以通过totalChunks以及currentChunk获取当前上传的进度情况呢&#xff1f; 后端 upload上传接口&#xff…

Go 知识chan

Go 知识chan 1. 基本知识1.1 定义1.2 操作1.3 操作限定1.4 chan 读写 2. 原理2.1 数据结构2.2 环形队列2.3 等待队列2.4 类型消息2.5 读写数据2.6 关闭chan 3. 使用3.1 操作符使用3.2 select3.3 for-range https://a18792721831.github.io/ 1. 基本知识 chan是go里面里面提供…

应用机器学习的建议

一、决定下一步做什么 在你得到你的学习参数以后&#xff0c;如果你要将你的假设函数放到一组新的房屋样本上进行测试&#xff0c;假如说你在预测房价时产生了巨大的误差&#xff0c;你想改进这个算法&#xff0c;接下来应该怎么办&#xff1f;实际上你可以考虑先采用下面的几种…

「QT」QString类的详细说明

✨博客主页何曾参静谧的博客📌文章专栏「QT」QT5程序设计📚全部专栏「VS」Visual Studio「C/C++」C/C++程序设计「UG/NX」BlockUI集合「Win」Windows程序设计「

并查集:连通块中点的数量

import java.io.*; import java.util.Scanner;public class Main{static int N 100010;static int[] p new int[N]; //存储每个节点的父亲节点,一开始默认p[i]i;static int[] size new int[N]; //存储每个连通块里含有多少个节点static BufferedReader in new BufferedR…

数学知识第二期 约数

前言 约数也是很重要的基础数学知识&#xff0c;希望大家能够完全掌握&#xff01;&#xff01;&#xff01; 一、约数的知识 简介 约数&#xff0c;又称因数。整数a除以整数b(b≠0) 除得的商正好是整数而没有余数&#xff0c;就说a能被b整除&#xff0c;或b能整除a。a称为b的…

【Java与网络6】实现一个自己的HTTP浏览器

前面我们讨论了HTTP协议的基本结构和Socket编程的基本原理&#xff0c;本文我们来整个大活&#xff1a;自己实现一个简单的浏览器。 目录 1.主线程循环体 2.readHostAndPort()方法的实现 3.readHttpRequest()方法的实现 4.sendHttpRequest()方法的实现 5.readHttpRespons…