第十三届蓝桥杯赛前的一点总结
比赛最主要的实现功能,需要关注各个部分之间的逻辑!
赛前的一点总结
- LED
- 数码管
- 独立按键
- 正常处理按键
- 长按键功能--规定秒数
- 长按键功能--不规定秒数
- 矩阵按键
- 4 * 4 矩阵按键
- 2 * 2 矩阵按键
- 斜按键操作
- NE555频率测量
- ADC
- DAC
- eeprom
- DS18B20
- DS1302
- 数据处理
- 头文件修改
- 底层代码修改
LED
整个工程中LED和数码管,按键部分其实是最主要的部分,往年省赛涉及部分也是相对较多的。
- 点亮L1
sbit L1 = P0^0;
void led_1()
{P2 = (P2 & 0x1f) | 0x80;L1 = 0;
}
- L1隔0.1s闪烁
#define uchar unsigned charsbit L1 = P0^0
bit flag_L1;
void Timer0Init(void); //50毫秒@12.000MHzvoid led_1()
{if (flag_L1){P2 = (P2 & 0x1f) | 0x80;L1 = 0;}else {P2 = (P2 & 0x1f) | 0x80;L1 = 1;}}void timer0() interrupt 1
{static uchar i1;if (++i1 == 2){i1 = 0;flag_L1 = !flag_L1;}
}
void Timer0Init(void) //50毫秒@12.000MHz
{AUXR &= 0x7F; //定时器时钟12T模式TMOD &= 0xF0; //设置定时器模式TL0 = 0xB0; //设置定时初值TH0 = 0x3C; //设置定时初值TF0 = 0; //清除TF0标志TR0 = 1; //定时器0开始计时ET0 = 1;EA = 1;
}
数码管
- 注意消隐和小数点处理
#define uchar unsigned char
uchar tab[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff }
//0 ~ 9 数码管熄灭
void Delay1ms(); //1ms@12.000MHz,延时1ms用于给足数码管足够显示时间
void dsp_smg_bit1(uchar pos, val, sta)
{P2 = (P2 & 0x1f) | 0x80;P0 = 1 << (pos - 1);P2 = (P2 & 0x1f) | 0x80;if (sta)//小数点P0 = tab[val] & 0x7f;elseP0 = tab[val];Delay1ms();//给足显示时间P0 = 0xff;//消隐P2 &= 0x1f;
}
独立按键
- 先调到BTN模式
正常处理按键
sbit S7 = P3^0;
sbit S6 = P3^1;
sbit S5 = P3^2;
sbit S4 = P3^3;void key_handle()
{ if (!S7){delay_k(15);//灵敏度更高就消抖时间短一些if (!S7){whlie(!S7)display();ps:这部分处理按键}}//跟S7实现一样if (!S6)....if (!S5)....if (!S4)....
}
长按键功能–规定秒数
- S7长按时间超过1s判断为长按键,否则为短按
sbit S7 = P3^0;
sbit S6 = P3^1;
sbit S5 = P3^2;
sbit S4 = P3^3;
#define uint unsigned int
bit pre_flag;//长按键标志,0为判断时间结束,1为判断开始
uint pre_cnt;//计算按下去多久
//这里利用定时器 定时1ms进入中断(ps:当然你也可以定时其他的时间)
void Timer0Init(void) //1毫秒@12.000MHz
{...
}
//中断服务函数
void timer0() interrupt 1
{if (pre_flag)//开始判断{pre_cnt++;}
}
void key_handle()
{ if (!S7){delay_k(15);//灵敏度更高就消抖时间短一些if (!S7){pre_flag = 1;whlie(!S7)display();pre_flag = 0;if (pre_cnt > 1000)//大于1s...长按键操作else ...短按键操作//还有一点重要的是,清零!pre_cnt = 0;}}//跟S7实现一样if (!S6)....if (!S5)....if (!S4)....
}
长按键功能–不规定秒数
if (!S7){delay_k(15);//灵敏度更高就消抖时间短一些if (!S7){if (1 == jm){...界面1的操作}if (2 == jm)//界面2操作长按为显示其他内容,短按或者按完不按处于其他界面{while(!S7)//长按为显示其他内容dsp_other();}whlie(!S7)//短按或者按完不按处于其他界面display();}}
矩阵按键
- 模式选择KBD
4 * 4 矩阵按键
#define uchar unsigned charvoid key_scanf()
{uchar i;P44 = P42 = P35 = P34 = 1;//初始化列线拉高for (i = 0; i < 4; i++){P3 |= 0x0f;//行初始化拉高,列线不变P3 &= ~(1 << i);//从上往下依次拉低行线if (!P44)//该行第一个键{ delay_k(20);if (!P44){while(!P44){display();}}key_val = 4 * i + 1;break;}剩下三个键类似}
}
void key_handle()
{key_scanf();通过key_val做出按键处理
}
2 * 2 矩阵按键
- 与4 * 4类似,对应初始化某两条列线先拉高。
- 需要for循环就控制i的初始值,不需要就除了需要判断的那一行拉低,另一行拉高,判断拉低的行的两个按键,对应哪一列为低
四个按键对应于左下角四个键s5 s4 s9 s8
void key_handle()
{P32 = P44 = P42 = 1;P33 = 0;if (!P44)//s4{delay_k(20);if (!P44){while(!P44)display();对应处理按键操作}}
斜按键操作
P34 = 1;P33 = 0, P30 = 1, P31 = 1, P32 = 1;//其他行默认低电平,所以我们将其拉高if(!P34)//s16{delay_k(10);if(!P34){if (2 == jm){if (--para_temp < 10)//参数操作 + 参数检查para_temp = 10;}if (1 == jm){while(!P34)//s17的长按键操作{rd_time();dsp_min_sec();}}while(!P34){display();} }}
NE555频率测量
①NE555频率测量,要把跳线帽接在P34和SIGNAL上,使用完之后记得把跳线帽摘下来,不然就会影响矩阵按键,因为矩阵按键第4列也接在P34上
②改变Rb3可以改变输出的频率值
uint cnt_freq, curr_freq;void timer0() interrupt 1
{cnt_freq++;
}
void timer1() interrupt 3
{static uchar i1 = 0;if (++i1 == 20)//1s{i1 = 0;curr_freq = cnt_freq;cnt_freq = 0;}
}
void sys_init()
{TMOD = 0x04; //设置定时器模式,定时器0--计数器模式,定时器1--定时器模式TL0 = 0xff;TH0 = 0xff;//来一个脉冲就溢出计数一次TR0 = 1;//50msTL1 = 0xB0; //设置定时初值TH1 = 0x3C; //设置定时初值TF1 = 0; //清除TF1标志TR1 = 1; //定时器1开始计时ET0 = 1;ET1 = 1;EA = 1;
}
ADC
通过pcf8591读数据,省赛中一般不会太搞人心态的,记住下方模板即可。
- 从pcf8591读数据
#define uchar unsigned char
uchar rd_pcf8591(uchar addr)
{uchar da;IIC_Start();IIC_SendByte(0x90);IIC_WaitAck();IIC_SendByte(addr);IIC_WaitAck();IIC_Start();IIC_SendByte(0x91);IIC_WaitAck();da = IIC_RecByte();IIC_SendAck(1);IIC_Stop();return da;
}
需要注意的是,由于pcf8591读取电压读取的为上一次的值,当我们连续从某多个通道读取数据时,每次调用时我们需要读取两次,这样才能保证数据的正确性。
#define uchar unsigned char
float v_val;
uchar rd_pcf8591(uchar addr)
{uchar da;uchar i;for (i = 0; i < 2; i++){IIC_Start();IIC_SendByte(0x90);IIC_WaitAck();IIC_SendByte(addr);IIC_WaitAck();IIC_Start();IIC_SendByte(0x91);IIC_WaitAck();da = IIC_RecByte();IIC_SendAck(1);IIC_Stop();} return da;
}
//255.0是小数,整个表达式被强制类型转换为浮点数,最后赋值给浮点数v_val
v_val = rd_pcf8591(0x03) * 5 / 255.0;
DAC
切换成为DAC输出模式,允许 DAC, 使用ADC 通道 0,最后注意需要延时5ms
void dac_pcf8591(uchar da)
{IIC_Start();IIC_SendByte(0x90);IIC_WaitAck();IIC_SendByte(0x40); //DAC输出模式,允许 DAC, ADC 通道 0IIC_WaitAck();IIC_SendByte(da);IIC_WaitAck();IIC_Stop();Delay5ms();
}
eeprom
省赛中一般就是对eeprom进行读写,也都是固定的代码模块,需要留意的是,为了保证一个完整的写入周期,我们需要延时5ms
- 写eeprom
#define uchar unsigned char
#define uint unsigned intvoid write_eeprom(uchar addr, da)
{IIC_Start();IIC_SendByte(0xa0);IIC_WaitAck();IIC_SendByte(addr);IIC_WaitAck();IIC_SendByte(da);IIC_WaitAck();IIC_Stop();Delay5ms();
}
- 读eeprom
#define uchar unsigned char
#define uint unsigned int
uchar rd_eeprom(uchar addr)
{uchar da;IIC_Start();IIC_SendByte(0xa0);IIC_WaitAck();IIC_SendByte(addr);IIC_WaitAck();IIC_Start();IIC_SendByte(0xa1);IIC_WaitAck();da = IIC_RecByte();IIC_SendAck(1);IIC_Stop();return da;
}
DS18B20
省赛中一般对温度进行保留小数或者读取整数的操作,也是几乎固定的模板
- 读取整数
#define uchar unsigned char
uchar rd_temp()
{uchar l, h, t;init_ds18b20();Write_DS18B20(0xcc);Write_DS18B20(0x44);init_ds18b20();Write_DS18B20(0xcc);Write_DS18B20(0xbe);l = Read_DS18B20();h = Read_DS18B20();t = (h << 4);t |= (l >> 4);return t;
}
- 读取带小数的温度
#define uchar unsigned char
#define uint unsigned int
float rd_temp()
{uchar l, h;uint t;float temp;init_ds18b20();Write_DS18B20(0xcc);Write_DS18B20(0x44);while(!DQ);init_ds18b20();Write_DS18B20(0xcc);Write_DS18B20(0xbe);l = Read_DS18B20();h = Read_DS18B20();t = (h & 0x0f);t <<= 8;t |= l;temp = t * 0.0625;return temp;
}
DS1302
省赛中一般仅仅使用秒、分、时,使用过程中主要就是需要注意,由于ds1302芯片存储的数据是BCD码,所以我们要进行BCD码与十进制之间的转换,例如0x16 的BCD码为16,十进制为1 * 16 + 6 = 32。
我个人是将这两者之间的转换放到官方给的底层代码中完成的,这样做的好处就是,我们在main.c中,只需要使用十进制,表示时间即可。
- 读时间
unsigned char Read_Ds1302_Byte ( unsigned char address )
{unsigned char i,temp=0x00;RST=0; _nop_();SCK=0; _nop_();RST=1; _nop_();Write_Ds1302(address);for (i=0;i<8;i++) { SCK=0;temp>>=1; if(SDA)temp|=0x80; SCK=1;} RST=0; _nop_();SCK=0; _nop_();SCK=1; _nop_();SDA=0; _nop_();SDA=1; _nop_();temp = temp / 16 * 10 + temp % 16;return (temp);
}
- 写时间
void Write_Ds1302_Byte( unsigned char address,unsigned char dat )
{RST=0; _nop_();SCK=0; _nop_();RST=1; _nop_(); Write_Ds1302(address);dat = dat / 10 * 16 + dat % 10; Write_Ds1302(dat); RST=0;
}
- main.c中初始化与读取时间
uchar init_time[] = {45, 59, 23};
uchar time[3] = { 0};
void time_init()
{Write_Ds1302_Byte(0x8e, 0);Write_Ds1302_Byte(0x80, init_time[0]);Write_Ds1302_Byte(0x82, init_time[1]);Write_Ds1302_Byte(0x84, init_time[2]);Write_Ds1302_Byte(0x8e, 80);//注意这个地方写80,而不是0x80,因为我们在底层代码中完成十进制转BCD码操作
}
void rd_time()
{time[0] = Read_Ds1302_Byte(0x81);time[1] = Read_Ds1302_Byte(0x83);time[2] = Read_Ds1302_Byte(0x85);
}
数据处理
在C语言中,浮点数 可以直接跟uint,uchar直接比较,在C语言内部会将这些类型都给强制类型转换为 同一类型。
float curr_temp = 25.6;
uchar temp_para = 25;
if (curr_temp > temp_para )
{对应处理操作
}
else
{对应处理操作
}
头文件修改
官方给iic.h、onewire.h、ds1302.h中使用的时C51的头件"reg52.h",我们需修改为对应的15系列头文件"STC15F2K60S2.h",这样才可以使用一些特殊位寄存器。
底层代码修改
需修改驱动代码onewire.c中单总线延时函数,官方给我们是STC89C52RC系列,15系列的单片机速度比51快8~12倍,需要修改对应的延时函数。修改如下:
void Delay_OneWire(unsigned int t)
{char i;while(t--)for (i = 0; i < 12; i++);
}
最后祝大家都能取得理想的成绩!!!
第十三届蓝桥杯赛前的一点总结相关推荐
- 2022年十三届蓝桥杯国赛(C/C++大学B组)个人题解
2022年十三届蓝桥杯国赛(C/C++大学B组)个人题解 更新:成绩出来了,估分50分左右,最后拿了个国二,还差点到国一,有点出乎意料,挺满意了挺满意了. 去年国赛基本都是暴力,最后国三都没拿到(我是 ...
- 第十三届蓝桥杯Python B组国赛题解
第十三届蓝桥杯Python B组国赛题解 试题A:斐波那契与7 试题 B: 小蓝做实验 试题 C: 取模 试题 D: 内存空间 试题 E: 近似 GCD 试题 F: 交通信号 试题 G: 点亮 试题 ...
- 2022 第十三届蓝桥杯省赛 C/C++ B组 试题与个人题解
2022 第十三届蓝桥杯省赛 C/C++ B组 试题与个人题解 试题A: 九进制转十进制 本题总分:5分 [问题描述] 九进制正整数 (2022), 转换成十进制等于多少? [答案提交] 这是一道结果 ...
- 第十三届蓝桥杯C++B组j国赛
第十三届蓝桥杯C++组 题目 2693: 蓝桥杯2022年第十三届决赛真题-卡牌 题目描述 这天,小明在整理他的卡牌. 他一共有 n 种卡牌,第 i 种卡牌上印有正整数数 i(i ∈ [1, n]), ...
- 第十三届蓝桥杯大赛软件赛省赛真题
第十三届蓝桥杯大赛软件赛省赛Java 大学 B 组 文章目录 第十三届蓝桥杯大赛软件赛省赛Java 大学 B 组 [考生须知] 试题 A: 星期计算 试题 B: 山 试题 C: 字符统计 试题 D: ...
- 第十三届蓝桥杯大赛软件赛省赛 Python 大学 B 组
第十三届蓝桥杯大赛软件赛省赛 Python 大学 B 组 第十三届蓝桥杯大赛软件赛省赛 Python 大学 B 组 [考生须知] 考试开始后,选手首先下载题目,并使用考场现场公布的解压密码解压试 题. ...
- 第十三届蓝桥杯大赛软件赛省赛(b组c语言)
试题 A: 九进制转十进制 本题总分:5 分 [问题描述] 九进制正整数 (2022)9 转换成十进制等于多少? 这道题没什么说的,2*9*9*9+0*9*9+2*9+2*1=1478: 试题 B: ...
- 第十三届蓝桥杯复盘及未来规划
2022年4月28日 第十三届蓝桥杯结果揭晓 面对这份成绩,心里有些沉重 qwq 心里五味杂陈 当看到距离省1只差4个名额,当看到清晰又刺眼的'二等奖',当看到社群里面好多小伙伴拿到了省1的同时分享着 ...
- 第十三届蓝桥杯模拟赛第二期JAVA组个人题解
第十三届蓝桥杯模拟赛第二期JAVA组个人题解 文章目录 第十三届蓝桥杯模拟赛第二期JAVA组个人题解 题目1 题目2 题目3 题目4 题目5 题目6 题目7 题目8 题目9 题目10 题目1 小蓝的I ...
最新文章
- 《Adobe After Effects CC完全剖析》——动画:完全是由“关系”组成的
- High Logic MainType 10中文版
- js字符串替换_浅析Vue的生命周期以及JS异步
- 讯飞linux_深度deepin又添一员“猛将”,讯飞输入法Linux版来了
- gulp 和npm_为什么我离开Gulp和Grunt去看npm脚本
- 世界之窗浏览器怎么隐藏收藏栏
- 图像处理之特征描述与匹配
- Java 8.if语句
- 你不知道的Event Loop
- [Java] 蓝桥杯BASIC-19 基础练习 完美的代价
- 5.2.1 标准原子类型
- snyk 项目漏洞检测
- 裤子尺码对照表eur40_裤子尺寸对照表,衣服尺寸对照表,服装尺寸对照表- 尺码对照表...
- 实验室的温湿度要求及其控制措施的详细讲解
- S32K--输入捕获(FTM_IC)配置与使用学习笔记(SDK3.0)
- 判断一个整数能否同时被3和5整除
- 2019届计算机专业-上海国企单位(银行、证券、通信)秋招经验大杂烩
- 手机之家在线签名_手写签名在线生成器在线-手写签名在线生成器在线
- NVT平台model屏幕配置
- office 2019+mathtype安装(word不显示,latex公式转换{EMBED Equation.DSMT4}问题等)