前言
马上省赛了,不是很有动力二刷做过的省赛题,再刷国赛又有点费时,感觉不会考这么难。就继续刷掉了这套省赛题目了。这套很顺畅,一次做下来提交就满分了,让我心情大好。不过依然有个小问题,就是运算dac的值的时候,会出现负数,但是定义的uchar是不允许负数的,所以在负数出现之前要*1.0,把格式转成float,这样就可以继续运算了。如图。
ps:之前没再练过dac的题可以自己再去找题,最好能超快速推出对应的函数关系。
我的做法是先求斜率k,然后点斜式y-y0=k(x-x0)。且运算过程中要注意运算量是否由于要显示的原因倍放大了倍数,且计算过程中出现负数的情况要格外注意。+0.5是进行四舍五入,保持数据精度。
代码如下
#include <STC15F2K60S2.H>
#include "iic.h"
#include "onewire.h"
#define control(x,y) P0=y;P2=x;P2=0
typedef unsigned char uchar ;
typedef unsigned int uint ;
code unsigned char Seg_Code[] =
{
0xc0, //0
0xf9, //1
0xa4, //2
0xb0, //3
0x99, //4
0x92, //5
0x82, //6
0xf8, //7
0x80, //8
0x90, //9
0xff, //10
0x88, //A11
0x83, //b12
0xc6, //C13
0xa1, //d14
0x86, //E15
0x8e ,//F16
0xc1//U17
};
uchar Seg_Bit[9]={10,10,10,10,10,10,10,10,10};
uchar interface;
uchar count_key;
bit mode;
uint count_temp;
uint count_adc;
uint count_dac;
uint temp;
uchar bright;
uchar dac_data;
uchar dac_input;
uchar L[3];
void Timer2Init(void)
{
AUXR |= 0x04; //?????1T??
T2L = 0x20; //??????
T2H = 0xD1; //??????
AUXR |= 0x10; //???2????
IE2|= 0x04;
EA=1;
}
void t2int() interrupt 12 //????
{ static Seg_Com=1;
///ÖÜÆÚË¢ÐÂ
++count_key;
++count_adc;
++count_dac;
++count_temp;
///ÊýÂë¹Ü
control(0xc0,0x00);
if((interface==0&&mode==0&&Seg_Com==7) ||(interface==1&& Seg_Com==7))
{
control(0xe0,Seg_Code[Seg_Bit[Seg_Com]]&0x7f);
}
else
{control(0xe0,Seg_Code[Seg_Bit[Seg_Com]]);
}
control(0xc0,1<<(Seg_Com-1));
if(++Seg_Com>8) Seg_Com=1;
///led/
control(0x80,~(L[1]|L[2]<<1));
}
void System_Init()
{
control(0x80,0xff);
control(0xa0,0x00);
while(++count_temp<100)
{
temp=Read_Temp()*10+0.5;
}
while(++count_adc<5)
{
bright=Read_ADC();
}
Timer2Init();
}
void Data_Task()
{
if(T2H<0xd9)
{
if(count_adc>150)
{
count_adc=0;
bright=Read_ADC();
}
else if(count_dac>150)
{count_dac=0;
Write_DAC(dac_input);
}
}
if(count_temp>750)
{
count_temp=0;
temp=Read_Temp()*10+0.5;
}
}
void Logic_Task()
{led/
L[1]=(mode==0)?(1):(0);
L[2]=(mode==1)?(1):(0);
///
if(mode==0)
{
if(temp<=100)
{dac_data=10;
}
else if(temp>=400)
{dac_data=50;
}
else
{
dac_data=(0.1333*(temp*0.1-40)+5)*10+0.5;//ÕâÀïÊÇ10±¶ÁË
}
}
if(mode==1)
{
if(bright<=10)
{dac_data=10;
}
else if(bright>=240)
{dac_data=50;
}
else
{
dac_data=(0.0174*(bright*1.0-240)+5)*10+0.5;//ÕâÀïÊÇ10±¶ÁË
}
}
dac_input=dac_data*5.1+0.5;
}
void Display_Task()
{
if(interface==0&&mode==0)//ģʽ1
{
Seg_Bit[1]=1;
Seg_Bit[2]=10;
Seg_Bit[3]=10;
Seg_Bit[4]=10;
Seg_Bit[5]=10;
Seg_Bit[6]=temp/100;
Seg_Bit[7]=temp/10%10;
Seg_Bit[8]=temp%10;
}
if(interface==0&&mode==1)//ģʽ2
{
Seg_Bit[1]=2;
Seg_Bit[2]=10;
Seg_Bit[3]=10;
Seg_Bit[4]=10;
Seg_Bit[5]=10;
Seg_Bit[6]=(bright>99)?(bright/100):(10);
Seg_Bit[7]=(bright>9)?(bright/10%10):(10);
Seg_Bit[8]=bright%10;
}
if(interface==1)//Êä³ö½çÃæ
{
Seg_Bit[1]=17;
Seg_Bit[2]=10;
Seg_Bit[3]=10;
Seg_Bit[4]=10;
Seg_Bit[5]=10;
Seg_Bit[6]=10;
Seg_Bit[7]=dac_data/10;
Seg_Bit[8]=dac_data%10;
}
}
uchar Read_Key()
{ static uchar count_press=0;
static uchar flag_press=0;
uchar value;
uchar x=0,y=0;
P3=0x0f;P4=0x00;
if(P30==0) x=3;
if(P31==0) x=2;
if(P32==0) x=1;
if(P33==0) x=0;
P3=0xf0;P4=0xff;
if(P35==0) y=3;
if(P42==0) y=2;
if(P44==0) y=1;
if(y)
{
if((++count_press>=8)&&(flag_press==0))
{
count_press=0;
flag_press=1;
value=x+y*4;
}
}
else
{
count_press=0;
flag_press=0;
}
return value;
}
void Key_Task()
{uchar key_value=0;
if(count_key>5)
{count_key=0;
key_value=Read_Key();
}
if(key_value==5)
{interface=!interface;
}
if(key_value==4)
{
if(interface==0)
{mode=!mode;
}
}
}
int main()
{
System_Init();
while(1)
{
Data_Task();
Logic_Task();
Display_Task();
Key_Task();
}
}
底层驱动常规写法。