#include <intrins.h>//Keil library (is used for _nop()_ operation)
#include <math.h> //Keil library
#include <stdio.h> //Keil library
unsigned char Tem,Hum
unsigned char Set_Tem,Set_Hum
sbit SS = P1^0 //片选
sbit SCLK = P1^1 //ISD4003 时钟
sbit MOSI = P1^2 //数据输入
sbit MISO = P1^3 //数据输出
sbit LED = P1^7 //指示灯
sbit ISD_INT = P3^2//中断
sbit AN = P1^6//执行
sbit STOP = P1^5 //复位
sbit PR = P1^4 //PR=1 录音PR=0 放音
sbit DATA=P2^0
sbit SCK=P2^1
sbit SCL=P1^1
sbit SDA=P1^0
#define TEMP 0
#define HUMI 1
typedef union
{ unsigned int i
float f
} value
//enum {,EMP,HUMI}
//以上所示为系统的主程序结构,其中子程序可根据系统整个具体的要求进行添加代码,
//刷新LED显示子程序write_led()硬件采用译码器;按键检测子程序check_key()的执行通过读单片机I/O口高低电平识别按键。
//以下所示代码为读温湿度传感器子程序read_ sensor()的程序内容:
/********************************************************************
工程名 SHTxx demo program (V2.1)
文件名: SHTxx_Sample_Code.c
MCU:80C51 family
编译器: Keil Version 6.14
*******************************************************************/
//-------------------------------------------------------------------
// modul-var
//-------------------------------------------------------------------
void warning(void)
void Delay(unsigned int time)
#define noACK 0
#define ACK 1
unsigned int *p_value
#define STATUS_REG_W 0x06 //000 00110
#define STATUS_REG_R 0x07 //000 00111
#define MEASURE_TEMP 0x03 //000 00011
#define MEASURE_HUMI 0x05 //000 00101
#define RESET0x1e //000 11110
//-------------------------------------------------------------------
char s_write_byte(unsigned char value)
//-------------------------------------------------------------------
// 写一个字节,检查应答信号
{
unsigned char idata i,error=0
for (i=0x80i>0i/=2)
{ if (i &value) DATA=1
else DATA=0
SCK=1
_nop_()_nop_()_nop_() //时钟脉冲宽度 5 us
SCK=0
}
DATA=1 //释放DATA
SCK=1 //9个CLK后应答
error=DATA//检查应答信号 (DATA 被拉低)
SCK=0
return error// 如果没有应答则error=1
}//
//-------------------------------------------------------------------
char s_read_byte(unsigned char ack)
//-------------------------------------------------------------------
// 读一个字节,检查应答信号
{
unsigned char i,val=0
DATA=1 //释放DATA信号
for (i=0x80i>0i/=2)
{ SCK=1
if (DATA) val=(val | i)
SCK=0
}
DATA=!ack //如果 "ack==1" ,拉低DATA
SCK=1 //clk #9 for ack
_nop_()_nop_()_nop_() //延时5微秒
SCK=0
DATA=1 //释放DATA
return val
}
//-------------------------------------------------------------------
void s_transstart(void)
//-------------------------------------------------------------------
// generates a transmission start
// _____ ________
// DATA: |_______|
// ___ ___
// SCK : ___| |___| |______
{
DATA=1SCK=0 //初始状态
_nop_()
SCK=1
_nop_()
DATA=0
_nop_()
SCK=0
_nop_()_nop_()_nop_()
SCK=1
_nop_()
DATA=1
_nop_()
SCK=0
}
//-------------------------------------------------------------------
void s_connectionreset(void)
//-------------------------------------------------------------------
//通讯复位: 至少在9 SCK 周期后,DATA=1 传输开始
// _____________________________________________________
// DATA: //|_______|
// ____________ ___
// SCK : __| |__| |__| |__| |__| |__| |__| |__| |__| |______| |___|
{
unsigned char i
DATA=1SCK=0 //初始状态
for(i=0i<9i++) //9 SCK周期
{ SCK=1
SCK=0
}
s_transstart() //通讯开始
}
//-------------------------------------------------------------------
char s_softreset(void)
// resets the sensor by a softreset
{
unsigned char error=0
s_connectionreset() //复位通讯
error+=s_write_byte(RESET) //发送复位命令
return error//如果传感器没有响应则error=1
}
//-------------------------------------------------------------------
char s_read_statusreg(unsigned char *p_value,unsigned *p_checksum)
//-------------------------------------------------------------------
//读效验寄存器状态 (8-bit)
{
unsigned char error=0
s_transstart() //通讯开始
error=s_write_byte(STATUS_REG_R)//发送命令
*p_value=s_read_byte(ACK) //读状态寄存器(8-bit)
*p_checksum=s_read_byte(noACK) //读效验和
return error //如果传感器没有响应则error=1
}
//-------------------------------------------------------------------
char s_write_statusreg(unsigned char *p_value)
//-------------------------------------------------------------------
// writes the status register with checksum (8-bit)
{
unsigned char error=0
s_transstart() //通讯开始
error+=s_write_byte(STATUS_REG_W)// 发送命令
error+=s_write_byte(*p_value) //发送状态寄存器的值
return error//如果传感器没有响应则error=1
}
//-------------------------------------------------------------------
char s_measure(unsigned char *p_value, unsigned char *p_checksum, unsigned char mode)
//-------------------------------------------------------------------
// makes a measurement (humidity/temperature) with checksum
{
unsigned char idata error=0
unsigned int i
s_transstart() //通讯开始
switch(mode)
{ //发送名令
case TEMP : error+=s_write_byte(MEASURE_TEMP)break
case HUMI : error+=s_write_byte(MEASURE_HUMI)break
default : break
}
for (i=0i<65535i++) if(DATA==0) break//等待传感器完成测量
if(DATA) error+=1
*(p_value) =s_read_byte(ACK) //读取第一个字节
*(p_value+1)=s_read_byte(ACK) //读取第二个字节
*p_checksum =s_read_byte(noACK) //读取效验和
return error
}
//-------------------------------------------------------------------
//-------------------------------------------------------------------
void calc_sth11(float *p_humidity ,float *p_temperature)
//-------------------------------------------------------------------
// 计算温度和湿度
// input : humi [Ticks] (12 bit)
// temp [Ticks] (14 bit)
// output: humi [%RH]
// temp
{ const float xdata C1=-4.0
const float xdata C2=+0.0405
const float xdata C3=-0.0000028
const float xdata T1=+0.01
const float xdata T2=+0.00008
float rh=*p_humidity//计算湿度值
float t=*p_temperature // 计算温度值
float rh_lin
float rh_true
float t_C
t_C=t*0.01 - 40
rh_lin=C3*rh*rh + C2*rh + C1
rh_true=(t_C-25)*(T1+T2*rh)+rh_lin
if(rh_true>100)rh_true=100 //如果结果超出了可能的范围就取消
if(rh_true<0.1)rh_true=0.1
*p_temperature=t_C
*p_humidity=rh_true
}
//-------------------------------------------------------------------
float calc_dewpoint(float h,float t)
//-------------------------------------------------------------------
// calculates dew point
// input: humid,ty , temperature
// output: dew point
{ float dew_point,logEx
logEx=0.66077+7.5*t/(237.3+t)+(log10(h)-2)
dew_point = (logEx - 0.66077)*237.3/(0.66077+7.5-logEx)
return dew_point
}
//-------------------------------------------------------------------
void main_measure()
//-------------------------------------------------------------------
// 使用SHT10功能步骤:
// 1.通讯复位
// 2. 测量温度,湿度
// 3. 计算温度,湿度
// 45. 显示温度,湿度
{ value humi_val,temp_val
float dew_point,error
unsigned char checksum
unsigned int idata i
s_connectionreset()
while(1)
{ error=0
error+=s_measure((unsigned char*) &humi_val.i,&checksum,HUMI) //测量湿度
error+=s_measure((unsigned char*) &temp_val.i,&checksum,TEMP) //测量温度
if(error!=0) s_connectionreset()
//如果有错误就复位
else
{ humi_val.f=(float)humi_val.i//将整数转换成浮点数
temp_val.f=(float)temp_val.i
calc_sth11(&humi_val.f,&temp_val.f)
//计算温度,湿度
dew_point=calc_dewpoint(humi_val.f,temp_val.f)
//计算dew
//printf("temp:%5.1fC humi:%5.1f%% dew point:%5.1f,\n",temp_v,l.f,humi_v,l.f,dew_point)
}
for (i=0i<40000i++)//----------延时0.8s
}
}
//语音功能子程序
//下面代码为语音芯片使用范例,该功能放在主程序中的warning()子程序中执行。
void delay(unsigned int time) //延迟 n 微秒
{
while(time!=0)
{
time--
}
}
void delayms(unsigned int time) //延迟 n 毫秒
{
TMOD=0x01
for(timetime>0time--)
{
TH0 = 0xfc
TL0 = 0x18
TR0 = 1
while(TF0!=1)
{}
TF0=0
TR0=0
}
}
//************************************
//ISD4002 spi 串行发送子程序,8 位数据
//************************************
void spi_send(unsigned char isdx)
{
unsigned char idata k
SS=0//SS=0 //,s=0,打开 spi 通信端
SCLK=0
for(k=0k<8k++) //先发低位再发高位,依发送。 { i
{
if((isdx&0x01)==1)
MOSI=1
else
MOSI=0
isdx=isdx>>1
SCLK=1
delay(2)
SCLK=0
delay(2)
}
}
//*******************************
//发送 stop 指令
//*******************************
void isd_stop(void)
{
delay(10)
spi_send(0x30)
SS=1
delayms(50)
}
//*******************************
//发送上电指令,并延迟 50ms
//*******************************
void isd_pu(void)
{ delay(10)
SS=0
spi_send(0x20)
SS=1
delayms(50)
}
//发送掉电指令,并延迟 50ms
//*******************************
void isd_pd(void)
{
delay(10)
spi_send(0x10)
SS=1
delayms(50)
}
//*******************************
//发送 play 指令
//*******************************
void isd_play(void)
{
LED=0
spi_send(0xf0)
SS=1
}
//*******************************
//发送 rec 指令
//*******************************
void isd_rec(void)
{
LED=0
spi_send(0xb0)
SS=1
}
//*******************************
//发送 setplay 指令
//*******************************
void isd_setplay(unsigned char adl,unsigned char adh)
{
spi_send(adl) //发送放音起始地址低位
adh=adh||0xe0
spi_send(adh) //发送放音起始地址高位
SS=1
}
//*******************************
//发送 setrec 指令
//*******************************
void isd_setrec(unsigned char adl,unsigned char adh)
{
spi_send(adl) //发送放音起始地址低位
adh=adh||0xa0
spi_send(adh) //发送放音起始地址高位
SS=1
}
//************************************
//芯片溢出,LED 闪烁提醒停止录音
//************************************
void isd_overflow(void)
{
while(AN==0)
{
LED=1
delayms(300)
LED=0
delayms(300)
}
}
//************************************
//检查芯片是否溢出(读,OVF,并返回 OVF 值)
//************************************
unsigned char chk_isdovf(void)
{
SS=0
delay(2)
SCLK=0
delay(2)
SCLK=1
SCLK=0
delay(2)
if (MISO==1)
{
SCLK=0
SS =1 //关闭 spi 通信端
isd_stop() //发送 stop 指令
return 1 //OVF 为 1,返回 1
}
else
{
SCLK=0
SS =1 //关闭 spi 通信端
isd_stop()//发送 stop 指令
return 0 //OVF 为 0,返回 0
}
}
//**********************************************************************
//主程序
//功能:1.录音时,按住 AN 键,LED 点亮开始录音,松开 AN 即可停止录音
// 再次按下 AN 键,LED 点亮开始录第二段音,依次类推,直到芯片溢出。
// 按 stop 键芯片复位
// 2.放音时,按一下 AN 键,即播放一段语音。按 stop 键芯片复位。
//************************************************************************
void voice(void)
{
unsigned char ovflog
while(1)
{
P0=P1=P2=P3=0xff//初始化
while (AN==1) //等待 AN 键按下
{
if (AN==0) //按键防抖动
{delayms(20)}
}
isd_pu() // AN 键按下,ISD 上电并延迟 50ms
isd_pd()
isd_pu()
if (PR==1) //如果 PR=1 则转入录音部分
{
delayms(500)//延迟录音
isd_setrec(0x00,0x00) //发送 0x0000h 地址的 setplay 指令
do
{
isd_rec() //发送 rec 指令
while(AN==0) //等待录音完毕
{
if (ISD_INT==0)//如果芯片溢出,进行 LED 闪烁提示,
isd_overflow()//如果取消录音(松开AN键)则停止录音,芯片复位
}
if (ISD_INT==0)
break
LED=1//录音完毕,LED 熄灭
isd_stop() //发送停止命令
while(AN==1) //如果 AN 再次按下,开始录制下一段语音
{
if(STOP==0) //如果按下 STOP 按键,则芯片复位
break
if (AN==0)
delayms(500)
}
}while(AN==0)
}
else //如果 PR==0 则转入放音部分
{
while(AN==0){}
isd_setplay(0x00,0x00)//发送 setplay 指令,从 0x0000 地址开始放音
do
{
isd_play()//发送放音指令
delay(20)
while(ISD_INT==1) //等待放音完毕的 EOM 中断信号
{}
LED=1
isd_stop() //放音完毕,发送 stop 指令
if (ovflog=chk_isdovf())//检查芯片是否溢出,如溢出则停止放音,芯片复位
break
while(AN==1)//等待 AN 键再次按下
{
if (STOP==0)
break
if(AN==0)
delayms(20)
}
}while(AN==0) // AN 键再次按下,播放下一段语音
}
isd_stop()
isd_pd()
}
}
#define ZLG7290 0x70
#define RADR 0x01
#define uchar unsigned char
#define uint unsigned int
/************************************/
void I2cStart(void)
{
SDA=1
SCL=1
Delay(10)
SDA=0
Delay(10)
SCL=0
}
/************************************/
void I2cStop(void)
{
SDA=0
SCL=1
Delay(10)
SDA=1
Delay(10)
SCL=0
}
/************************************/
void WriteI2cByte(uchar dat)
{
uchar k
SCL=0
for (k=0k<8k++)
{
SDA=(bit)(dat&0x80)
SCL=1
Delay(10)
SCL=0
dat<<=1
}
SCL=0
}
/*************************************/
uchar ReadI2cByte(void)
{
uchar dat,k
for (k=0k<8k++)
{
SCL=0
SDA=1 //一定要将SDA置为高电平,否则不能正常连续取数据
Delay(10)
SCL=1
dat<<=1
if (SDA)
dat|=0x01
SCL=0
Delay(10)
}
SCL=0
return dat
}
/*************************************/
void SendAck(void)
{
SDA=0
Delay(10)
SCL=1
Delay(10)
SCL=0
}
/*************************************/
void SendNoAck(void)
{
SDA=1
SCL=1
Delay(10)
SCL=0
}
/************************************/
void I2cWaitAck(void)
{
uchar ack
SDA=1
SCL=1
Delay(10)
ack=SDA
SCL=0
}
/***********************************************************/
void I2cReadSequence(uchar sla,uchar sbua,uchar *s,uchar len)
{
uchar l
I2cStart()
WriteI2cByte(sla)
I2cWaitAck()
WriteI2cByte(sbua)
I2cWaitAck()
I2cStart()
WriteI2cByte(sla+1)
I2cWaitAck()
for (l=0l<len-1l++)
{
*s=ReadI2cByte()
SendAck()
s++
}
*s=ReadI2cByte()
SendNoAck()
I2cStop()
}
/************************************************************/
void I2cWriteSequence(uchar sla,uchar sbua,uchar *s,uchar len) //wr
{
uchar k
I2cStart()
WriteI2cByte(sla)
I2cWaitAck()
WriteI2cByte(sbua)
I2cWaitAck()
for (k=0k<lenk++)
{
WriteI2cByte(*s)
I2cWaitAck()
s++
}
I2cStop()
}
/**************************************************************/
void I2cWriteByteToSlaver(uchar sla,uchar sbua,uchar dat)
{
I2cStart()
WriteI2cByte(sla)
I2cWaitAck()
WriteI2cByte(sbua)
I2cWaitAck()
WriteI2cByte(dat)
I2cWaitAck()
I2cStop()
Delay(10)
}
/**************************************************************/
uchar I2cReadByteFromSlaver(uchar sla,uchar sbua)
{
uchar dat
I2cStart()
WriteI2cByte(sla)
I2cWaitAck()
WriteI2cByte(sbua)
I2cWaitAck()
I2cStart()
WriteI2cByte(sla+1)
I2cWaitAck()
dat=ReadI2cByte()
SendAck()
SendNoAck()
I2cStop()
return dat
}
/**************************************************/
void main()
{
voice()//完成语音芯片的初始化 置入工作状态
s_softreset()
while(1)//进入程序主循环
{
main_measure()//读温湿度传感器 得到温度值Tem 湿度值Hum
/* if(Tem>Set_Tem &&Hum >Set_Hum)//设置报警区间
{
warning()//执行警告 启动报警
} */
}
}
/*********************************************************************
文件名
:
温度采集DS18B20.c
*
描述
:
该文件实现了用温度传感器件DS18B20对温度的采集,并在数码管上显示出来。
*
创建人
:
东流,2009年4月10日
*
版本号
:
2.0
***********************************************************************/
#include<reg52.h>
#define
uchar
unsigned
char
#define
uint
unsigned
int
#define
jump_ROM
0xCC
#define
start
0x44
#define
read_EEROM
0xBE
sbit
DQ
=
P2^3
//DS18B20数据口
unsigned
char
TMPH,TMPL
uchar
code
table[10]
=
{0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}
/********************************************************************
*
名称
:
delay()
*
功能
:
延时,延时时间大概为140US。
*
输入
:
无
*
输出
:
无
***********************************************************************/
void
delay_1()
{
int
i,j
for(i=0
i<=10
i++)
for(j=0
j<=2
j++)
}
/********************************************************************
*
名称
:
delay()
*
功能
:
延时函数
*
输入
:
无
*
输出
:
无
***********************************************************************/
void
delay(uint
N)
{
int
i
for(i=0
i<N
i++)
}
/********************************************************************
*
名称
:
Delay_1ms()
*
功能
:
延时子程序,延时时间为
1ms
*
x
*
输入
:
x
(延时一毫秒的个数)
*
输出
:
无
***********************************************************************/
void
Delay_1ms(uint
i)//1ms延时
{
uchar
x,j
for(j=0j<ij++)
for(x=0x<=148x++)
}
/********************************************************************
*
名称
:
Reset()
*
功能
:
复位DS18B20
*
输入
:
无
*
输出
:
无
***********************************************************************/
uchar
Reset(void)
{
uchar
deceive_ready
DQ
=
0
delay(29)
DQ
=
1
delay(3)
deceive_ready
=
DQ
delay(25)
return(deceive_ready)
}
/********************************************************************
*
名称
:
read_bit()
*
功能
:
从DS18B20读一个位值
*
输入
:
无
*
输出
:
从DS18B20读出的一个位值
***********************************************************************/
uchar
read_bit(void)
{
uchar
i
DQ
=
0
DQ
=
1
for(i=0
i<3
i++)
return(DQ)
}
/********************************************************************
*
名称
:
write_bit()
*
功能
:
向DS18B20写一位
*
输入
:
bitval(要对DS18B20写入的位值)
*
输出
:
无
***********************************************************************/
void
write_bit(uchar
bitval)
{
DQ=0if(bitval==1)
DQ=1
delay(5)
DQ=1
}
/********************************************************************
*
名称
:
read_byte()
*
功能
:
从DS18B20读一个字节
*
输入
:
无
*
输出
:
从DS18B20读到的值
***********************************************************************/
uchar
read_byte(void)
{
uchar
i,m,receive_data
m
=
1
receive_data
=
0
for(i=0
i<8
i++)
{
if(read_bit())
{
receive_data
=
receive_data
+
(m
<<
i)
}
delay(6)
}
return(receive_data)
}
/********************************************************************
*
名称
:
write_byte()
*
功能
:
向DS18B20写一个字节
*
输入
:
val(要对DS18B20写入的命令值)
*
输出
:
无
***********************************************************************/
void
write_byte(uchar
val)
{
uchar
i,temp
for(i=0
i<8
i++)
{
temp
=
val
>>
i
temp
=
temp
&
0x01
write_bit(temp)
delay(5)
}
}
/********************************************************************
*
名称
:
Main()
*
功能
:
主函数
*
输入
:
无
*
输出
:
无
***********************************************************************/
void
main()
{
float
tt
uint
temp
P2
=
0x00
while(1)
{
Reset()
write_byte(jump_ROM)
write_byte(start)
Reset()
write_byte(jump_ROM)
write_byte(read_EEROM)
TMPL
=
read_byte()
TMPH
=
read_byte()
temp
=
TMPL
/
16
+
TMPH
*
16
P0
=
table[temp/10%10]
P2
=
6
Delay_1ms(5)
P0
=
table[temp%10]
P2
=
7
Delay_1ms(5)
}
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)