蓝桥杯单片机学习过程记录(十二)第四届智能灌溉
这部分应该是写麻烦了,后面根据理解会改进
过程中遇到了几个问题:
一是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;
}