前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >STC51(点灯+五向开关)

STC51(点灯+五向开关)

作者头像
云深无际
发布2021-01-20 15:45:43
7980
发布2021-01-20 15:45:43
举报
文章被收录于专栏:云深之无迹云深之无迹

实物

原理图

丝印层


这个实验需要做程序的烧录,需要一些下载的软件什么的

代码语言:javascript
复制
https://www.stcisp.com/

STC的官网丢上来。

菊花里面夹芯片

哪个鬼才整的这花活

好家伙儿,我一往开点。差点把我送走

这是

吃~

这个是意法的官网,不是我崇洋媚外。

芯片这么高大上的东西,能不能让我看一眼就不明觉厉啊。。。

点击这里下载烧录软件

代码语言:javascript
复制
http://www.stcmcudata.com/STCISP/stc-isp-15xx-v6.88.zip

解压的文件有这些

打开以后第一遍提醒这个

说我芯片老,emmmmm

先设置一下这个串口


按说是先点灯才对,我们点个灯吧

这个就是编程控制的最基本的

这个地方的意思就是连接串口烧录

P3.0

P3.1

在这个地方可以知道设计的准则

选择晶振的频率

选择要生成hax文件

我们还要加这个头文件,延时用

选择要下载的Hax文件

上传成功

代码语言:javascript
复制
#include "reg52.h"
#include "intrins.h"
sbit LED = P1^7;
void Delay1000us();
int main(void){
   while(1){
    LED = 0;
 Delay1000us();
    LED = 1;
 Delay1000us();
   }
}
void Delay1000us()    //@11.0592MHz
{
  unsigned char i, j;
  _nop_();
  _nop_();
  _nop_();
  i = 11;
  j = 190;
  do
  {
    while (--j);
  } while (--i);
}

对于这个延时,可以用下载软件的自动生成代码


到现在为止,灯也亮完了。硬件ok,软件ok~

写按钮吧~

我们一会儿写程序实现这个效果

上下左右,这个叫法顺口

对应小灯LED1,2,3,4

看到对应连接4个LED小灯

左边还有限流电阻

这个是原理图,是公阳极的连接

分别连在芯片这些脚上

我们要实现以上的功能,需要这么多的文件。或者说是程序

我边写边解释嗷~

按照我上篇文章的说法

这个程序分为,硬件模块,逻辑模块以及延时模块

代码语言:javascript
复制
#include "config.h"//ÒýÈëÅäÖÃÄ£¿é
#include "key.h"//ÒýÈ밴ťģ¿é
#include "delay.h"//ÒýÈëÑÓʱģ¿é
int main(void){
  while(1){
    if(!Key_Up_Press())led1=~led1;    //up    -> led1 toggle
    if(!Key_Left_Press())led2=~led2;  //left  -> led2 toggle
    if(!Key_Right_Press())led3=~led3; //right -> led3 toggle
    if(!Key_Down_Press())led4=~led4;  //down  -> led4 toggle
    if(!Key_Enter_Press()){        //enter -> led1~led4 toggle
      led1=~led1;
      led2=~led2;
      led3=~led3;
      led4=~led4;
    }
  }
}

上面的编码方式有点不对劲,是GB2312的。浏览器是UTF-8的,所以乱码了

这个地方我注释都是加的模块,可能更加的符合程序整体的模块化的感觉

可能有人会问为什么木有看见单片机特殊功能寄存器的头文件,那是因为在配置文件的模块里面引用了,属于配置方面的模块了,注意这种编程的思想

代码语言:javascript
复制
while(1){
    if(!Key_Up_Press())led1=~led1;    //up    -> led1 toggle
    if(!Key_Left_Press())led2=~led2;  //left  -> led2 toggle
    if(!Key_Right_Press())led3=~led3; //right -> led3 toggle
    if(!Key_Down_Press())led4=~led4;  //down  -> led4 toggle
    if(!Key_Enter_Press()){        //enter -> led1~led4 toggle
      led1=~led1;
      led2=~led2;
      led3=~led3;
      led4=~led4;
    }
  }

因为就是裸机的MCU编码,所以直接死循环安排了

下面写了5个if判断,来判断对应按钮按下灯的状态!我用了状态的词语


这个里面的要点有很多:

比如文件的格式,这个是一种写法

代码语言:javascript
复制
while (1)
  {
    if (!Key_Up_Press())
    {
      led1 = ~led1
    }; //up    -> led1 toggle
    if (!Key_Left_Press())
    {
      led2 = ~led2
    }; //left  -> led2 toggle
    if (!Key_Right_Press())
    {
      led3 = ~led3
    }; //right -> led3 toggle
    if (!Key_Down_Press())
    {
      led4 = ~led4
    }; //down  -> led4 toggle
    if (!Key_Enter_Press())
    { //enter -> led1~led4 toggle
      led1 = ~led1;
      led2 = ~led2;
      led3 = ~led3;
      led4 = ~led4;
    }
  }

