【XR806开发板试用】SPI驱动数码管显示

news2024/12/25 22:09:05

准备工作

安装repo
  • 创建repo安装目录。

    mkdir ~/bin
    
  • 下载repo

    wget https://storage.googleapis.com/git-repo-downloads/repo -P ~/bin/
    
  • 改变执行权限

    chmod a+x ~/bin/repo
    
  • 设置环境变量,在~/.bashrc文件的最后输入

    export PATH=~/bin:$PATH和export REPO_URL=https://mirrors.tuna.tsinghua.edu.cn/git/git-repo/
    
  • 重启shell

代码下载

#mkdir xr806_openharmony
#cd xr806_openharmony
#repo init -u https://gitee.com/openharmony/manifest.git -b OpenHarmony_1.0.1_release --no-repo-verify
#repo sync -c
#repo forall -c 'git lfs pull'   #下载部分大容量二进制文件

下载xr806源码

从https://gitee.com/moldy-potato-chips/devboard_device_allwinner_xr806 下载device仓内容。
从https://gitee.com/moldy-potato-chips/devboard_vendor_allwinner_xr806 下载vendor仓内容。
目录结构

device仓目录

device/xradio/xr806
├── adapter				# OpenHarmony接口适配
├── BUILD.gn			# GN构建脚本
├── build.sh			# 启动编译脚本
├── doc					# 指导文档
├── libcopy.py			# SDK编译脚本
├── liteos_m			# 编译工具,编译选项定义
├── os					# liteos接口适配
├── target_config.h		# liteos系统裁剪
└── xr_skylark			# SDK平台相关文件(内核驱动)

vendor仓目录

vendor/xradio
├── LICENSE
├── README.md
└── xr806

环境配置

安装必要的库和工具
sudo apt-get install build-essential gcc g++ make zlib* libffi-dev e2fsprogs pkg-config flex bison perl bc openssl libssl-dev libelf-dev libc6-dev-amd64 binutils binutils-dev libdwarf-dev u-boot-tools mtd-utils gcc-arm-linux-gnueabi cpio device-tree-compiler
安装Python3
python3 --version
sudo apt-get install python3.8
sudo apt update && sudo apt install software-properties-common

安装hb

python3 -m pip install --user ohos-build
vim ~/.bashrc
export PATH=~/.local/bin:$PATH
source ~/.bashrc

设置编译工具链

编译链工具推荐gcc-arm-none-eabi-10-2020-q4-major。(下载网站:
https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm/downloads)

修改device/xradio/xr806/liteos_m/config.gni中的board_toolchain_prefix为实际环境下的gcc路径,以存放在tools文件夹下为例。

board_toolchain_prefix = "~/tools/gcc-arm-none-eabi-10-2020-q4-major/bin/arm-none-eabi-"

修改device/xradio/xr806/xr_skylark/gcc.mk中的CC_DIR为实际环境下的gcc路径,以存放在tools文件夹下为例。

CC_DIR := ~/tools/gcc-arm-none-eabi-10-2020-q4-major/bin

工程配置

进入SDK目录。

cd device/xradio/xr806/xr_skylark/

复制配置文件。

cp project/demo/audio_demo/gcc/defconfig .config

使用图形化界面确认配置。

make menuconfig

执行make menuconfig后,按方向键选择save保存后,选择exist退出即可。

清除过程文件。

make build_clean

生成静态库已经自动生成头文件。

make lib -j2

返回根目录编译工程。

返回根目录。

cd - 

选择厂商。

hb set  #回车,并选择wifi_skylark

编译系统,后续文件修改不需要重复配置。

hb build -f

SPI驱动点阵数码管

数码管采用的是MAX7219点阵模块 4合一显示屏模块,购买链接:https://item.taobao.com/item.htm?spm=a1z09.2.0.0.6fd52e8dlTXLdZ&id=534578656397&_u=nkiuie8f98

引脚连接

1.VCC  ---   VCC
2.GND  ---   GND
3.DIN  ---   PB04
4.CS   ---   PB06
5.CLK  ---   PB07

main.c

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "ohos_init.h"
#include "driver/chip/hal_gpio.h"
#include "driver/chip/hal_spi.h"
#include "kernel/os/os.h"
#include "wifi_device.h"

/* GPIO */
#define GPIO_OUTPUT_PORT             GPIO_PORT_A

/* spi */
#define DEMO_SPI_MCLK                (48 * 1000 * 1000)
#define DEMO_SPI_CS_LEVEL            0
#define DEMO_SPI_PORT                SPI0
#define DEMO_SPI_CS                  SPI_TCTRL_SS_SEL_SS0

