蓝桥杯单片机学习过程记录(十二)第四届智能灌溉

蓝桥杯单片机学习过程记录(十二)第四届智能灌溉


这部分应该是写麻烦了,后面根据理解会改进
过程中遇到了几个问题:
一是SCL=P20;SDA=P21;弄混了
二是iic_stop中开始应该是SCL=1;SDA=0;->SDA=0;
第三个是时钟函数、iic等不熟悉,不能很快的写出。

应用的内容:
led小灯、数码管
独立按键
蜂鸣器继电器
IIC通信eep保存rd2
时钟DS1302

主函数

//第四届智能灌溉
#include<STC15F2K60S2.H>
#include<intrins.h>
sbit s4=P3^3;
sbit s5=P3^2;
sbit s6=P3^1;
sbit s7=P3^0;
sbit sck=P1^7;
sbit io=P2^3;
sbit ce=P1^3;
sbit SCL=P2^0;
sbit SDA=P2^1;
unsigned char shidu;
unsigned char t;
unsigned char shidu_set;
unsigned char shijian[7];
unsigned char init_time[]={0,30,8,0,0,0};
unsigned char flag_guangai;
unsigned char flag_zhuangtai;
unsigned char flag_s6_0=0;
unsigned char flag_s6_1=1;
unsigned char seg[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf,0xff};
unsigned char yi,er,san,si,wu,liu,qi,ba;
void delayms(int ms);
void display_12(yi,er);
void display_34(san,si);
void display_56(wu,liu);
void display_78(qi,ba);
void allinit();
void key_scan_0();
void key_scan_1();
void ds1302_get(void);
void ds1302_init();
void Delay6us();
void ds1302_write(unsigned char address,unsigned char dat);
unsigned char ds1302_read(unsigned char address);
void write_byte(unsigned char temp);
unsigned char eep_read(unsigned char address);
unsigned char iic_read();
void eep_write(unsigned char address,unsigned char dat);
void main(){
 //初始化
 allinit();
 ds1302_init();
 //读取eep中的值
 shidu_set=eep_read(0x04);
 delayms(2);
 while(1){
  //获取时钟值
  ds1302_get();
  //读取湿度值
  shidu=iic_read();delayms(2);
  //自动状态
  if(flag_zhuangtai==0){
   //led1亮
   P2=0X80;P0=~0X01;
   //自动状态下的按键
   key_scan_0();
   //湿度小于阈值打开
   if(shidu<shidu_set){
   //继电器打开
   P2=0XA0;P0=0X10;
   }
   else{
    //继电器关闭
    P2=0XA0;P0=0X00;
   }
   //s6湿度阈值设置
   if(flag_s6_0==1){
    yi=10;er=10;san=11;si=11;
    wu=11;liu=11;qi=shidu_set%100/10;ba=shidu_set%10;
   }
   else{
    yi=shijian[2]/10;er=shijian[2]%10;san=10;si=shijian[1]/10;wu=shijian[1]%10; liu=11;qi=shidu%100/10;ba=shidu%10;
   }
  } 
  //手动状态
  else if(flag_zhuangtai==1){
   //小灯2开
   P2=0X80;P0=~0X02;
   //如果湿度低于阈值
   if(shidu<shidu_set){
    //继电器工作与蜂鸣器四种情况
    if(flag_guangai==0 && flag_s6_1==0){
     P2=0XA0;P0=0x00;
    }
    else if(flag_guangai==0&&flag_s6_1==1){
     P2=0XA0;P0=0x40;
    }
    else if(flag_guangai==1&&flag_s6_1==0){
     P2=0XA0;P0=0x10;
    }
    else if(flag_guangai==1&&flag_s6_1==1){
     P2=0XA0;P0=0x50;
    }
    yi=shijian[2]/10;er=shijian[2]%10;san=10;si=shijian[1]/10;wu=shijian[1]%10; liu=11;qi=shidu%100/10;ba=shidu%10;
   }
   else {
    //高于阈值的蜂鸣器不响的两种情况
    if(flag_guangai==0){
     P2=0XA0;P0=0x00;
    }
    else if(flag_guangai==1){
     P2=0XA0;P0=0x10;
    }
    yi=shijian[2]/10;er=shijian[2]%10;san=10;si=shijian[1]/10;wu=shijian[1]%10; liu=11;qi=shidu%100/10;ba=shidu%10;
   }
   key_scan_1();
  }
 display_12(yi,er);
 display_34(san,si);
 display_56(wu,liu);
 display_78(qi,ba); 
 }
}