我可以写成这样

有的人习惯上是如果if后面只有一个语句,就直接分号处理。

我给的建议是,只要出现if就加{},这是一种习惯。分号的作用就是来限定作用域,不能因为代码量少就破坏这种感觉,诚然单语句不写花括号是清爽的表现,但是现代软件工程就难在维护上面。希望你要了解这些代码之外的东西,在编写之初,甚至是学习之初就不要有小毛病。


还有这个变量名的命名方式单个动词大写首字母用多个下划线连接多个动词。

还有一点就是用~的逻辑运算符号

代码语言:javascript
复制
  if (!Key_Enter_Press())
    { //enter -> led1~led4 toggle
      led1 = ~led1;
      led2 = ~led2;
      led3 = ~led3;
      led4 = ~led4;
    }

最后直接就是按下中心按钮,4个LED同时取反。


接下来我们看我们对按钮模块的抽象

首先看h文件,对将要使用的函数有个认识

可以从这几个方面看

那我们上面的函数就是,无参数调用。返回值是个bit。

其实就是返回一个状态

这个文件就是key的实现了

首先是引入3个头文件,具体作用可以看上面。头文件让模块之间相联系

首先这个C文件里面就是5个函数的具体实现。没有其他内容

代码语言:javascript
复制
bit Key_Up_Press(void){
  bit flag = 1;         //¶¨Òå°´¼ü±ê־λ
  key1 = 1;         //ÉèÖóÉÊäÈë״̬
  if(!key1){         //²éѯ°´¼üÊÇ·ñ°´ÏÂ
    Delay15ms();     //Ìø¹ýÇ°Ñض¶¶¯
    if(!key1){       //È·¶¨ÊÇ·ñ°´ÏÂ
      while(!key1);  //µÈ´ýÊÍ·Å
      Delay15ms();   //Ìø¹ýºóÑض¶¶¯
      while(!key1);  //µÈ´ýÊÍ·Å
      flag = 0;     //°´¼ü±ê־λÇåÁã
    }
  }  
  return flag;       //·µ»Ø0±íʾ°´¼ü°´ÏÂ
}

就分析一个函数就可以,其他函数都是改一下名字而已

此时我们遇到了第一个难点


你认为你按下这个开关的时候电路一下机导通了,并且维持在稳定的状态。其实不是的,这个过程里面有机械抖动的,按下时的抖动叫前沿抖动,中间才是稳定的状态。你抬手的时候,是按下的逆向过程。

对于按钮你想实现很多的功能,比如摁一下,俩下,三下,长按1s,长按2s。这些场景里面,上面的这个物理现象就会让你很苦恼,怎么办?

在制作很昂贵的硬件的时候,或者你的客户一定要加硬件去抖动的

亦或是你真的很富有,那你就加。(其实按键俩段并联电容就好)


我们重点讲这个软件去抖动。

延时+判断就好了,既然抖动过程很短,那就避过去,然后再判断你的按键情况。

就好了,至于这个延时时间目前是15ms(单片机是us运行)。

这个就是我们编写这个程序的依据

首先定义了一个bit变量,来存放一个默认的状态,这个bit未来会传出去。

接着将IO设置为输入的状态,一接通,导电,开始干活

接着是一个if的判断,先查看IO的信息,确认没有按下!

开始软件延时:延时15ms

再if判断,查看此时的IO状态,如果按下的话就等着按键的下个状态就是松开。此时再延时来跳过松开按键时,IO对按钮状态的读取。释放了,按钮的状态就是0,所以flag = 0;接着跳出循环,用return将按键的信息传递出去。函数的使命就结束了。当然更加复杂的逻辑也是这个函数的变种,我们后面会分析一个游戏手柄的库,我们再详细的进行分析。


这个是上文对应的查询方式

延时函数的头,一个15ms,一个5ms

这个是具体的实现,可以用软件生成

在配置文件内,首先是两个头文件

一个是MCU的特殊功能寄存器的定义或是映射表

一个是延时用的头文件

代码语言:javascript
复制
typedef unsigned char uint8;
typedef unsigned int  uint16;
typedef unsigned long uint32;
typedef signed char   int8;
typedef signed int    int16;
typedef signed long   int32;

typedef是一个内置的关键字(我在放屁),就是将已有的数据类型重新包装(就是对于名字而已),优点是统一数据类型,方便多平台移植。

然后就是一个对于引脚的定义

就是这么个情况,视频还得审核、、、

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-01-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 云深之无迹 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档