一.题目要求
要点的一些个人见解:
1.正负值的判断:
数据部分仍然采用无符号整型,但是多设置一个标志位,来表示正负,在正负时候采用不同的加减逻辑,重点是从负数加到0和从0减到负数这两个关键位置符号的转变,下面是一个例子
if(SMG_Mode==3)
{
if(factory_Mode==1)
{
if(sign==0)
{
if(jiaozhun<90)
{
jiaozhun+=5;
}
}
if(sign==1)
{
if(jiaozhun==5)
{
sign=0;
jiaozhun=0;
}
if(jiaozhun>5)
{
jiaozhun-=5;
}
}
}
2.双按键长按,官方给的例程是两个按键同时按下对应一个键值,我这里采用另外一种思路,就是按下S8后先进入循环等待S9按下,若没有按下,则松开S8的时候执行相应的操作,检测按下后置相应的标志位,开启计时器计时,若时间条件满足,执行复位操作,否则执行短按的操作,为了规避S8,S9按下的先后顺序问题,S9也要有类似的步骤
//在按键扫描开头先将reset_times清零
if(R1==0)
{
Delay_SMG(500);
if(R1==0)
{
while(R1==0)
{
Display_Dynamic();
DS18B20_Read();
if(R2==0)
{
Delay_SMG(500);
if(R2==0)
{
reset_Flag=1;
while(R2==0)
{
Display_Dynamic();
DS18B20_Read();
}
reset_Flag=0;
if(reset_times>2000)
{
Dis_param=40;
T_param=30;
jiaozhun=0;
speed=350;
DAC_low=10;
sign=0;
}
}
}
}
if(reset_times<2000)
{
//其他操作
}
二. 代码实现:
main.c
#include <STC15F2K60S2.H>
#include "intrins.h"
#include "onewire.h"
#include "iic.h"
sbit C1=P4^4;
sbit C2=P4^2;
sbit R1=P3^2;
sbit R2=P3^3;
sbit TX=P1^0;
code unsigned char SMG_Nodot[] =
{0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};
code unsigned char SMG_Dot[] =
{0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};
unsigned char SMG_Mode=1;
unsigned int T_smg;
float T_Value;
unsigned char Distance;
unsigned char Dis_temp;
unsigned char Dis_Mode=1;
unsigned char param_Mode=1;
unsigned char Dis_param=40;
unsigned char T_param=30;
unsigned char factory_Mode=1;
bit sign;
unsigned char jiaozhun;
unsigned int speed=340;
unsigned char DAC_low=10;
unsigned char DAC_Value;
bit PCA_Flag;
unsigned int times;
unsigned int PCA_times;
bit reset_Flag;
unsigned char timer_times;
unsigned int reset_times;
bit Key_Flag;
unsigned int Key_times;
unsigned char LED_Mode=0xff;
bit LED_Flag;
bit Flash_Flag;
unsigned char LED_times;
void Delay_SMG(unsigned int t)
{
while(t--);
}
void Delay12us() //@12.000MHz
{
unsigned char i;
_nop_();
_nop_();
i = 33;
while (--i);
}
void SendWave()
{
unsigned char i;
for(i=0;i<8;i++)
{
TX=0;
Delay12us();
TX=1;
Delay12us();
}
}
void SelectHC573(unsigned char channel,unsigned char dat)
{
P0=dat;
switch(channel)
{
case 4:
P2=(P2&0x1f)|0x80;
break;
case 5:
P2=(P2&0x1f)|0xa0;
break;
case 6:
P2=(P2&0x1f)|0xc0;
break;
case 7:
P2=(P2&0x1f)|0xe0;
break;
case 0:
P2=(P2&0x1f)|0x00;
break;
}
P2=(P2&0x1f)|0x00;
}
void SMG_Display(unsigned char pos,unsigned char dat)
{
SelectHC573(6,0x01<<(pos-1));
SelectHC573(7,dat);
Delay_SMG(500);
SelectHC573(6,0x01<<(pos-1));
SelectHC573(7,0xff);
}
void Display_Dynamic()
{
if(SMG_Mode==1)
{
SMG_Display(1,SMG_Nodot[T_smg/100]);
SMG_Display(2,SMG_Dot[T_smg%100/10]);
SMG_Display(3,SMG_Nodot[T_smg%10]);
SMG_Display(4,0xbf);
if(Dis_Mode==1)
{
if(Distance>999)
{
SMG_Display(5,SMG_Nodot[Distance/1000]);
}
if(Distance>99)
{
SMG_Display(6,SMG_Nodot[Distance%1000/100]);
}
if(Distance>9)
{
SMG_Display(7,SMG_Nodot[Distance%100/10]);
}
SMG_Display(8,SMG_Nodot[Distance%10]);
}
if(Dis_Mode==2)
{
if(Distance>999)
{
SMG_Display(5,SMG_Nodot[Distance/1000]);
}
SMG_Display(6,SMG_Dot[Distance%1000/100]);
SMG_Display(7,SMG_Nodot[Distance%100/10]);
SMG_Display(8,SMG_Nodot[Distance%10]);
}
}
if(SMG_Mode==2)
{
SMG_Display(1,0x8c);
SMG_Display(2,SMG_Nodot[param_Mode]);
if(param_Mode==1)
{
SMG_Display(7,SMG_Nodot[Dis_param/10]);
SMG_Display(8,SMG_Nodot[Dis_param%10]);
}
if(param_Mode==2)
{
SMG_Display(7,SMG_Nodot[T_param/10]);
SMG_Display(8,SMG_Nodot[T_param%10]);
}
}
if(SMG_Mode==3)
{
SMG_Display(1,SMG_Nodot[15]);
SMG_Display(2,SMG_Nodot[factory_Mode]);
if(factory_Mode==1)
{
if(sign==1)
{
if(jiaozhun>9)
{
SMG_Display(6,0xbf);
}
if(jiaozhun<9)
{
SMG_Display(7,0xbf);
}
}
if(jiaozhun>9)
{
SMG_Display(7,SMG_Nodot[jiaozhun/10]);
}
SMG_Display(8,SMG_Nodot[jiaozhun%10]);
}
if(factory_Mode==2)
{
if(speed>999)
{
SMG_Display(5,SMG_Nodot[speed/1000]);
}
if(speed>99)
{
SMG_Display(6,SMG_Nodot[speed%1000/100]);
}
if(speed>9)
{
SMG_Display(7,SMG_Nodot[speed%100/10]);
}
SMG_Display(8,SMG_Nodot[speed%10]);
}
if(factory_Mode==3)
{
SMG_Display(7,SMG_Dot[DAC_low/10]);
SMG_Display(8,SMG_Nodot[DAC_low%10]);
}
}
}
void PCA_Init()
{
CMOD=0x01;
CCAPM0=0x11;
EA=1;
}
void PCA_Service() interrupt 7
{
CR=0;
if(CF==1)
{
CF=0;
PCA_Flag=0;
}
if(CCF0==1)
{
CCF0=0;
PCA_Flag=1;
times=CCAP0H<<8|CCAP0L;
}
}
void Measure_Distance()
{
CH=CL=0;
SendWave();
CR=1;
if(PCA_Flag==0)
{
Distance=255;
}
if(PCA_Flag==1)
{
if(sign==0)
{
Distance=times*(speed/2*0.0001)+jiaozhun;
}
if(sign==1)
{
Distance=times*(speed/2*0.0001)-jiaozhun;
}
}
}
void Timer0Init(void)
AUXR &= 0x7F;
TMOD &= 0xF0;
TL0 = 0x18;
TH0 = 0xFC;
TF0 = 0;
TR0 = 1;
ET0=1;
}
void Timer0_Service() interrupt 1
{
PCA_times++;
if(PCA_times==125)
{
Measure_Distance();
PCA_times=0;
}
if(reset_Flag==1)
{
reset_times++;
}
if(Key_Flag==1)
{
Key_times++;
if(Key_times==6000)
{
Key_times=0;
Key_Flag=0;
Dis_temp=Distance;
}
}
if(LED_Flag==1)
{
LED_times++;
if(LED_times==100)
{
LED_times=0;
Flash_Flag=~Flash_Flag;
if(Flash_Flag==1)
{
LED_Mode&=0xfe;
SelectHC573(4,LED_Mode);
}
if(Flash_Flag==0)
{
LED_Mode|=0x01;
SelectHC573(4,LED_Mode);
}
}
}
}
void DS18B20_Read()
{
unsigned int temp;
unsigned char LSB,MSB;
init_ds18b20();
Display_Dynamic();
Write_DS18B20(0xcc);
Write_DS18B20(0x44);
Display_Dynamic();
init_ds18b20();
Display_Dynamic();
Write_DS18B20(0xcc);
Write_DS18B20(0xbe);
LSB=Read_DS18B20();
MSB=Read_DS18B20();
temp=MSB<<8|LSB;
Display_Dynamic();
T_Value=temp*0.0625;
T_smg=T_Value*10;
}
void DAC_Caculate()
{
float k;
k=(255-5.1*DAC_low)/80.0;
if(Dis_temp<10)
{
DAC_Value=51;
}
if(Dis_temp>90)
{
DAC_Value=255;
}
if(Dis_temp>10&&Dis_temp<90)
{
DAC_Value=(Dis_temp-10)*k+DAC_low*5.1;
}
}
void DAC_Write()
{
DAC_Caculate();
I2CStart();
I2CSendByte(0x90);
I2CWaitAck();
I2CSendByte(0x43);
I2CWaitAck();
I2CSendByte(DAC_Value);
I2CWaitAck();
I2CStop();
}
void Scan_Key()
{
reset_times=0;
C1=0;C2=1;
R1=R2=1;
if(R1==0)
{
Delay_SMG(500);
if(R1==0)
{
if(SMG_Mode==1)
{
switch(Dis_Mode)
{
case 1:
Dis_Mode=2;
break;
case 2:
Dis_Mode=1;
break;
}
}
if(SMG_Mode==2)
{
switch(param_Mode)
{
case 1:
param_Mode=2;
break;
case 2:
param_Mode=1;
break;
}
}
if(SMG_Mode==3)
{
switch(factory_Mode)
{
case 1:
factory_Mode=2;
break;
case 2:
factory_Mode=3;
break;
case 3:
factory_Mode=1;
break;
}
}
}
while(R1==0)
{
Display_Dynamic();
DS18B20_Read();
}
}
if(R2==0)
{
Delay_SMG(500);
if(R2==0)
{
switch(SMG_Mode)
{
case 1:
SMG_Mode=2;
Dis_Mode=1;
break;
case 2:
SMG_Mode=3;
param_Mode=1;
break;
case 3:
SMG_Mode=1;
factory_Mode=1;
break;
}
}
while(R2==0)
{
Display_Dynamic();
DS18B20_Read();
}
}
C1=1;C2=0;
R1=R2=1;
if(R1==0)
{
Delay_SMG(500);
if(R1==0)
{
while(R1==0)
{
Display_Dynamic();
DS18B20_Read();
if(R2==0)
{
Delay_SMG(500);
if(R2==0)
{
reset_Flag=1;
while(R2==0)
{
Display_Dynamic();
DS18B20_Read();
}
reset_Flag=0;
if(reset_times>2000)
{
Dis_param=40;
T_param=30;
jiaozhun=0;
speed=350;
DAC_low=10;
sign=0;
}
}
}
}
if(reset_times<2000)
{
if(SMG_Mode==1)
{
DAC_Write();
}
if(SMG_Mode==2)
{
if(param_Mode==1)
{
if(Dis_param>10)
{
Dis_param-=10;
}
}
if(param_Mode==2)
{
if(T_param>0)
{
T_param--;
}
}
}
if(SMG_Mode==3)
{
if(factory_Mode==1)
{
if(sign==0)
{
if(jiaozhun==0)
{
sign=1;
}
if(jiaozhun>0)
{
jiaozhun-=5;
}
}
if(sign==1)
{
if(jiaozhun<90)
{
jiaozhun+=5;
}
}
}
if(factory_Mode==2)
{
if(speed>10)
{
speed-=10;
}
}
if(factory_Mode==3)
{
if(DAC_low>1)
{
DAC_low--;
}
}
}
}
}
while(R1==0)
{
Display_Dynamic();
DS18B20_Read();
}
}
if(R2==0)
{
Delay_SMG(500);
if(R2==0)
{
while(R2==0)
{
Display_Dynamic();
DS18B20_Read();
if(R1==0)
{
Delay_SMG(500);
if(R1==0)
{
reset_Flag=1;
while(R1==0)
{
Display_Dynamic();
DS18B20_Read();
}
reset_Flag=0;
if(reset_times>2000)
{
Dis_param=40;
T_param=30;
jiaozhun=0;
speed=340;
DAC_low=10;
sign=0;
}
}
}
}
if(reset_times<2000)
{
if(SMG_Mode==1)
{
Key_Flag=1;
}
if(SMG_Mode==2)
{
if(param_Mode==1)
{
if(Dis_param<90)
{
Dis_param+=10;
}
}
if(param_Mode==2)
{
if(T_param<80)
{
T_param++;
}
}
}
if(SMG_Mode==3)
{
if(factory_Mode==1)
{
if(sign==0)
{
if(jiaozhun<90)
{
jiaozhun+=5;
}
}
if(sign==1)
{
if(jiaozhun==5)
{
sign=0;
jiaozhun=0;
}
if(jiaozhun>5)
{
jiaozhun-=5;
}
}
}
if(factory_Mode==2)
{
if(speed<9990)
{
speed+=10;
}
}
if(factory_Mode==3)
{
if(DAC_low<20)
{
DAC_low++;
}
}
}
}
}
while(R2==0)
{
Display_Dynamic();
DS18B20_Read();
}
}
}
void LED_Control()
{
if(SMG_Mode==2)
{
LED_Mode&=0x7f;
SelectHC573(4,LED_Mode);
}
if(SMG_Mode!=2)
{
LED_Mode|=0x80;
SelectHC573(4,LED_Mode);
}
if(SMG_Mode==3)
{
LED_Flag=1;
}
if(SMG_Mode!=3)
{
LED_Flag=0;
LED_Mode|=0x01;
}
if(SMG_Mode==1)
{
SelectHC573(4,~Distance);
}
}
void jdq_Control()
{
if((Distance>Dis_param-5&&Distance<Dis_param+5)&&(T_Value<T_param))
{
SelectHC573(5,0x10);
}
else{
SelectHC573(5,0x00);
}
}
void Sys_Init()
{
SelectHC573(4,0xff);
SelectHC573(5,0x00);
PCA_Init();
Timer0Init();
}
void main()
{
Sys_Init();
while(1)
{
Display_Dynamic();
if(Key_Flag==0)
{
Scan_Key();
}
DS18B20_Read();
LED_Control();
jdq_Control();
}
}
iic.c
/* # I2C代码片段说明
1. 本文件夹中提供的驱动代码供参赛选手完成程序设计参考。
2. 参赛选手可以自行编写相关代码或以该代码为基础,根据所选单片机类型、运行速度和试题
中对单片机时钟频率的要求,进行代码调试和修改。
*/
#include <STC15F2K60S2.H>
#include "intrins.h"
#define DELAY_TIME 10
sbit scl=P2^0;
sbit sda=P2^1;
//
static void I2C_Delay(unsigned char n)
{
do
{
_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_();
}
while(n--);
}
//
void I2CStart(void)
{
sda = 1;
scl = 1;
I2C_Delay(DELAY_TIME);
sda = 0;
I2C_Delay(DELAY_TIME);
scl = 0;
}
//
void I2CStop(void)
{
sda = 0;
scl = 1;
I2C_Delay(DELAY_TIME);
sda = 1;
I2C_Delay(DELAY_TIME);
}
//
void I2CSendByte(unsigned char byt)
{
unsigned char i;
for(i=0; i<8; i++){
scl = 0;
I2C_Delay(DELAY_TIME);
if(byt & 0x80){
sda = 1;
}
else{
sda = 0;
}
I2C_Delay(DELAY_TIME);
scl = 1;
byt <<= 1;
I2C_Delay(DELAY_TIME);
}
scl = 0;
}
//
unsigned char I2CReceiveByte(void)
{
unsigned char da;
unsigned char i;
for(i=0;i<8;i++){
scl = 1;
I2C_Delay(DELAY_TIME);
da <<= 1;
if(sda)
da |= 0x01;
scl = 0;
I2C_Delay(DELAY_TIME);
}
return da;
}
//
unsigned char I2CWaitAck(void)
{
unsigned char ackbit;
scl = 1;
I2C_Delay(DELAY_TIME);
ackbit = sda;
scl = 0;
I2C_Delay(DELAY_TIME);
return ackbit;
}
//
void I2CSendAck(unsigned char ackbit)
{
scl = 0;
sda = ackbit;
I2C_Delay(DELAY_TIME);
scl = 1;
I2C_Delay(DELAY_TIME);
scl = 0;
sda = 1;
I2C_Delay(DELAY_TIME);
}
onewire.c
/* # 单总线代码片段说明
1. 本文件夹中提供的驱动代码供参赛选手完成程序设计参考。
2. 参赛选手可以自行编写相关代码或以该代码为基础,根据所选单片机类型、运行速度和试题
中对单片机时钟频率的要求,进行代码调试和修改。
*/
#include <STC15F2K60S2.H>
sbit DQ=P1^4;
//
void Delay_OneWire(unsigned int t)
{
unsigned char i;
while(t--){
for(i=0;i<12;i++);
}
}
//
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);
}
//
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;
}
//
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;
}