一:DS13B20固定套路(温度模块)
//**********************读取温度***************************/
void read_DS18B20_temp()
{
uchar Temp,LSB,MSB; //LSB低八位,MSB高八位
//温度转换
init_ds18b20(); //初始化DS18B20
Write_DS18B20(0xcc); //跳过ROM
Write_DS18B20(0x44); //开始温度转换
Delay_OneWire(200); //等待温度转换完成
//读温度
init_ds18b20(); //初始化DS18B20
Write_DS18B20(0xcc); //跳过ROM
Write_DS18B20(0xbe); //开始读温度
//读温度
LSB = Read_DS18B20(); //读取低八位数据
MSB = Read_DS18B20(); //读取高八位数据
Temp=MSB<<4;
Temp=Temp|(LSB>>4);
return Temp;
带小数部分
void read_DS18B20_temp()
{
uchar LSB,MSB; //LSB低八位,MSB高八位
//温度转换
init_ds18b20(); //初始化DS18B20
Write_DS18B20(0xcc); //跳过ROM
Write_DS18B20(0x44); //开始温度转换
Delay_OneWire(200); //等待温度转换完成
//读温度
init_ds18b20(); //初始化DS18B20
Write_DS18B20(0xcc); //跳过ROM
Write_DS18B20(0xbe); //开始读温度
//读温度
LSB = Read_DS18B20(); //读取低八位数据
MSB = Read_DS18B20(); //读取高八位数据
temp = MSB;
temp <<= 8; //高八位右移8位
temp = temp | LSB; //将独立的高、低8位合并为16位
if((temp & 0xf800) == 0x0000) //判断temp的高五位来判断温度的正负,高5位全为0表示为正,全为1表示负
{
temp >>= 4;
temp = temp * 10; //temp先右移四位在乘上10相当于整数部分乘以0.625倍
temp = temp + (LSB & 0x0f) * 0.625; //整数部分 * 0.625 + 小数部分 *0.625
}
}
void Read_Temperature(void)
{
unsigned char LSB = 0,MSB = 0;
unsigned int temp = 0;
init_ds18b20();
Write_DS18B20(0xcc);
Write_DS18B20(0x44);
delay(800);
init_ds18b20();
Write_DS18B20(0xcc);
Write_DS18B20(0xbe);
LSB = Read_DS18B20();
MSB = Read_DS18B20();
init_ds18b20();
temp = (MSB << 8)| LSB;
if((temp & 0xf800) == 0x0000)
{
T_temp = temp * 0.0625;
}
Real_T = T_temp * 10;
}
简: TLMicc44
2百iccbe
LM=RD
TM左4TT
并L右4返
二:时间模块DS1302
unsigned char DS1302_Write_Addr[] = {0x80,0x82,0x84,0x86,0x88,0x8a,0x8c};
unsigned char DS1302_Read_Addr[]= {0x81,0x83,0x85,0x87,0x89,0x8b,0x8d};
//2022-12-23 23-25-30 周五
unsigned char Init_DS1302_Clock[] = {0x40,0x54,0x30,0x23,0x12,0x05,0x22};
void Write_DS1302_Data(void)
{
unsigned char i = 0;
//关闭写保护
Write_Ds1302(0x8e,0x00);
for(i =0;i<7;i++)
{
Write_Ds1302(DS1302_Write_Addr[i],Init_DS1302_Clock[i]);
}
//打开写保护
Write_Ds1302(0x8e,0x80);
}
//读取时间
void Read_DS1302_Data(void)
{
unsigned char i = 0;
for(i = 0;i<7;i++)
{
Init_DS1302_Clock[i] = Read_Ds1302(DS1302_Read_Addr[i]);
}
}
简:
三:555频率
uint count_f = 0; //计算频率 uint dat_f = 0; //缓存上一秒频率 uchar count_t = 0; //计算时间
//NE555是Rb3,短接SIGNAL和P34
void Init_Timer()
{
//定时器0用作计数,8位重装
TH0 = 0XFF;
TL0 = 0XFF;
//定时器1用作定时,定时时间50ms
TH1 = (65535 - 50000 + 1) / 256;
TL1 = (65535 - 50000 + 1) % 256;
TMOD = 0X16;//0001 0110
ET0 = 1;
ET1 = 1;
EA = 1;
TR0 = 1;
TR1 = 1;
}
void Service_T0() interrupt 1
{
count_f++;
}
void Service_T1() interrupt 3
{
TH1 = (65535 - 50000 + 1) / 256;
TL1 = (65535 - 50000 + 1) % 256;
count_t++;
if(count_t == 20)
{
dat_f = count_f;
count_f = 0;
count_t = 0;
}
}
简:
f上次f时间,0计数1计时
频率:一秒内周期性变化
四:光敏/rb2
//通道一:光敏电阻0x01 通道3:RB2电位器0x03
//Light_read(0X01)
uchar Light_read(uchar add)
{
uchar temp;
IIC_Start();
IIC_SendByte(0X90);
IIC_WaitAck();
IIC_SendByte(add);
IIC_WaitAck();
IIC_Stop();
IIC_Start();
IIC_SendByte(0X91);
IIC_WaitAck();
temp = IIC_RecByte();
IIC_Stop();
return temp;
}
简:t开始90add停,开始91赋t停,中间间隔尾返t
通道一光敏三rb2,电压输出乘0.1963
五:DAC
void read_DAC(uint dat)
{
IIC_Start();
IIC_SendByte(0x90); //写设备地址
IIC_WaitAck();
IIC_SendByte(0x40); //写控制字
IIC_WaitAck();
IIC_SendByte(dat); //dat为要转换的数字量
IIC_WaitAck();
IIC_Stop();
}
简:开始9040dat停,而后中间ack
控制电压输出
六:EEPROM存储
AT24C02
EEPROM(寄存器)
/*
EEPROM_write(0X01, 126);
delayms(5) //延时5ms
EEPROM_read(0X01)
*/
//读取阈值
uchar EEPROM_read(uchar add)
{
uchar temp;
IIC_Start();
IIC_SendByte(0XA0);
IIC_WaitAck();
IIC_SendByte(add);
IIC_WaitAck();
IIC_Stop();
IIC_Start();
IIC_SendByte(0XA1);
IIC_WaitAck();
temp = IIC_RecByte();
IIC_Stop();
return temp;
}
//写入阈值
void EEPROM_write(uchar add, uchar dat)
{
IIC_Start();
IIC_SendByte(0XA0);
IIC_WaitAck();
IIC_SendByte(add);
IIC_WaitAck();
IIC_SendByte(dat);
IIC_WaitAck();
IIC_Stop();
}
简:EEPROM读:光敏9换A
写:发送A0 add dat
七:系统初始化
//系统初始化
void Initsys()
{
SelectHC138(5);
P0 = 0X00;//关闭蜂鸣器和继电器
SelectHC138(4);
P0 = 0XFF;//关闭LED
SelectHC138(6);
P0 = 0XFF; //选择所有数码管
SelectHC138(7);
P0 = 0XFF; //关闭所有数码管
}
八:超声波模块
1】基本原理
超声波发射模块向某一方向发射超声波,在发射时刻的同时开始计时,超声波在空气中传播,途中碰到障碍物就立即返回来,超声波接收器收到反射波就立即停止计时。
【2】计算公式
距离 = 声速 × 发出超声波到接收返回的时间/2
因为超声波在空气中的传播速度受温度影响。声波在空气中的传播速度与温度的关系是:
在20摄氏度时,声速V = 332 + 0.607t (m/s)
利用超声波进行距离测量,要求精度一般都不高,取20摄氏度时候的声速344M/S进行计算,再进行适当的补偿就可以。所以,其计算公式为:距离L = 344M/S * T / 2 = 172M/S * T 。
【3】实现步骤
1-产生8个40KHz的超声波信号,通过TX引脚发射出去。
2-启动定时器,计算计数脉冲。
3-等待超声波信号返回,如果接收到反射回来的信号,RX引脚变为低电平。
4-停止定时器,读取脉冲个数,即获得时间T。
5-根据公式,L = V * T /2m,进行距离的计算。
sbit TX = P1^0;
sbit RX = P1^1;
unsigned int distance = 0;
void Measure_Distance() //超声波测距
{
unsigned int time = 0;
TMOD &= 0x0f; //定时器1模式0,13位,最大8192个计数脉冲
TL1 = 0x00;
TH1 = 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;
}
}
void Send_Wave() //产生8个40KHx超声波信号
{
unsigned char i;
for(i = 0; i < 8; i++)
{
TX = 1;
Delay12us();
TX = 0;
Delay12us();
}
}
简:
sendwave遍八TX10十二微秒隔
TXRX为P10P11
TM与0f发启,等收到超量闭
time= TH1
time=(time<<8)|TL1
distance=((time/10)×17)/100+3
tHtt左8竖L,距离t除时括乘一七
前者除十后加3
超出标志得置零
rb2乘0.01963为电压
九:38译码器
3.配置138译码器
Void init138(uc n)
{
Switch(n)
{
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;
}
}
十:数码管显示
4.数码管显示函数
Void showsmg_bit(uc pos,uc dat)
{
init138(6);
P0=0x01<<pos;
Init138(7);
P0=dat;
}
十一:中断
中断源:INT0;TF0;INT1;TF1;RI/TI;
注意按键有两层==;中间还有个等待松开
如果按键多用,则外定义状态,每次以不同的状态进入按键识别,最后总的加个等待按键松开
中断配置函数
Void init_INT0()
{
IT0=1;//下降沿触发
EX0=1;
EA=1
}
Void serviceINT0() interrupt 0
{
自由添加//尽量少做事情
}
Void initimer0()
{
TMOD=0X01;
TH0=(65535-50000)/256;
TL0=(65535-50000)%256;
ET0=1;
EA=1;
TR0=1;
}
Void servicetimer() interrupt 1
{
TH0=(65535-50000)/256;
TL0=(65535-50000)%256;********************特别注意PWM时50000为100,其中DUTY为高电平占的比例,再在按键扫描中首下打开定时器TR0
+服务函数
}
十二:串口通信
头部sfr AUXR=0X8E;
void InitUart()
{
TMOD = 0X20;
TH1 = 0XFD;
TL1 = 0XFD;
TR1 = 1;
SCON = 0X50;
AUXR = 0X00;
ES = 1;
EA = 1;
}
void SendByte(uchar dat)
{
SBUF = dat;
while(TI == 0);
TI = 0;
}
void ServiceUart() interrupt 4
{
if(RI == 1)
{
RI = 0;
urdat = SBUF;
SendByte(urdat + 1);
}
}
字符串传输
uchar command = 0;
void ServiceUart() interrupt 4
{
if(RI == 1)
{
command = SBUF;
RI = 0;
}
}
void SendByteUart(uchar dat)
{
SBUF = dat;
while(TI == 0);
TI = 0;
}
void SendStringUart(uchar *str)
{
while(*str != '\0')
{
SendByteUart(*str);
str++;
}
}
//*******************************
void Working()
{
SelectHC138(4);
if(command != 0)
{
switch(command & 0xf0) //提取高四位
{
case 0xA0:
P0 = (P0 | 0X0F) & (~command | 0XF0); //保留高4位,反转低四位
command = 0X00;
break;
case 0xB0:
P0 = (P0 | 0XF0) & (~command << 4| 0X0F);
command = 0X00;
break;
case 0xC0:
SendStringUart("The System is Runing……\r\n");
command = 0X00;
break;
}
}
}
十三:
外部资源的地址映射关系
0x8000—指示灯
0xa000—蜂鸣器与继电器
0xc000—数码管位选
0xe000—数码管段码
2.2 提示
进行存储器映射扩展,CT107平台的J13要将1-2脚短接
引入“absacc.h”,通过XBYTE关键字来直接操作扩展资源。
存储器映射扩展方式要占用单片机的P3.6引脚。
头文件模块化设计
#ifndef
#define
..........
#endif