比赛最主要的实现功能,需要关注各个部分之间的逻辑!

赛前的一点总结

  • 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 矩阵按键

  1. 与4 * 4类似,对应初始化某两条列线先拉高。
  2. 需要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++);
}

最后祝大家都能取得理想的成绩!!!

第十三届蓝桥杯赛前的一点总结相关推荐

  1. 2022年十三届蓝桥杯国赛(C/C++大学B组)个人题解

    2022年十三届蓝桥杯国赛(C/C++大学B组)个人题解 更新:成绩出来了,估分50分左右,最后拿了个国二,还差点到国一,有点出乎意料,挺满意了挺满意了. 去年国赛基本都是暴力,最后国三都没拿到(我是 ...

  2. 第十三届蓝桥杯Python B组国赛题解

    第十三届蓝桥杯Python B组国赛题解 试题A:斐波那契与7 试题 B: 小蓝做实验 试题 C: 取模 试题 D: 内存空间 试题 E: 近似 GCD 试题 F: 交通信号 试题 G: 点亮 试题 ...

  3. 2022 第十三届蓝桥杯省赛 C/C++ B组 试题与个人题解

    2022 第十三届蓝桥杯省赛 C/C++ B组 试题与个人题解 试题A: 九进制转十进制 本题总分:5分 [问题描述] 九进制正整数 (2022), 转换成十进制等于多少? [答案提交] 这是一道结果 ...

  4. 第十三届蓝桥杯C++B组j国赛

    第十三届蓝桥杯C++组 题目 2693: 蓝桥杯2022年第十三届决赛真题-卡牌 题目描述 这天,小明在整理他的卡牌. 他一共有 n 种卡牌,第 i 种卡牌上印有正整数数 i(i ∈ [1, n]), ...

  5. 第十三届蓝桥杯大赛软件赛省赛真题

    第十三届蓝桥杯大赛软件赛省赛Java 大学 B 组 文章目录 第十三届蓝桥杯大赛软件赛省赛Java 大学 B 组 [考生须知] 试题 A: 星期计算 试题 B: 山 试题 C: 字符统计 试题 D: ...

  6. 第十三届蓝桥杯大赛软件赛省赛 Python 大学 B 组

    第十三届蓝桥杯大赛软件赛省赛 Python 大学 B 组 第十三届蓝桥杯大赛软件赛省赛 Python 大学 B 组 [考生须知] 考试开始后,选手首先下载题目,并使用考场现场公布的解压密码解压试 题. ...

  7. 第十三届蓝桥杯大赛软件赛省赛(b组c语言)

    试题 A: 九进制转十进制 本题总分:5 分 [问题描述] 九进制正整数 (2022)9 转换成十进制等于多少? 这道题没什么说的,2*9*9*9+0*9*9+2*9+2*1=1478: 试题 B: ...

  8. 第十三届蓝桥杯复盘及未来规划

    2022年4月28日 第十三届蓝桥杯结果揭晓 面对这份成绩,心里有些沉重 qwq 心里五味杂陈 当看到距离省1只差4个名额,当看到清晰又刺眼的'二等奖',当看到社群里面好多小伙伴拿到了省1的同时分享着 ...

  9. 第十三届蓝桥杯模拟赛第二期JAVA组个人题解

    第十三届蓝桥杯模拟赛第二期JAVA组个人题解 文章目录 第十三届蓝桥杯模拟赛第二期JAVA组个人题解 题目1 题目2 题目3 题目4 题目5 题目6 题目7 题目8 题目9 题目10 题目1 小蓝的I ...

最新文章

  1. 《Adobe After Effects CC完全剖析》——动画:完全是由“关系”组成的
  2. High Logic MainType 10中文版
  3. js字符串替换_浅析Vue的生命周期以及JS异步
  4. 讯飞linux_深度deepin又添一员“猛将”,讯飞输入法Linux版来了
  5. gulp 和npm_为什么我离开Gulp和Grunt去看npm脚本
  6. 世界之窗浏览器怎么隐藏收藏栏
  7. 图像处理之特征描述与匹配
  8. Java 8.if语句
  9. 你不知道的Event Loop
  10. [Java] 蓝桥杯BASIC-19 基础练习 完美的代价
  11. 5.2.1 标准原子类型
  12. snyk 项目漏洞检测
  13. 裤子尺码对照表eur40_裤子尺寸对照表,衣服尺寸对照表,服装尺寸对照表- 尺码对照表...
  14. 实验室的温湿度要求及其控制措施的详细讲解
  15. S32K--输入捕获(FTM_IC)配置与使用学习笔记(SDK3.0)
  16. 判断一个整数能否同时被3和5整除
  17. 2019届计算机专业-上海国企单位(银行、证券、通信)秋招经验大杂烩
  18. 手机之家在线签名_手写签名在线生成器在线-手写签名在线生成器在线
  19. NVT平台model屏幕配置
  20. office 2019+mathtype安装(word不显示,latex公式转换{EMBED Equation.DSMT4}问题等)

热门文章

  1. Java 6大设计原则28大设计模式
  2. 如何快速的在Windows自带cmd生产文件的MD5数值
  3. FlexSim批量操作插件
  4. 劳动法对女职工在经期、孕期、产期、哺乳期所享受的特殊保护有哪些规定?
  5. 3D数字人虚拟人带你解锁更多元宇宙玩法
  6. 物联网 android前景,物联网卡的发展前景
  7. 计算机音乐算法冯,恒模算法
  8. OTB100数据集序列分类
  9. preg_match 与 preg_match_all 区别
  10. 反思既往 也同时送给屌丝程序员一些小福利