如题,这是之前在学校写的,用的是普中科技的51单片机板,完成蓝桥杯第六届题目,现发出源代码,给有需要的同学参考一下,为了直观,自己加了485通信,并用C#写了个对应485上位机实时检测,连同蓝桥杯第六届题目都一起附上,
上位机界面(附件内含源码):
单片机源程序如下:
- #include <REGX51.H>
- #include <cdm.h>
- #include <stdio.h>
- #include <display.h>
- //#include "intrins.h"
- #define uchar unsigned char
- #define uint unsigned int
- sbit RS485E=P3^6; //定义485的使能脚
- bit jian = 1;
- sbit L1=P1^3;
- sbit J1=P1^4;
- sbit L2=P1^5;
- sbit LSA=P1^2;
- sbit LSB=P1^1;
- sbit LSC=P1^0;
- bit SendFlag;
- unsigned int ReData,SenData;
- // 0 1 2 3 4 5 6 7 8 9 灭 -
- //code unsigned char duan[] = { 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00,0x40};
- //unsigned char wei[8] = {11,3,0,10,10,11,2,0}; //存放设置参数设定数值
- //unsigned char wei_0[8] = {11,10,10,10,10,11,10,10}; // 设置参数初始化
- //unsigned char wei_1[8] = {11,10,11,10,10,10,10,10}; // 温度检测显示数值
- //unsigned char wei_2[4] = {1,2,6,7}; // 指向设置参数设定需改变的地址
- unsigned char wendu[4] = {0,0,0,0};
- unsigned char xiafa[2] = {0,0};
- int gewei = 0;
- int shiwei = 0;
- int j = 0;
- unsigned char ming;//dspcom = 0,;
- char max = 30,min = 20; //上下限温度初始值
- int intr1 = 0,intr2 = 0;
- uchar temperature = 0;
- bit temper_flag = 0; //温度读取标志
- int sendendFlag = 0;
- int cnt = 0;
- char data12 = 0;
- int pinlv = 4; //L1闪烁的频率
- char qujian = 0;
- char jidianqi = 0;
- int FallFlag = 1; //设定工作参数错误标志
- int pinFlag = 0; //L1闪烁标志,决定L1是否闪烁
- int L1_Flag = 0; //L1闪烁标志,决定L1是否闪烁
- //设置参数设定界面扫描函数
- //void display()
- //{
- // P0=0x00;//消隐
- //
- // switch(dspcom) //位选,选择点亮的数码管,
- // {
- // case(0):
- // LSA=0;LSB=0;LSC=0; break;//显示第0位
- // case(1):
- // LSA=1;LSB=0;LSC=0; break;//显示第1位
- // case(2):
- // LSA=0;LSB=1;LSC=0; break;//显示第2位
- // case(3):
- // LSA=1;LSB=1;LSC=0; break;//显示第3位
- // case(4):
- // LSA=0;LSB=0;LSC=1; break;//显示第4位
- // case(5):
- // LSA=1;LSB=0;LSC=1; break;//显示第5位
- // case(6):
- // LSA=0;LSB=1;LSC=1; break;//显示第6位
- // case(7):
- // LSA=1;LSB=1;LSC=1; break;//显示第7位
- // }
- // P0=duan[wei[dspcom]];//发送段码
- // if(++dspcom == 8)
- // {
- // dspcom = 0;
- // }
- //}
- //
- //
- ////检测温度显示区间界面扫描函数
- //void display_1()
- //{
- // P0=0x00;//消隐
- //
- // switch(dspcom) //位选,选择点亮的数码管,
- // {
- // case(0):
- // LSA=0;LSB=0;LSC=0; break;//显示第0位
- // case(1):
- // LSA=1;LSB=0;LSC=0; break;//显示第1位
- // case(2):
- // LSA=0;LSB=1;LSC=0; break;//显示第2位
- // case(3):
- // LSA=1;LSB=1;LSC=0; break;//显示第3位
- // case(4):
- // LSA=0;LSB=0;LSC=1; break;//显示第4位
- // case(5):
- // LSA=1;LSB=0;LSC=1; break;//显示第5位
- // case(6):
- // LSA=0;LSB=1;LSC=1; break;//显示第6位
- // case(7):
- // LSA=1;LSB=1;LSC=1; break;//显示第7位
- // }
- // P0=duan[wei_1[dspcom]];//发送段码
- // if(++dspcom == 8)
- // {
- // dspcom = 0;
- // }
- //}
- //延时函数
- void delay(uint i)
- {
- uint k;
- for(k=0;k<i;k++);
- }
- //void delay1(unsigned char i)
- //{
- // unsigned char j;
- // for(i; i > 0; i--)
- // for(j = 200; j > 0; j--);
- //}
- //设置参数设定函数
- void key_du()
- {
- uchar key,hang,i;//,cnt1;
- ming=0;
- P1_6 = 1;
-
- while(1)
- {
- P2 = 0x0f;
- //L1_Flag = 1;
- if(jian == 0)
- {
- ming = ming+1;
- jian=1;
- }
- if(P2 != 0x0f) //有按键按下
- {
- delay(1200); //消抖
-
- if(P2 != 0x0f)
- {
- if(ming <5)
- {
- if((P2 & 0x08) == 0) hang = 0;
- if((P2 & 0x04) == 0) hang = 1;
- if((P2 & 0x02) == 0) hang = 2;
- P2=0xf0;
- if((P2 & 0x80) == 0) key = (hang+0); while((P2 & 0x80) == 0); //等待按键释放
- if((P2 & 0x40) == 0) key = (hang+3); while((P2 & 0x40) == 0); //等待按键释放
- if((P2 & 0x20) == 0) key = (hang+6); while((P2 & 0x20) == 0); //等待按键释放
- if((P2 & 0x10) == 0) key = (hang+9); while((P2 & 0x10) == 0); //等待按键释放
- if(key == 11) //等待消除键按下,初始化
- {
- for(i=0;i<8;i++)
- {
- wei[i]=wei_0[i];
- }
- ming=0;
- }
- if((key == 10) && (ming == 0))
- {
- intr1 = 0;
- L1_Flag = 0;
- break;
- }
- if((key == 10) &&(ming == 4)) //保存设置参数
- {
- intr1 = 0;
- L1_Flag = 0;
- break;
- }
- if((key!=10) && (key!=11) && (ming !=4)) //修改参数
- {
- if(ming == 0)
- {
- for(i=1;i<8;i++)
- {
- wei[i]=wei_0[i];
- }
- }
- wei[wei_2[ming]]=key;
- jian=0;
- }
- if(ming == 3) //计算上限温度和下限温度
- {
- max = wei[wei_2[0]] * 10 + wei[wei_2[1]];
- min = wei[wei_2[2]] * 10 + wei[wei_2[3]];
- //wendu[2] = (char)max/10;
- //wendu[2] = (char)min;
- if(max < min) //设置错误,L2点亮
- {
-
- L2 = 0;
- FallFlag = 0;
- }
- else //反之熄灭
- {
- FallFlag = 1;
- }
- }
- }
- }
- }
-
- display(); //数码管扫描
- }
- }
- void isr_timer_0(void) interrupt 1 //默认中断优先级 1
- { //uchar intr1,intr2;
- TH0 = (65536 - 10000)/256; //设置定时初值
- TL0 = (65535 - 10000)%256; //设置定时初值
- //display_1();
- if(++intr2 == 100) //10ms执行一次
- {
- intr2 = 0;
- temper_flag = 1; //1s温度读取标志位置1
- pinFlag = 1;
- }
- if(pinFlag == 1 && FallFlag == 1)
- {
- if(++intr1 == pinlv) //10ms执行一次
- {
- intr1 = 0;
- if(L1_Flag == 0)
- {
- L1 = !L1;
- }
- }
- }
-
- }
- void ser_int (void) interrupt 4 using 1
- {
- // if(TI == 1&&sendendFlag == 1)
- // {
- // TI = 0;
- // SendFlag = 0;
- // sendendFlag = 0;
- // }
- if(RI == 1) //RI接受中断标志
- {
- RI = 0; //清除RI接受中断标志
- ReData = SBUF; //SUBF接受/发送缓冲器
- data12 = SBUF;
- SenData=ReData;
-
- if(data12 == '1')
- {
- wendu[0] = data12;
- wendu[1] = '0';
- wendu[2] = (max/10)+'0';
- wendu[3] = (max%10)+'0';
- }
- if(data12 == '2')
- {
- wendu[0] = data12;
- wendu[2] = (min/10)+'0';
- wendu[3] = (min%10)+'0';
- }
- if(data12 == '3')
- {
- wendu[0] = data12;
- wendu[2] = '0';
- wendu[3] = qujian+'0';
- }
- if(data12 == '4')
- {
- wendu[0] = data12;
- wendu[2] = '0';
- wendu[3] = jidianqi+'0';
- }
- if(data12 == '5')
- {
- wendu[0] = data12;
- wendu[2] = (pinlv/10)+'0';
- wendu[3] = (pinlv%10)+'0';
- }
- if(data12 == '6')
- {
- wendu[0] = data12;
- wendu[2] = (temperature/10)+'0';
- wendu[3] = (temperature%10)+'0';
- }
- if(data12 == '7')
- {
- for(j = 0;j<2;j++)
- {
- while(RI == 0);
- RI = 0;
- xiafa[j] = SBUF;
- }
- shiwei = xiafa[0] - '0';
- gewei = xiafa[1] - '0';
- wei[wei_2[0]] = shiwei;
- wei[wei_2[1]] = gewei;
- max = shiwei*10 + gewei;
- }
- if(data12 == '8')
- {
- for(j = 0;j<2;j++)
- {
- while(RI == 0);
- RI = 0;
- xiafa[j] = SBUF;
- }
- shiwei = xiafa[0] - '0';
- gewei = xiafa[1] - '0';
- wei[6] = shiwei;
- wei[7] = gewei;
- min = shiwei*10 + gewei;
- }
- SendFlag = 1;
- }
- }
- //主函数
- void main()
- {
-
- TMOD = 0x21; //设置定时器模式
- SCON = 0x50; //REN=1允许串行接受状态,串口工作模式1
- PCON|= 0x80;
- TH1 = 0xF3; //baud*2 /* reload value 19200、数据位8、停止位1。效验位无
- // //baud*2 /* 波特率4800、数据位8、停止位1。效验位无 (12M)
- TL1 = 0xF3;
- TH0 = (65536 - 10000)/256; //设置定时初值
- TL0 = (65535 - 10000)%256; //设置定时初值
- TR0 = 1;
- TR1 = 1;
- ES = 1;
- ET0 = 1;
- EA = 1;
- while(1)
- {
- P2=0xf0;
- display_1();
- if (SendFlag==1) // max485(半双工通信) RE/DE定义 RE=0为接受状态 DE=1为发送状态(参考MAX485芯片管脚)
- {
- RS485E=1; // RS5485E=0为接收状态 RS5485E=1为发送状态
- for(cnt = 0;cnt<4;cnt++)
- {
- SBUF=wendu[cnt];//SenData; //发送数据
- while(TI == 0);//{display_1();}
- TI = 0;
- display_1();
- }
- SendFlag = 0;
- //sendendFlag = 1;
- }
- else
- {
- RS485E=0; //接收状态
- }
- if((P2 & 0x10) == 0) //有按键按下
- {
- delay(1200); //消抖
- if((P2 & 0x10) == 0)
- {
- P2=0x0f;
- if((P2 & 0x04) == 0) //判断是否是 设置 按键按下
- {
-
- while((P2 & 0x04) == 0); //等待按键释放
- L1_Flag = 1;
- L1 = 1;
- key_du(); //进入参数设置函数
- }
- }
- }
- if(FallFlag == 1)
- {
- L2 = 1;
- }
- else
- {
- L2 = 0;
- }
- if(temper_flag)
- {
- temper_flag = 0;
- temperature = rd_temperature(); //读温度
- }
-
- if((temperature <= min) && temperature != 0) //区间0
- {
- wei_1[1]=0;
- qujian = 0;
- ……………………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载:
485后台.zip
(33.52 KB, 下载次数: 14)
|