按键函数

//自动时的按键
void key_scan_0(){
 //s4在s6状态下-1
 if(s4==0){
  delayms(5);
  if(s4==0){
   if(flag_s6_0==1)
    shidu_set=shidu_set-1;
  }
  while(!s4);
 }
 //s5在s6状态下+1
 else if(s5==0){
  delayms(5);
  if(s5==0){
   if(flag_s6_0==1)
    shidu_set=shidu_set+1;
  }
  while(!s5);
 }
 //s6进入设置,退出保存
 else if(s6==0){
  delayms(5);
  if(s6==0){
   if(flag_s6_0==0)
    flag_s6_0=1;
   else{
    flag_s6_0=0;
    //eep保存
    eep_write(0x04,shidu_set);
    delayms(2);
   }
  }
  while(!s6);
 }
 //s7改变状态
 else if(s7==0){
  delayms(5);
  if(s7==0){
   flag_zhuangtai=1;
  }
  while(!s7);
 }
}
//手动时的按键
void key_scan_1(){
 if(s4==0){
  delayms(5);
  if(s4==0){
   //s4继电器打开,关闭灌溉
   flag_guangai=0;
  }
  while(!s4);
 }
 else if(s5==0){
  delayms(5);
  if(s5==0){
   //s5继电器打开,打开灌溉
   flag_guangai=1;
  }
  while(!s5);
 }
 //s6开关蜂鸣器
 else if(s6==0){
  delayms(5);
  if(s6==0){
   if(flag_s6_1==0)
    flag_s6_1=1;
   else
    flag_s6_1=0;
  }
  while(!s6);
 }
 //s7状态转换
 else if(s7==0){
  delayms(5);
  if(s7==0){
   flag_zhuangtai=0;
  }
  while(!s7);
 }
}

通信

//iic启动
void iic_start(){
 SDA=1;SCL=1;Delay6us();
 SDA=0;Delay6us();
 SCL=0;
}
//iic关闭
void iic_stop(){
 SDA=0;SCL=1;Delay6us();
 SDA=1;Delay6us();
}
//iic等待响应
void iic_wait(){
 SDA=1;Delay6us();
 SCL=1;Delay6us();
 if(SDA){
  SCL=0;
  Delay6us();
  iic_stop();
 }
 else
  SCL=0;
}
//iic发送
void iic_send(unsigned char dat){
 unsigned char i;
 for(i=0;i<8;i++){
  if(dat&0x80)
   SDA=1;
  else
   SDA=0;
  Delay6us();
  SCL=1;
  dat<<=1;
  Delay6us();
  SCL=0;
 }
}
//iic接收
unsigned char iic_rect(){
 unsigned char i;
 unsigned char dat;
 for(i=0;i<8;i++){
  SCL=1;Delay6us();
  dat<<=1;
  if(SDA)
   dat|=0x01;
  SCL=0;
  Delay6us();
 }
 return dat;
}
//iic读取
unsigned char iic_read(){
 unsigned char temp;
 iic_start();
 iic_send(0x90);
 iic_wait();
 iic_send(0x03);
 iic_wait();
 iic_stop();
 iic_start();
 iic_send(0x91);
 iic_wait();
 temp=iic_rect();
 iic_stop();
 //100%转换
 temp=temp*0.39;
 return temp;
}
//eep写入
void eep_write(unsigned char address,unsigned char dat){
 iic_start();
 iic_send(0xa0);
 iic_wait();
 iic_send(address);
 iic_wait();
 iic_send(dat);
 iic_wait();
 iic_stop();
}
//eep读取
unsigned char eep_read(unsigned char address){
 unsigned char temp;
 iic_start();
 iic_send(0xa0);
 iic_wait();
 iic_send(address);
 iic_wait();
 iic_stop();
 iic_start();
 iic_send(0xa1);
 iic_wait();
 temp=iic_rect();
 iic_stop();
 return temp;
}

