也是刚刚把这个题目做完,让我们一起来看看2021年的题目吧,有什么不对的地方,还希望大家指正。

题目

首先依旧还是三大模块(数码管、LED、按键)
,还有DS18B20,DA输出。写了有一些省赛题了,每次考的都是这些东西,只要平常每个模块都有练习过,应该是不难的。我发现从2020年开始,虽然还是用四个按键,但是变成了矩阵按键,之前都是独立按键。

1 数码管显示

数码管有温度显示,参数设置和DA输出三个界面,通过s4来切换。

2 LED

当在模式1状态时L1亮,数码管处于温度显示界面时L2亮,参数设置界面时L3亮,DA输出界面时L4亮。

3 按键模块

使用的是矩阵键盘,s4是三个界面的切换,s8,s9是温度参数加减1,这里有个小坑就是设定的温度参数只有在退出参数设置界面时才生效,这就要定义两个温度参数的变量,一个是用来在温度参数加减的,在退出温度参数界面时赋值给另一个变量,另一个是用来和实时温度比较大小的。s5有两个模式,模式一
实时温度小于温度参数DA输出0v,否则输出5v。模式二 按照图所给的关系输出电压。

4 DS18B20

就是改写底层驱动代码部分(onewire),然后放在定时器中,每隔一段时间读取一次。

5 DAC

就是改写底层驱动代码部分(IIC)。