static OS_Thread_t g_led_thread;
static OS_Thread_t g_spi_thread1;
static OS_Thread_t g_spi_thread2;

static void gpio_output_init(void)
{
    GPIO_InitParam param;
    param.driving = GPIO_DRIVING_LEVEL_1;
    param.mode = GPIOx_Pn_F1_OUTPUT;
    param.pull = GPIO_PULL_NONE;
    HAL_GPIO_Init(GPIO_OUTPUT_PORT, GPIO_PIN_21, &param);   //led灯对应IO
}

/*
 * buf按十六进制输出
 */
static void hexdump(unsigned char *buf, unsigned int num)
{
    unsigned int i = 0;
    for (; i < num; i++)
    {
        printf("%02X ", buf[i]);
        if ((i + 1) % 5 == 0)
            printf("\n");
    }
    printf("\r\n");
}

static void gpio_output_ctl(uint8_t level)
{
    HAL_GPIO_WritePin(GPIO_OUTPUT_PORT, GPIO_PIN_21, level ? GPIO_PIN_HIGH : GPIO_PIN_LOW);
}

static int spi_init(void)
{
    SPI_Config spi_Config;
    HAL_Status ret = HAL_OK;
    SPI_Global_Config spi_param;

    spi_param.cs_level = DEMO_SPI_CS_LEVEL;
    spi_param.mclk = DEMO_SPI_MCLK;

    HAL_SPI_Init(DEMO_SPI_PORT, &spi_param);

    spi_Config.firstBit = SPI_TCTRL_FBS_MSB;
    spi_Config.mode = SPI_CTRL_MODE_MASTER;
    spi_Config.opMode = SPI_OPERATION_MODE_POLL;
    spi_Config.sclk = 4000000;
    spi_Config.sclkMode = SPI_SCLK_Mode0;

    printf("spi init...\n");
    ret = HAL_SPI_Open(DEMO_SPI_PORT, DEMO_SPI_CS, &spi_Config, 5000);
    if (ret != HAL_OK)
    {
        printf("spi open failed");
        return ret;
    }

    HAL_SPI_Config(DEMO_SPI_PORT, SPI_ATTRIBUTION_IO_MODE, SPI_IO_MODE_NORMAL);
    HAL_SPI_CS(DEMO_SPI_PORT, 1);

    return ret;
}

static int spi_deinit(void)
{
    HAL_Status ret = HAL_OK;

    printf("spi deinit...\n");
    HAL_SPI_CS(DEMO_SPI_PORT, 0);
    HAL_SPI_Close(DEMO_SPI_PORT);

    return ret;
}

static void LedThread(void *arg)
{
    gpio_output_init();

    while(1)
    {
        gpio_output_ctl(1);
        OS_Sleep(1);
        gpio_output_ctl(0);
        OS_Sleep(1);
    }
}

static void SpiThread1(void *arg)
{
    HAL_Status ret = HAL_OK;
    uint8_t cmd[] = {0xFF, 0x11, 0x22, 0x33, 0x00};
    uint8_t data[5];

    printf("spi demo started.\n");
    if (HAL_OK != spi_init())
    {
        printf("spi init failed.\n");
        return;
    }

    while(1)
    {
        cmd[4] += 1;
        printf("spi write...\n");
        ret = HAL_SPI_TransmitReceive(DEMO_SPI_PORT, cmd, data, 5);
        if (ret != HAL_OK)
        {
            printf("spi write failed");
        }
        printf("spi read...\n");
        hexdump(data,5);
        OS_Sleep(1);
    }

    if (HAL_OK != spi_deinit())
    {
        printf("spi deinit failed.\n");
        return;
    }
}

