五.用LED灯显示格蠹光码

5.1背景和基本目标

在深度嵌入式系统中的,常常没有标准的显示器,这时如何实现人机交互就成为一个常见的问题。本项目通过一个简单的LED灯,以长短不同的闪烁来编码,输出信息,具有成本低,易于实现的优势

开发包下载:https://gedu.oss-cn-beijing.aliyuncs.com/gdk3/gdk3sdk20230109.zip

相关代码在开发包的gdsk3\src\gecode上,里面已经make生成了gecode.elfgecode.hex

如何烧录详情可返回上手系列之三,默认显示gdk3字符串的光码glc_show_string("gdk3");。
想要自己编写函数并编译和烧录的话,自己编写完成后再重新make
make clean可以清除make产生的文件

提示与建议

1.建议学习和熟悉makefile的使用
2.每次使用MSYS2 MSYS都要重新export PATH=路径:$PATH 设置gnu arm工具链路径

5.2编码方法

以下是基本的编码规则:
1)每个比特的显示长度固定,亮表示1,不亮表示0
2)每个字节的间隔为三次快闪(显示间隔时间是每个比特时间的十分之一)

5.3编码

编码建议

所有函数都以glc开头,代表gedu light code

5.3.1用于控制连接状态指示灯的亮灭状态的函数

void LED_CONNECTED_OUT(uint32_t bit)
{
    if (bit & 1)
        CONNECTED_LED_PORT->BCR/*BRR*/ = CONNECTED_LED_PIN; // LED on  为低电平时亮起
    else
        CONNECTED_LED_PORT->BSHR/*BSRR*/ = CONNECTED_LED_PIN;// LED off 为高电平时熄灭
}

5.3.2定义一个显示一比特的函数

void glc_show_bit(bool one)
{
    LED_CONNECTED_OUT((uint32_t)one);       //将bool值强制转化成整型,调用控制led灯亮灭的函数,uint32_t是用typedef定义的无符号int型宏定义
    Delay_Ms(500);                          //设置延时,便于观察小灯亮灭的变化
}

5.3.3三次快闪,显示字节间隔的函数

int  gd_blink_gap()
{
    int counter = 0;                        //控制led灯亮与灭的变量
    int num = 0; 
    int delay=50;
    while (num < 3)                         //循环三次,使得实现3次快闪
    {
        Delay_Ms(delay);                    //设置延时时间,便于观察led灯的变化
        PBout(12) ^= (1 << 0);              
        if (counter % 2 == 1)               //如果counter % 2 == 1,则led灯会亮,用num计数
            num++;                          //小灯每亮一次num加一
        LED_CONNECTED_OUT((counter++) % 2); //如果(counter++) % 2为0,小灯灭,反之,小灯亮
    }
    return counter;
}

5.3.4定义显示一个字节的函数

void glc_show_byte(unsigned char byte)
{
    for (int i= 0; i <=7; i++)             //显示字节可以用for循环转化成显示位的函数,一个字符占一个byte,占8bit,整型数在计算机中会以二进制的形式体现,每一位都要进行判断是0或1
    {
        glc_show_bit((byte >>i)&1);           //因为1的二进制形式位0000 0001,利用for循环将byte每个二进制数右移,和1进行与运算,判断每一位是0还是1,调用显示一比特的函数,用LED的亮与灭来判断每一位是0还是1
    }
    gd_blink_gap();                        //判断完一个字节,跳出for循环,调用gd_blink_gap()函数
}

5.3.5定义一个显示字符串的函数

void glc_show_string(const char* str)
{
     for (int i = 0; i < strlen(str); i++) //显示字符串可以用for循环转化成显示字符的函数
     {
         glc_show_byte(str[i]);      //调用显示字节的函数并传入字符
     }
}

5.4 编码执行过程

建议大家自行理解执行过程以下仅供参考

glc_show_string(传入字符串)->glc_show_byte(依次传入字符串中每一个字符)将每个字符的每位二进制传入->glc_show_bit(传入字符的每个二进制数)是1就亮0就灭形成光码->gd_blink_gap()快速闪烁3次以此判断一个字符光码已经形成继续进入下一个字符。

初学者可能会遇到的问题和注意事项(也是我的切身体会,说多了都是泪啊):

  • 写代码时,要注意换行和缩进,统一格式,尽量使代码看起来更加简洁,要去掉冗余的代码,多思考。
  • 要注意函数之间的关系,比如你想定义一个显示字符串的函数,那你可以通过使用for循环调用显示字符的函数,显示字符又可以通过调用显示位的函数,一定要注意函数之间的关系。
  • 写代码时,不要调用基础函数,一定要多实践,在主函数中调用字符串函数时可以直接传递一个字符串,不用设置一个变量再赋值的,要使代码看起来更加简洁。
  • 关于一些知识点的总结,可能有些小伙伴对一些知识点不太了解或者忘记啦。
    uint32_t是用typedef定义的无符号int型宏定义
    所有的指针变量进行sizeof的操作结果均为4,所以我们进行的sizeof(str)运算,得到的就是指针所占的字节数.
作者:zuoyingying  创建时间:2022-12-13 11:55
最后编辑:李梓涌  更新时间:2024-02-02 17:39