74HC595和74HC138控制程序
void Device_ctrl(unsigned char p2date,unsigned char p0date)//p0date为数据p2date为选中模块 { P0=p0date; P2=P2&0x1f|p2date; P2&=0x1f; }
Device_ctrl(0x80,0xff);///关闭蜂鸣器继电器 Device_ctrl(0xa0,0x00);//关闭led
数码管显示函数(需配合定时器)
unsigned char smg_du[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};///共阳极数码管段码 unsigned char smg_display[8]; unsigned int smg_count; void smg_show() { unsigned int i; Device_ctrl(0xc0,0); Device_ctrl(0xe0,~smg_display[i]); Device_ctrl(0xc0,0x01<<i); i=(i 1)%8; } void smg_process() { if(smg_count>3) { } }
按键使用函数(需配合定时器使用)
unsigned char trig_btn; unsigned char con_btn; unsigned int key_count; void key_btn()//三行按钮 { unsigned char readdate=P3^0xff; trig_btn=readdate&(con_btn^readdate); con_btn=readdate; } void key_process() { if(key_count>=10) { key_count=0; key_btn(); if(trig_btn==0x08)//s4 { } if(trig_btn==0x04)//s5 { if(trig_btn==0x02)//s6 { } if(trig_btn==0x01)//s7 { } } }
#define KEY3 P3 #define NO_KEY 0xff #define KEY_STATE0 0 #define KEY_STATE1 1 #define KEY_STATE2 2 unsigned int key_count; unsigned char key_scan() { static unsigned char key_state=KEY_STATE0; unsigned char key_temp,key_value=0; unsigned char key1,key2; P30=0;P31=0;P32=0;P33=0;P34=1;P35=1;P42=1;P44=1; if(P44==0){key1=0x70;} if(P42==0){key1=0xb0;} if(P35==0){key1=0xd0;} if(P34==0){key1=0xe0;} if((P44==1)&&(P42==1)&&(P34==1)&&(P35==1)){key1=0xf0;} P30=1;P31=1;P32=1;P33=1;P34=0;P35=0;P42=0;P44=0; if(P30==0){key2=0x0e;} if(P31==0){key2=0x0d;} if(P32==0){key2=0x0b;} if(P33==0){key2=0x07;} if((P30==1)&&(P31==1)&&(P32==1)&&(P33==1)){key2=0x0f;} key_temp=key1|key2; switch(key_state) { case KEY_STATE0: if(key_temp!=NO_KEY) { key_state=KEY_STATE1; } break; case KEY_STATE1: if(key_temp==NO_KEY) { key_state=KEY_STATE0; } else { switch(key_temp) { case 0x77:key_value=4;break; case 0x7b:key_value=5;break; case 0x7d:key_value=6;break; case 0x7e:key_value=7;break; case 0xb7:key_value=8;break; case 0xbb:key_value=9;break; case 0xbd:key_value=10;break; case 0xbe:key_value=11;break; case 0xd7:key_value=12;break; case 0xdb:key_value=13;break; case 0xdd:key_value=14;break; case 0xde:key_value=15;break; case 0xe7:key_value=16;break; case 0xeb:key_value=17;break; case 0xed:key_value=18;break; case 0xee:key_value=19;break; } key_state=KEY_STATE2; } break; case KEY_STATE2:if(key_temp==NO_KEY) { key_state=KEY_STATE0; } break; } return key_value; } void key_process() { unsigned char key_val; if(key_count>10) { key_count=0; key_val=key_scan(); switch(key_val) { case 4:break; case 5:break; case 6:break; case 7:break; case 8:break; case 9:break; case 10:break; case 11:break; case 12:break; case 13: break; case 14: break; case 15: break; case 16: break; case 17: break; case 18 : break; case 19: break; } } }
温度读取函数(需配合定时器)
//通过在while 1 运行前准备读取温度,避免刚上电温度读取85问题 unsigned int temp; void temper_start()//准备读取温度 { init_ds18b20(); Write_DS18B20(0xcc); Write_DS18B20(0x44); } float read_temper()///读取温度 { float temper; unsigned char low,high; init_ds18b20(); Write_DS18B20(0xcc); Write_DS18B20(0xbe); low=Read_DS18B20(); high=Read_DS18B20(); temper=(high<<8)|low; temper=temper*0.0625; return temper; } unsigned int temp_count; void temp_process()//每秒读一次温度 在定时器中设置温度读取间隔 { if(temp_count>1000) { temp=read_temper()*100; temper_start(); temp_count=0; } }
底层驱动代码读取温度
onewire.c
#include "reg52.h" sbit DQ = P1^4; ///单总线接口 ///单总线延迟函数 void Delay_OneWire(unsigned int t) //STC89C52RC { t*=12; while(t--); } ///通过单总线DS18B20写一个字节 void Write_DS18B20(unsigned char dat) { unsigned char i; for(i=0;i<8;i ) { DQ = 0; DQ = dat&0x01; Delay_OneWire(5); DQ = 1; dat >>= 1; } Delay_OneWire(5); } //DS18B20读取一个字节
unsigned char Read_DS18B20(void)
{
unsigned char i;
unsigned char dat;
for(i=0;i<8;i++)
{
DQ = 0;
dat >>= 1;
DQ = 1;
if(DQ)
{
dat |= 0x80;
}
Delay_OneWire(5);
}
return dat;
}
//DS18B20设备初始化
bit init_ds18b20(void)
{
bit initflag = 0;
DQ = 1;
Delay_OneWire(12);
DQ = 0;
Delay_OneWire(80);
DQ = 1;
Delay_OneWire(10);
initflag = DQ;
Delay_OneWire(5);
return initflag;
}
温度读取头文件
onewire.h
#ifndef __ONEWIRE_H
#define __ONEWIRE_H
void Delay_OneWire(unsigned int t);
void Write_DS18B20(unsigned char dat);
unsigned char Read_DS18B20(void);
bit init_ds18b20(void);
#endif
AD函数(需配合定时器使用)
unsigned int ad_count;
unsigned char ad_val;
unsigned char read_ad(unsigned char add)//读取ad数值0-255
{
unsigned char ad_value;
IIC_Start();
IIC_SendByte(0x90);
IIC_WaitAck();
IIC_SendByte(add);
IIC_WaitAck();
IIC_Start();
IIC_SendByte(0x91);
IIC_WaitAck();
ad_value=IIC_RecByte();
IIC_SendAck(1);
IIC_Stop();
return ad_value;
}
void ad_process()//通过定时器来读取ad数值
{
if(ad_count>100)
{
ad_count=0;
ad_val=read_ad(0x03);//0x03为电位器rb2 0x01为光敏电阻
}
}
DA函数(需配合定时器使用)
unsigned int da_count;//定时器控制电压输出频率
unsigned int ad_val;//255对应5v
void da(unsigned char date)//电压输出函数
{
IIC_Start();
IIC_SendByte(0x90);
IIC_WaitAck();
IIC_SendByte(0X40);
IIC_WaitAck();
IIC_SendByte(date);
IIC_WaitAck();
IIC_Stop();
}
void da_process()
{
if(da_count>100)
{
da_count=0;
ad_val=255;
da(ad_val);
}
}
eeprom函数
写入函数
void write_eeprom(unsigned char add,unsigned char date)//eeprom写入函数
{
IIC_Start();
IIC_SendByte(0xa0);
IIC_WaitAck();
IIC_SendByte(add);
IIC_WaitAck();
IIC_SendByte(date);
IIC_WaitAck();
IIC_Stop();
}
eeprom读取函数
unsigned char read_eeprom(unsigned char add)//eeprom写入函数
{
unsigned char date;
IIC_Start();
IIC_SendByte(0xa0);
IIC_WaitAck();
IIC_SendByte(add);
IIC_WaitAck();
IIC_Start();
IIC_SendByte(0xa1);
IIC_WaitAck();
date=IIC_RecByte();
IIC_SendAck(1);
IIC_Stop();
return date;
}
IIC底层驱动函数
iic.c
#include "reg52.h"
#include "intrins.h"
#define DELAY_TIME 5
#define SlaveAddrW 0xA0
#define SlaveAddrR 0xA1
//总线引脚定义
sbit SDA = P2^1; /* 数据线 */
sbit SCL = P2^0; /* 时钟线 */
void IIC_Delay(unsigned char i)
{
do{_nop_();}
while(i--);
}
//总线启动条件
void IIC_Start(void)
{
SDA = 1;
SCL = 1;
IIC_Delay(DELAY_TIME);
SDA = 0;
IIC_Delay(DELAY_TIME);
SCL = 0;
}
//总线停止条件
void IIC_Stop(void)
{
SDA = 0;
SCL = 1;
IIC_Delay(DELAY_TIME);
SDA = 1;
IIC_Delay(DELAY_TIME);
}
//发送应答
void IIC_SendAck(bit ackbit)
{
SCL = 0;
SDA = ackbit; // 0:应答,1:非应答
IIC_Delay(DELAY_TIME);
SCL = 1;
IIC_Delay(DELAY_TIME);
SCL = 0;
SDA = 1;
IIC_Delay(DELAY_TIME);
}
//等待应答
bit IIC_WaitAck(void)
{
bit ackbit;
SCL = 1;
IIC_Delay(DELAY_TIME);
ackbit = SDA;
SCL = 0;
IIC_Delay(DELAY_TIME);
return ackbit;
}
//通过I2C总线发送数据
void IIC_SendByte(unsigned char byt)
{
unsigned char i;
for(i=0; i<8; i++)
{
SCL = 0;
IIC_Delay(DELAY_TIME);
if(byt & 0x80) SDA = 1;
else SDA = 0;
IIC_Delay(DELAY_TIME);
SCL = 1;
byt <<= 1;
IIC_Delay(DELAY_TIME);
}
SCL = 0;
}
//从I2C总线上接收数据
unsigned char IIC_RecByte(void)
{
unsigned char i, da;
for(i=0; i<8; i++)
{
SCL = 1;
IIC_Delay(DELAY_TIME);
da <<= 1;
if(SDA) da |= 1;
SCL = 0;
IIC_Delay(DELAY_TIME);
}
return da;
}
iic.h0
#ifndef __IIC_H
#define __IIC_H
void IIC_Start(void);
void IIC_Stop(void);
bit IIC_WaitAck(void);
void IIC_SendAck(bit ackbit);
void IIC_SendByte(unsigned char byt);
unsigned char IIC_RecByte(void);
void IIC_Delay(unsigned char i);
#endif
DS1302写入时分秒
void set_sfm(unsigned char shi,unsigned char fen,unsigned char miao)
{
Write_Ds1302_Byte(0x8e,0);
Write_Ds1302_Byte(0x80,(miao/10)*16+miao%10);
Write_Ds1302_Byte(0x82,(fen/10)*16+fen%10);
Write_Ds1302_Byte(0x84,(shi/10)*16+shi%10);
Write_Ds1302_Byte(0x8e,0x80);
}
时分秒读取
shi=shi/16*10+shi%16;
fen=fen/16*10+fen%16;
miao=miao/16*10+miao%16;
DS1302底层驱动代码
ds1302.c
#include <reg52.h>
#include <intrins.h>
sbit SCK=P1^7;
sbit SDA=P2^3;
sbit RST = P1^3; // DS1302复位
void Write_Ds1302(unsigned char temp)
{
unsigned char i;
for (i=0;i<8;i++)
{
SCK=0;
SDA=temp&0x01;
temp>>=1;
SCK=1;
}
}
void Write_Ds1302_Byte( unsigned char address,unsigned char dat )
{
RST=0; _nop_();
SCK=0; _nop_();
RST=1; _nop_();
Write_Ds1302(address);
Write_Ds1302(dat);
RST=0;
}
unsigned char Read_Ds1302_Byte ( unsigned char address )
{
unsigned char i,temp=0x00;
RST=0; _nop_();
SCK=0; _nop_();
RST=1; _nop_();
Write_Ds1302(address);
for (i=0;i<8;i++)
{
SCK=0;
temp>>=1;
if(SDA)
temp|=0x80;
SCK=1;
}
RST=0; _nop_();
SCK=0; _nop_();
SCK=1; _nop_();
SDA=0; _nop_();
SDA=1; _nop_();
return (temp);
}
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
ne555测量频率函数
void counter_init()//计数器初始化
{
TMOD|=0X05; //定时器0/计数器0配置成计数模式且不自动装载
TL0=0X00; //初值为0
TH0=0X00; //初值为0
TR0=1; //启动计数器
}
void ne555_process() //放在1ms定时器2中断执行
{
count_ne555++;
if(count_ne555>=1000) //精确的1s
{
count_ne555=0;
freq_ne555=(TH0<<8)|TL0;
TL0=0;
TH0=0;
}
}
超声波测距函数
sbit TX=P1^0;
sbit RX=P1^1;
void sendwave()
{
unsigned char i;
for(i=0;i<8;i++)
{
TX=1;
Delay12us();
TX=0;
Delay12us();
}
}
void Distancemeasure()
{
TMOD&=0x0f;
TH1=0X00;
TL1=0X00;
sendwave();
TR1=1;
while((RX==1)&&(TF1==0));
TR1=0;
if(TF1==1)
{
distance=999;
TF1=0;
}
else
{
time=(TH1<<8)|TL1;
distance=time*0.0172;
}
}
void distance_measure()
{
if(distance_count>100)
{
distance_count=0;
Distancemeasure();
}
}