unsigned char disp1[20][8]=
{
#if 0
    {0x3C,0x42,0x42,0x42,0x42,0x42,0x42,0x3C},  //0
    {0x10,0x30,0x50,0x10,0x10,0x10,0x10,0x38},  //1
    {0x7E,0x2,0x2,0x7E,0x40,0x40,0x40,0x7E},    //2
    {0x3E,0x2,0x2,0x3E,0x2,0x2,0x3E,0x0},       //3
    {0x8,0x18,0x28,0x48,0xFE,0x8,0x8,0x00},     //4
    {0x0,0x3C,0x20,0x20,0x3C,0x4,0x4,0x3C},     //5
    {0x0,0x3C,0x20,0x20,0x3C,0x24,0x24,0x3C},   //6
    {0x0,0x3E,0x22,0x4, 0x8, 0x8, 0x8, 0x8},    //7
    {0x0,0x3E,0x22,0x22,0x3E,0x22,0x22,0x3E},   //8
    {0x3E,0x22,0x22,0x3E,0x2,0x2,0x3E,0x00},    //9
    {0x0,0x8,0x14,0x22,0x3E,0x22,0x22,0x22},    //A
    {0x0,0x3C,0x22,0x22,0x3E,0x22,0x22,0x3C},   //B
    {0x0,0x3C,0x40,0x40,0x40,0x40,0x40,0x3C},   //C
    {0x0,0x7C,0x42,0x42,0x42,0x42,0x42,0x7C},   //D
    {0x7C,0x40,0x40,0x7C,0x40,0x40,0x7c,0x00},  //E
    {0x00,0x7C,0x40,0x40,0x7C,0x40,0x40,0x40},  //F
    {0x00,0x3C,0x40,0x40,0x40,0x44,0x44,0x3C},  //G
    {0x00,0x44,0x44,0x44,0x7C,0x44,0x44,0x44},  //H
    {0x00,0x10,0xFE,0x92,0x92,0xFE,0x10,0x10},  //中
    {0xFE,0xBA,0x92,0xBA,0x92,0x9A,0xBA,0xFE},  //国

#else
    {0x3C,0x40,0x40,0x38,0x04,0x04,0x78,0x00},  //S
    {0x7C,0x10,0x10,0x10,0x10,0x10,0x10,0x00},  //T
    {0x10,0x10,0x28,0x28,0x38,0x6c,0x44,0x00},  //A
    {0x78,0x44,0x44,0x78,0x48,0x44,0x42,0x00},  //R
#endif
};


#define Max7219_pinCS_Set()     HAL_SPI_CS(DEMO_SPI_PORT, 1)
#define Max7219_pinCS_Clr()     HAL_SPI_CS(DEMO_SPI_PORT, 0);

void Write_Max7219_byte(unsigned char data)
{
    HAL_Status ret = HAL_OK;
    unsigned char rdata;

    ret = HAL_SPI_TransmitReceive(DEMO_SPI_PORT, &data, &rdata, 1);
    if (ret != HAL_OK)
    {
        printf("spi write failed");
    }
}

void Init_MAX7219(void)
{
    int i = 0;
    //译码方式:BCD码
    Max7219_pinCS_Clr();
    for(i = 0; i < 4; i++)
    {
        Write_Max7219_byte(0x09);
        Write_Max7219_byte(0x00);
    }
    Max7219_pinCS_Set();
    //亮度
    Max7219_pinCS_Clr();
    for(i = 0; i < 4; i++)
    {
        Write_Max7219_byte(0x0a);
        Write_Max7219_byte(0x03);
    }
    Max7219_pinCS_Set();
    //扫描界限;8个数码管显示
    Max7219_pinCS_Clr();
    for(i = 0; i < 4; i++)
    {
        Write_Max7219_byte(0x0b);
        Write_Max7219_byte(0x07);
    }
    Max7219_pinCS_Set();
    //掉电模式:0,普通模式:1
    Max7219_pinCS_Clr();
    for(i = 0; i < 4; i++)
    {
        Write_Max7219_byte(0x0c);
        Write_Max7219_byte(0x01);
    }
    Max7219_pinCS_Set();
    //显示测试:1;测试结束,正常显示:0
    Max7219_pinCS_Clr();
    for(i = 0; i < 4; i++)
    {
        Write_Max7219_byte(0x0f);
        Write_Max7219_byte(0x00);
    }
    Max7219_pinCS_Set();
}

static void SpiThread2(void *arg)
{
    printf("spi demo2 started.\n");
    int i, j;

    if (HAL_OK != spi_init())
    {
        printf("spi init failed.\n");
        return;
    }

    Init_MAX7219();

    while(1)
    {
        for(i = 1; i < 9; i++)
        {
            Max7219_pinCS_Clr();
            for(j = 0; j < 4; j++)
            {
                Write_Max7219_byte(i);                  //写入地址,即数码管编号
                Write_Max7219_byte(disp1[j][i-1]);      //写入数据,即数码管显示数字
            }
            Max7219_pinCS_Set();
        }
        OS_Sleep(1);
    }

    if (HAL_OK != spi_deinit())
    {
        printf("spi deinit failed.\n");
        return;
    }
}

