上电数码管显示时间,按下S7显示测量距离,松开显示时间;按下S6显示温度,松开显示时间。向串口助手发送send,串口助手接受时间,测量距离,和当前温度。 main.c
#include <stc15f2k60s2.h> #include <ds1302.h> #include <intrins.h> #include "onewire.h" sbit s7=P3^0; sbit s6=P3^1; sbit TX=P1^0; sbit RX=P1^1; unsigned char c1,c2; unsigned char mingling; unsigned char code tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; unsigned char display[]={0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}; unsigned int wendu,ti,distance; unsigned char shou[]="send"; void Timer0Init(void); void UartInit(void); void SendByte(unsigned char dat); void Send_Wave(); void xianshi(); void Delay10ms(); void anjian(); void mdistance(); void Delay12us(); void SendStr(unsigned char *s); void working(); void main() { UartInit();ES=1; EA=1;ET0=1;Timer0Init(); P2=(P2&=0X1F)|0XA0;P0=0X00;P2&=0X1F; DS_init(); SendStr(" 请");SendStr("输");SendStr("入");SendStr(" :");SendStr("\r\n"); while(1) { working(); anjian(); xianshi(); DS_get(); } } void xianshi() { display[0]=tab[TIME[2]/16]; display[1]=tab[TIME[2]%16]; display[3]=tab[TIME[1]/16]; display[4]=tab[TIME[1]%16]; display[6]=tab[TIME[0]/16]; display[7]=tab[TIME[0]%16]; } void Timer0Init(void) //2毫秒@11.0592MHz { AUXR |= 0x80; //定时器时钟1T模式 TMOD &= 0xF0; //设置定时器模式 TL0 = 0x9A; //设置定时初值 TH0 = 0xA9; //设置定时初值 TF0 = 0; //清除TF0标志 TR0 = 1; //定时器0开始计时 } void shuma() interrupt 1 { unsigned char i; unsigned int p; P2=(P2&0X1F)|0XE0; P0=0XFF; P2&=0X1F; P2=(P2&0X1F)|0XC0; P0=1<<i; P2&=0X1F; P2=(P2&0X1F)|0XE0; P0=display[i]; P2&=0X1F; i++; if(i>=8)i=0; if((s7!=0)&&(s6!=0)) { p++; if(p==250) { display[2]=display[5]=0XfF; } else if(p==500) { p=0; display[2]=display[5]=0XbF; } } } void anjian() { unsigned int t; if(s7==0) { Delay10ms(); while(s7==0) { t++; if(t>=5000) { t=0; mdistance(); display[0]=0xff; display[1]=0xff; display[2]=0xff; display[3]=0xff; display[4]=0xff; display[5]=tab[distance%1000/100]; display[6]=tab[distance%100/10]; display[7]=tab[distance%10]; } } } if(s6==0) { Delay10ms(); while(s6==0) { t++; if(t>=5000) { wendu=readtemp(); display[0]=tab[wendu%10000/1000]; display[1]=tab[wendu%1000/100]&0x7f; display[2]=tab[wendu%100/10]; display[3]=tab[wendu%10]; display[4]=0xff; display[5]=0xff; display[6]=0xff; display[7]=0xff; } } } } void Delay10ms() //@11.0592MHz { unsigned char i, j; i = 108; j = 145; do { while (--j); } while (--i); } void Send_Wave() { unsigned char i; for(i=0;i<8;i++) { TX=1; Delay12us(); TX=0; Delay12us(); } } void mdistance() { unsigned int time=0; TMOD&=0X0F;//定时器1模式 TL1=0; TH1=0;//初始化 Send_Wave(); //发送声波信号 TR1=1;//启动定时器 while((RX==1)&&(TF1==0)) ;//等待超声波信号返回或者等到测量超出范围 TR1=0; //停止定时器 if(TF1==0) { ti=TH1; ti=(ti<<8)|TL1; //将计算值装到16为计数器 distance=ti*0.017;//测量距离 } else { TF1=0;//禁止中断溢出 distance=99; } // if(distance>=30) // {P2=0XA0;P0=0Xff;P2=0X1F;} // else // {P2=0XA0;P0=0X00;P2=0X1F;} } void Delay12us() { unsigned char i; _nop_(); _nop_(); i = 33; while (--i); } /*------------------------------------------------ 发送一个字节 ------------------------------------------------*/ void SendByte(unsigned char dat) { SBUF = dat; //发送数据 后TI标志位置1 while(TI==0); //发送完整 TI=0; //停止 } /*------------------------------------------------ 发送一个字符串 ------------------------------------------------*/ void SendStr(unsigned char *s) //字符型指针变量 { while(*s!='\0') { SendByte(*s); s++; } }/*------------------------------------------------ 串口中断程序 ------------------------------------------------*/ void UartInit(void) //9600bps@11.0592MHz { SCON = 0x50; //8位数据,可变波特率 AUXR |= 0x01; //串口1选择定时器2为波特率发生器 AUXR |= 0x04; //定时器2时钟为Fosc,即1T T2L = 0xE0; //设定定时初值 T2H = 0xFE; //设定定时初值 AUXR |= 0x10; //启动定时器2 } void UART(void) interrupt 4 { if(RI) //是否接收完整 如果接收完整 RT置1 { RI=0; mingling=SBUF; //将接收到的数据写入mingling if(mingling!='\0') { if(mingling==shou[c1++]) { c2++; if(c2==4)mingling=1; else mingling=2; } } } if(TI) TI=0; } void working() //接受上位机命令工作 { switch(mingling) { case 1: mdistance(); SendStr("\r\n"); SendStr("\r\n"); SendStr("时");SendStr("间");SendByte(TIME[2]/16+0x30);SendByte(TIME[2]%16+0x30);SendStr("-"); SendByte(TIME[1]/16+0x30);SendByte(TIME[1]%16+0x30);SendStr("-");SendByte(TIME[0]/16+0x30);SendByte(TIME[0]%16+0x30); SendStr("\r\n"); SendStr("距");SendStr("离"); SendByte(distance%100/10+0x30);SendByte(distance%10+0x30);SendStr("cm"); wendu=readtemp(); SendStr("\r\n");SendStr("温");SendStr("度");SendByte(wendu%10000/1000+0x30);SendByte(wendu%1000/100+0x30);SendStr("."); SendByte(wendu%100/10+0x30);SendByte(wendu%10/1+0x30);SendStr("°");SendStr("c"); SendStr("\r\n"); c1=c2=0; mingling=0; break; case 2:SendStr("\r\n"); SendStr("error"); c1=c2=0; mingling=0; break; } }ds1302.c
#include<ds1302.h> sbit SCK=P1^7; sbit SDA=P2^3; sbit RST = P1^3; // DS1302?? unsigned char code READ_RTCADDR[7]={0X81,0X83,0X85,0X87,0X89,0X8B,0X8D}; unsigned char code WRITE_RTCADDR[7]={0x80,0X82,0X84,0X86,0X88,0X8C,0X8E}; char TIME[7]={0x50,0x59,0x23}; 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); } void DS_init() { unsigned char n; Write_Ds1302_Byte(0x8e,0x00);//关闭写保护 for(n=0;n<3;n++) Write_Ds1302_Byte(WRITE_RTCADDR[n],TIME[n]); Write_Ds1302_Byte(0x8e,0x80); } void DS_get() { unsigned char n; for(n=0;n<3;n++) TIME[n]=Read_Ds1302_Byte (READ_RTCADDR[n]); }ds1302.h
#ifndef __DS1302_H_ #define __DS1302_H_ #include<stc15f2k60s2.h> #include<intrins.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 ); void DS_init(); void DS_get(); extern char TIME[7]; //---??????--// #endifonewire.c
/* 程序说明: 单总线驱动程序 软件环境: Keil uVision 4.10 硬件环境: CT107单片机综合实训平台(外部晶振12MHz) STC89C52RC单片机 日 期: 2011-8-9 */ #include "reg52.h" unsigned int temp; sbit DQ = P1^4; //单总线接口 //单总线延时函数 void Delay_OneWire(unsigned int t) //STC89C52RC { unsigned char i; while(t--) { for(i=0;i<12;i++); } } //通过单总线向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; } unsigned int readtemp() { float tp; unsigned char th,tl; init_ds18b20(); Write_DS18B20(0xcc); Write_DS18B20(0x44); Delay_OneWire(200); init_ds18b20(); Write_DS18B20(0xcc); Write_DS18B20(0xbe); tl=Read_DS18B20(); th=Read_DS18B20(); temp=th; temp<<=8; temp|=tl; if(temp<0) { temp=~temp; temp=temp-1; tp=temp; temp=tp*0.0625*100+0.5; } else { tp=temp; temp=tp*0.0625*100+0.5; } return temp; }onewire.h
#ifndef __ONEWIRE_H #define __ONEWIRE_H unsigned char rd_temperature(void); //; ; unsigned int readtemp(); #endif