onewire.c
#include"onewire.h" sbit DQ = P1^4; void Delay_OneWire(unsigned int t) {
t*=12; while(t--); } 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; } unsigned
int Get_Temp() { unsigned int result; unsigned char high,low; init_ds18b20();
Write_DS18B20(0xcc); Write_DS18B20(0x44); init_ds18b20(); Write_DS18B20(0xcc);
Write_DS18B20(0xbe); low=Read_DS18B20(); high=Read_DS18B20();
result=(high<<8)|low; result*=6.25; return result; }
onewire.h
#ifndef _ONEWIRE_H_ #define _ONEWIRE_H_ #include<stc15f2k60s2.h> void
Delay_OneWire(unsigned int t); void Write_DS18B20(unsigned char dat); unsigned
char Read_DS18B20(void); bit init_ds18b20(void); unsigned int Get_Temp(); #endif
IIC.c
#include"IIC.h" #define DELAY_TIME 5 #define SlaveAddrW 0xA0 #define
SlaveAddrR 0xA1 sbit SDA = P2^1; sbit SCL = P2^0; void IIC_Delay(unsigned char
i) { do{_nop_();} while(i--); } void IIC_Start(void) { SDA = 1; SCL = 1;
IIC_Delay(DELAY_TIME); SDA = 0; IIC_Delay(DELAY_TIME); SCL = 0; } void
IIC_Stop(void) { SDA = 0; SCL = 1; IIC_Delay(DELAY_TIME); SDA = 1;
IIC_Delay(DELAY_TIME); } bit IIC_WaitAck(void) { bit ackbit; SCL = 1;
IIC_Delay(DELAY_TIME); ackbit = SDA; SCL = 0; IIC_Delay(DELAY_TIME); return
ackbit; } void IIC_SendByte(unsigned char byt) { unsigned char i; for(i=0; i<8;
i++) { SCL = 0; IIC_Delay(DELAY_TIME); if(byt & 0x80) SDA = 1; else SDA = 0;
IIC_Delay(DELAY_TIME); SCL = 1; byt <<= 1; IIC_Delay(DELAY_TIME); } SCL = 0; }
void DA_out(unsigned char date) { IIC_Start(); IIC_SendByte(0x90);
IIC_WaitAck(); IIC_SendByte(0x40); IIC_WaitAck(); IIC_SendByte(date);
IIC_WaitAck(); IIC_Stop(); }
IIC.h
#ifndef _IIC_H_ #define _IIC_H_ #include<stc15f2k60s2.h> #include<intrins.h>
void IIC_Delay(unsigned char i); void IIC_Start(void); void IIC_Stop(void); bit
IIC_WaitAck(void); void IIC_SendByte(unsigned char byt); void DA_out(unsigned
char date); #endif
init.c
#include"init.h" #define u8 unsigned char #define u16 unsigned int #define
state_0 0 #define state_1 1 #define state_2 2 #define kbd_io P3 u8
tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf,0xff,0xc6,0x8c,0x88};
u8 seg[]={11,11,11,11,11,11,11,11,11,11,11}; extern u8 mode,value; static u8
segadder=0; void close() //关闭无关外设 { P2=(P2&0x1f)|0x80;P0=0xff;P2&=0x1f;
P2=(P2&0x1f)|0xa0;P04=0;P06=0;P2&=0x1f; P2=(P2&0x1f)|0xc0;P0=0x00;P2&=0x1f;
P2=(P2&0x1f)|0xe0;P0=0xff;P2&=0x1f; } void display() //数码管显示函数 { static u8
kbd_state=0,key_num=0; u8 kbd_press; u8 row; switch(kbd_state) { case state_0:
kbd_io=0x0f; P42=0; P44=0; kbd_press =kbd_io; if(kbd_press != 0x0f) kbd_state =
state_1; break; case state_1: kbd_press =kbd_io; if(kbd_press != 0x0f) {
if((kbd_io&0x08)==0) row=4; if((kbd_io&0x04)==0) row=5; if((kbd_io&0x02)==0)
row=6; if((kbd_io&0x01)==0) row=7; kbd_io=0xf0; P42=1;P44=1; if(P44==0)
key_num=row; if(P42==0) key_num=row+4; if((kbd_io&0x20)==0) key_num=row+8;
if((kbd_io&0x10)==0) key_num=row+12; kbd_state = state_2; } else kbd_state =
state_0; break; case state_2: kbd_io=0x0f; P42=0; P44=0; kbd_press =kbd_io;
if(kbd_press == 0x0f) kbd_state = state_0; break; } value=key_num; key_num=0;
return value; } void Timer0Init(void) { AUXR |= 0x80; TMOD &= 0xF0; TL0 = 0x20;
TH0 = 0xD1; TF0 = 0; TR0 = 1; ET0 = 1; EA = 1; }
init.h
#ifndef _INIT_H_ #define _INIT_H_ #include<stc15f2k60s2.h> void close(); void
display(); unsigned char read_key(); void Timer0Init(void); #endif
jm.c
#include"jm.h" #include"IIC.h" #define u8 unsigned char #define u16 unsigned
int extern u8 mode,seg[]; // extern表示此变量是在别处定义的,要在此处引用 extern u16
TT,TF,temp,RB; extern bit MS; void jm4() { if(mode==0) //温度显示界面 { seg[0]=12;
seg[1]=11; seg[2]=11; seg[3]=11; seg[4]=temp/1000; seg[5]=temp/100%10;
seg[6]=temp/10%10; seg[7]=temp%10; } else if(mode==1) //参数设置界面 { seg[0]=13;
seg[1]=11; seg[2]=11; seg[3]=11; seg[4]=11; seg[5]=11; seg[6]=TF/1000;
seg[7]=TF/100%10; } else if(mode==2) //DA输出界面 { seg[0]=14; seg[1]=11;
seg[2]=11; seg[3]=11; seg[4]=11; seg[5]=RB/100; seg[6]=RB/10%10; seg[7]=RB%10;
} } void jm5() //模式切换函数 { if(MS==0) { if(temp<TF) { DA_out(0); RB=0; } else {
DA_out(255); RB=500; } } else { if(temp<2000) { DA_out(51); RB=100; } else
if(temp>=2000&&temp<4000) { DA_out((0.15*temp-200)*0.51); RB=0.15*temp-200; }
else { DA_out(204); RB=400; } } } void jm8() { if(mode==1)TT-=100; } void jm9()
{ if(mode==1)TT+=100; } void LED() //LED显示函数 { if(mode==0){ if(MS==0){
P2=(P2&0x1f)|0x80;P0=0xfc;P2&=0x1f; } else{ P2=(P2&0x1f)|0x80;P0=0xfd;P2&=0x1f;
} } else if(mode==1){ if(MS==0){ P2=(P2&0x1f)|0x80;P0=0xfa;P2&=0x1f; } else{
P2=(P2&0x1f)|0x80;P0=0xfb;P2&=0x1f; } } else if(mode==2){ if(MS==0){
P2=(P2&0x1f)|0x80;P0=0xf6;P2&=0x1f; } else{ P2=(P2&0x1f)|0x80;P0=0xf7;P2&=0x1f;
} } }
jm.h
#ifndef _JM_H_ #define _JM_H_ #include<stc15f2k60s2.h> void jm4(); void jm5();
void jm8(); void jm9(); void LED(); #endif
main.c
#include"jm.h" #include"onewire.h" #include"IIC.h" #include"init.h" #define u8
unsigned char #define u16 unsigned int u8 value=0,num=0,mode=0; u8
temp_count=0; u16 temp,TT=2500,TF=2500,RB=0; bit temp_flag=0,MS=0; void main()
{ close(); Timer0Init(); while(1) { if(temp_flag==1) //每200ms读取一次温度的值 {
temp_flag=0; temp=Get_Temp(); } num=read_key(); switch(num) { case 4:
if(++mode==3)mode=0; break; case 5: MS^=1; break; case 8: jm8(); TF=TT; break;
case 9: jm9(); TF=TT; break; } jm4(); jm5(); LED(); } } void Timer0() interrupt
1 { display(); if(++temp_count==200) { temp_count=0; temp_flag=1; } }
最后再说一次,每个模块都是比较简单的,最重要的编程逻辑。

技术
下载桌面版
GitHub
Gitee
SourceForge
百度网盘(提取码:draw)
云服务器优惠
华为云优惠券
腾讯云优惠券
阿里云优惠券
Vultr优惠券
站点信息
问题反馈
邮箱:[email protected]
吐槽一下
QQ群:766591547
关注微信