void SPITestMain(void)
{
    /*led flash test*/
    if (OS_ThreadCreate(&g_led_thread, "LedThread", LedThread, NULL,
                        OS_THREAD_PRIO_APP, 2 * 1024) != OS_OK)
    {
        printf("[ERR] Create LedThread Failed\n");
    }

    /*spi send recieve test*/
    /*
    if (OS_ThreadCreate(&g_spi_thread1, "SpiThread1", SpiThread1, NULL,
                        OS_THREAD_PRIO_APP, 4 * 1024) != OS_OK)
    {
        printf("[ERR] Create SpiThread Failed\n");
    }
    */
    /*spi led test*/
    if (OS_ThreadCreate(&g_spi_thread2, "SpiThread2", SpiThread2, NULL,
                        OS_THREAD_PRIO_APP, 4 * 1024) != OS_OK)
    {
        printf("[ERR] Create SpiThread Failed\n");
    }

}

SYS_RUN(SPITestMain);

实验结果

在这里插入图片描述

参考

  1. https://aijishu.com/a/1060000000288328
  2. https://aijishu.com/a/1060000000256653
  3. https://aijishu.com/a/1060000000256631

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1658083.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ANSI转义序列

一、ASCII码 ASCII&#xff08;American Standard Code for Information Interchange&#xff0c;美国信息交换标准代码&#xff09;最初的设计是一个7位的字符编码&#xff0c;使用了从0到127的数字来表示字符。这意味着它总共可以表示128个不同的字符。这包括了英文大小写字…

[鸟哥私房菜]4.首次登录与在线求助

第4章 首次登录与在线求助 4.1.3 X Window 与命令行模式的切换 通常我们称命令行界面为终端界面、Terminal 或 Console。Linux 默认的情况下会提供六个终端&#xff08;Terminal&#xff09;来让用户登录&#xff0c; 切换的方式为使用&#xff1a;[Ctrl] [Alt] [F1]~[F6] …

Joplin:自由、安全、多功能的笔记应用

什么是 Joplin&#xff1f; Joplin是一款免费、开源的笔记和待办事项应用程序&#xff0c;可以处理整理到笔记本中的大量笔记。这些笔记是可搜索的&#xff0c;可以直接从应用程序或从您自己的文本编辑器中复制、标记和修改。笔记采用Markdown 格式 功能亮点 功能丰富&#x…

超标量处理器设计:重排序缓存(ROB)

★超标量处理器的很多地方用到了重排序缓存&#xff0c;但是我对它不是很了解&#xff0c;所以我整理一下重排序缓存的知识点。 重排序缓存(ROB)在确保乱序执行的指令能够正确地完成和提交(Commit)&#xff0c;也可以用来寄存器重命名。 ROB是一个先进先出的表&#xff0c;每个…

基于Springboot的线上教学平台

基于SpringbootVue的线上教学平台设计与实现 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringbootMybatis工具&#xff1a;IDEA、Maven、Navicat 系统展示 用户登录 首页 学习资料 交流论坛 试卷列表 公告信息 后台登录 后台首页 学员管理 资料类型…

深入理解Linux中TCP/IP协议栈的实现原理与具体过程

一、Linux内核与网络体系结构 在我们了解整个linux系统的网络体系结构之前&#xff0c;我们需要对整个网络体系调用&#xff0c;初始化和交互的位置&#xff0c;同时也是Linux操作系统中最为关键的一部分代码-------内核&#xff0c;有一个初步的认知。 1、Linux内核的结构 …

pytest教程-43-钩子函数-pytest_report_header

领取资料&#xff0c;咨询答疑&#xff0c;请➕wei: June__Go 上一小节我们学习了pytest_runtest_makereport钩子函数的使用方法&#xff0c;本小节我们讲解一下pytest_report_header钩子函数的使用方法。 pytest_report_header 钩子函数允许你在 pytest 的终端报告的头部添…

系统运维(虚拟化)

1.VLAN VLAN&#xff08;Virtual Local Area Network&#xff09;即虚拟局域网&#xff0c;是将一个物理的LAN在逻辑上划分成多个广播域的通信技术。 每个VLAN是一个广播域&#xff0c;VLAN内的主机间可以直接通信&#xff0c;而VLAN间则不能直接互通。这样&#xff0c;广播报…

NOIP,CSP-J,CSP-S——图

一、图的基本概念 图是顶点和边的集合 1、无向图: 每一条边都是无方向的 2、有向图: 每一条边都是有方向的 3、完全图: 任意两个顶点都有一条边相连接; 4、结论 若n个顶点的无向图有n(n-1)/2条边,称为无向完成图; 若n个顶点的有向图有n(n-1)条边,称为有向完成图…

