2019蓝桥杯单片机设计与开发省赛(部分代码)
首先看一下硬性要求,貌似有些条件坑了一部分同学
和我一起参赛的小哥哥,做完题目就直接嚣张的走出了考场,等我出来,听到他跟我说的第一句话就是省一没毛病。当他听到要求工程文件要以考号命名时,心凉了半截。回学校的路上锤头丧气的,过还好等成绩出来时我们俩还是拿了省一。
*
感觉这次题目从逻辑上说还是比较简单的吧,暂且不提555和A/D。做好了估计拿奖还是没问题吧。就连身边两个陪考的妹子也拿了省二
因为当时写出来D/A的和读取A/D有冲突,我就直接把D/A给注释掉了。不过值得庆幸的是还没有太差,虽然平时没练过555,因为之前写过一个用555测量电阻的程序,所以当时脑子第一反应就是用计数器。
其实单片机的定时器本身就来自计数器,当计数器计单片机的机械周期时就变成了定时器。频率来自555,开发板上的SIGNAL和P34跳帽连接(请原谅沙漠之雕的我找老师要杜邦线)。
555真是一个神奇器件,差点爱上他
废话少说直接上码
相信你们都能看得懂
**
计数器定时器的配置
**
void Timer1Init(void)
{
AUXR |= 0x40; //1T模式
TMOD = 0x04; //定时器0计数 定时器1定时
TL0 = 0;
TH0 = 0;
TR0 = 1;
TL1 = 0x20; //1ms
TH1 = 0xD1;
TF1 = 0;
TR1 = 1;
ET1 = 1;
EA = 1;
}
频率显示函数
判断?条件1:条件2(悄悄告诉你)
void display_f(void)
{
smg_display[0]=~smg_du[11];
smg_display[1]=~smg_du[10];
(sum_f>=100000)?(smg_display[2]=~smg_du[sum_f/100000%10]):(smg_display[2]=~smg_du[10]);
(sum_f>=10000)?(smg_display[3]=~smg_du[sum_f/10000%10]):(smg_display[3]=~smg_du[10]);
(sum_f>=1000)?(smg_display[4]=~smg_du[sum_f/1000%10]):(smg_display[4]=~smg_du[10]);
smg_display[5]=~smg_du[sum_f/100%10];
smg_display[6]=~smg_du[sum_f/10%10];
smg_display[7]=~smg_du[sum_f%10];
}
频率读取和转化放在中断里了
不知道你是怎么想的
if(f_count==1000) //1S
{
TR0=0;
f_count=0;
sum_f=0;
sum_f=TH0;
sum_f<<=8;
sum_f|=TL0; // sum_f就是频率了呀
TH0=0;
TL0=0;
TR0=1;
}
对了,不知道你晓得三行按键扫描程序不
反正我早已经爱上她了
她就像是一个妹子,不仅身材好,姿势还---------(不好意思跑题了)
unsigned char Trg,Cont;
void key_scan(void) //(10ms换一次姿势)你懂的
{
unsigned char ReadData=P3^0x0f;
Trg=ReadData&(ReadData^Cont);
Cont=ReadData;
}
剩下就是驱动了
这次连延时都不用改了
把读取A/D关闭中断的代码写到驱动里是不是很骚啊
unsigned char read_adc(unsigned char add)
{
unsigned char temp;
EA=0;
IIC_Start();
IIC_SendByte(0x90);
IIC_WaitAck();
IIC_SendByte(add);
IIC_WaitAck();
IIC_Start();
IIC_SendByte(0x91);
IIC_WaitAck();
temp=IIC_RecByte();
IIC_SendAck(1);
IIC_Stop();
EA=1;
return temp;
}
void write_adc(unsigned char add)
{
EA=0;
IIC_Start();
IIC_SendByte(0x90);
IIC_WaitAck();
IIC_SendByte(0x40);
IIC_WaitAck();
IIC_SendByte(add);
IIC_SendAck(1);
IIC_Stop();
EA=1;
}