时钟及其他

//时钟获取
void ds1302_get(void){
 unsigned char i,add;
 add=0x81;
 ds1302_write(0x8e,0x00);
 for(i=0;i<7;i++){
  shijian[i]=ds1302_read(add);
  add=add+2;
 }
 ds1302_write(add,0x80);
}
//时钟初始化
void ds1302_init(void){
 unsigned char i,add;
 add=0x80;
 ds1302_write(0x8e,0x00);
 for(i=0;i<7;i++){
  ds1302_write(add,init_time[i]);
  add=add+2;
 }
 ds1302_write(0x8e,0x80);
}
//上升沿写入
void ds1302_write(unsigned char address,unsigned char dat){
 unsigned char i;
 ce=0;_nop_();
 sck=0;_nop_();
 ce=1;
 for(i=0;i<8;i++){
  sck=0;
  io=address&0x01;
  _nop_();
  sck=1;
  address>>=1;
 }
 dat=(((dat/10)<<4)|(dat%10));
 for(i=0;i<8;i++){
  sck=0;
  io=dat&0x01;
  sck=1;
  dat>>=1;
 }
}
//下降沿读取
unsigned char ds1302_read(unsigned char address){
 unsigned char i,temp,dat_1,dat_2;
 ce=0;sck=0;ce=1;
 write_byte(address);
 for(i=0;i<8;i++){
  sck=0;
  temp>>=1;
  if(io)
   temp|=0x80;
  sck=1;
 }
 io=0;
 dat_1=temp/16;
 dat_2=temp%16;
 temp=dat_1*10+dat_2;
 return temp;
}
//字节写入
void write_byte(unsigned char temp){
 unsigned char i;
 for(i=0;i<8;i++){
  sck=0;
  io=temp&0x01;
  sck=1;
  temp>>=1;
 }
}
//延时函数
void delayms(int ms){
 int q,w;
 for(q=0;q<ms;q++)
  for(w=0;w<845;w++);
}
//数码管12
void display_12(yi,er){
 P2=0XC0;P0=0X01;P2=0XE0;P0=seg[yi];delayms(1);
 P2=0XC0;P0=0X02;P2=0XE0;P0=seg[er];delayms(1);
}
//数码管34
void display_34(san,si){
 P2=0XC0;P0=0X04;P2=0XE0;P0=seg[san];delayms(1);
 P2=0XC0;P0=0X08;P2=0XE0;P0=seg[si];delayms(1);
}
//数码管56
void display_56(wu,liu){
 P2=0XC0;P0=0X10;P2=0XE0;P0=seg[wu];delayms(1);
 P2=0XC0;P0=0X20;P2=0XE0;P0=seg[liu];delayms(1);
}
//数码管78
void display_78(qi,ba){
 P2=0XC0;P0=0X40;P2=0XE0;P0=seg[qi];delayms(1);
 P2=0XC0;P0=0X80;P2=0XE0;P0=seg[ba];delayms(1);
}
//初始化
void allinit(){
 P2=0XA0;P0=0X00;
 P2=0XC0;P0=0XFF;P2=0XE0;P0=0XFF;
 P2=0X80;P0=0XFF;
}
发布了27 篇原创文章 · 获赞 17 · 访问量 4145

猜你喜欢

转载自blog.csdn.net/weixin_44747240/article/details/104341809