74HC595和74HC138控制程序
void Device_ctrl(unsigned char p2date,unsigned char p0date)//p0date为数据p2date为选中模块
{
P0=p0date;
P2=P2&0x1f|p2date;
P2&=0x1f;
}
系统初始化关闭蜂鸣器LED继电器
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
|