模型onnx转ncnn小记

前期准备 Netron 模型准备&#xff1a;onnx模型,这里使用模型face【det_10g.onnx】 大佬文档引用&#xff1a;手工优化ncnn模型结构 - 知乎 ncnn算子描述参考&#xff1a;ncnn 算子操作描述-CSDN博客 模型优化 安装 pip install onnx-simplifier 先把我要转的模型优化合…

extern关键字的使用。keil中编译时,出现error:identifier xxx is undefined

问题 编译时&#xff0c;出现error&#xff1a; identifier “Reg_Flag” is undefined extern Reg_Flag reg_flag; 很奇怪&#xff0c;我明明已经定义了。无非就是定义是在extern的下面&#xff0c;会不会是这个原因&#xff1f; 解决 果然&#xff0c;把extern的部分放到…

类和对象test

一、初始化列表 引言&#xff1a; 虽然上述构造函数调用之后&#xff0c;对象中已经有了一个初始值&#xff0c;但是不能将其称为对对象中成员变量 的初始化&#xff0c;构造函数体中的语句只能将其称为赋初值&#xff0c;而不能称作初始化。因为初始化只能初始 化一次&#x…

[华为OD] C卷 田忌赛马 DFS 200

题目&#xff1a; 给定两个只包含数字的数组a, b,调整数组a里面数字的顺序&#xff0c;使得尽可能多的a[i] >b[i]。 数组a和b中的数字各不相同。 输出所有可以达到最优结果的a数组的数量 输入描述 输入的第一行是数组a中的数字&#xff0c;其中只包含数字&#xff0c;每…

网页主题自动适配:网页跟随系统自动切换主题

主题切换是网站设计中一个非常有趣的功能&#xff0c;它允许用户在多种预先设计的样式之间轻松切换&#xff0c;以改变网站的视觉表现。最常见的就是白天和黑夜主题的切换&#xff0c;用户可以根据自己的喜好进行设置。 除了让用户手动去切换主题外&#xff0c;如果能够让用户第…

2024年3月份宠物行业线上市场数据分析:市场呈现出精细化、品质化趋势

近些年来&#xff0c;养宠物的家庭越来越多&#xff0c;宠物经济也逐渐衍生开来。宠物经济主要是围绕宠物产生的一整条产业链&#xff0c;包括宠物食品、宠物家居、宠物美容和最近火起来的宠物保险等多个领域。目前随着居民人均收入的提高&#xff0c;宠物市场也得到稳步发展。…

PC端网页特效异读

pc网页特效 一、三大系列1.元素偏移量&#xff08;offset系列&#xff09;&#xff08;1&#xff09;一些属性&#xff08;2).offset和style的区别(3).一些例子 2.元素可视区(client系列&#xff09;(1).一些属性(2).flexible.js源码分析 3.scroll系列(4).三大系列小结 其他&am…

YOLOv9改进策略 | 添加注意力篇 | 一文带你改进GAM、CBAM、CA、ECA等通道注意力机制和多头注意力机制

一、本文介绍 这篇文章给大家带来的改进机制是一个汇总篇&#xff0c;包含一些简单的注意力机制&#xff0c;本来一直不想发这些内容的&#xff08;网上教程太多了&#xff0c;发出来增加文章数量也没什么意义&#xff09;&#xff0c;但是群内的读者很多都问我这些机制所以单…

雷伴品鉴【神农式】倪琴 倪诗韵古琴

雷伴品鉴【神农式】倪琴 倪诗韵古琴 此琴材质为老杉木音色细腻&#xff0c;下指按弹舒适&#xff0c;手感极好漆面精美&#xff0c;线条流畅。

一文搞懂 ARM 64 系列: ADC

1 指令语法 adc <Xd>, <Xn>, <Xm> 2 指令语义 adc就是带「进位」加法&#xff0c;指令中的c就是英文carry。 整个指令等价于: (Xd, _) Xn Xm PSTATE.C 也就是将寄存器Xn&#xff0c;寄存器Xm&#xff0c;PSTATE中的「进位」标志相加&#xff0c;将相加的…

元素设置 flex:1,但是会被内部长单词宽度超出拉伸

初始布局如上图&#xff0c;left中是代码编辑器&#xff0c;实际上是个文本域&#xff0c;当输入长文本过长时&#xff0c;left宽度会被拉伸。 右侧容器被挤压。 解决方案&#xff1a;width&#xff1a;0&#xff1b; .left{flex:1; width:0} 当输入长文本过长时&#xff0c…