扩展板数码管驱动移植

1.实验原理

打开扩展板原理图对照扩展板可以看到扩展板上四位数码管原理图如下:

由图中可以确定数码管为共阴极数码管, DS_A DS_B DS_C DS_D DS_E DS_F 、 DS_G、 DS_DP 分别对应数码管的每个段,对应管脚为高电平时对应的部位会被电量,因为只有一组数据信号,但是有四个数码管,所以需要通过控制 DS_G1 DS_G2 DS_G3 和DS_G4 选择某个数码管显示内容,然后通过轮询刷新让四个数码管正常显示。

 

M74HC595 是一个传入并出的移位寄存器,如果有多个芯片级联也可串行输出控制下一 级芯片,QA~QH 为并行输出, QH’ 为串行输出;如果本例四个 LED 数码管由两个M74HC595 控制,第一级控制数码管显示什么,第二级控制哪个数码管显示。
数码管显示码

数码管控制码所以当需要第 2个数码管显示 8时,只需要通过 SER连续输入 02 7F两个字节数据即可。

原理图中 RCLK SRCLK SER 分别和 STM32MP157 SPI4_NSS SPI4_CLK、 SPI4_MOSI 连接, 74HC595 芯片手册中对于 RCLK SRCLK SER 的描述为:

SPI NSSCLKMOSI 描述为: 根据上述描述在编写驱动是可以通过 GPIO 模拟 74HC595 的时钟完成控制,因为 74H595 时序和 SPI 时序兼容,所以也可通过 SPI 控制器控制 74HC595

 查看芯片手册,管脚对应关系如下:

 2.实验步骤

1) 导入交叉编译工具链

linux@ubuntu:$ source /opt/st/stm32mp1/3.1-openstlinux-5.4-dunfell-mp1-20-06-24/environment-setup-cortexa7t2hf-neon-vfpv4-ostl-linux-gnueabi

2) 内核配置

74HC595 非标准 SPI 设备,且内核并没有其驱动,本节移植 spidev 通用驱动,然后通过应用程序驱动 74HC595
内核中有 STM32MP1 SPI 控制器标准驱动及 spidevi 驱动,只要在内核中配置对应选项即可,驱动路径为:
drivers/spi/spi-stm32.c
drivers/spi/spidev.c
执行 make menuconfig 配置内核对应选项
linux@ubuntu:$ make menuconfig
Device Drivers --->
        [*] SPI support --->
                <*> STMicroelectronics STM32 SPI controller
                <*> User mode SPI device driver support

3) 修改设备树

参考 linux 内核文档:
Documentation/devicetree/bindings/spi/spi-stm32.txt
修改设备树文件:
arch/arm/boot/dts/stm32mp157a-fsmp1a-extended.dts
由于 spi4 相关内容在 stm32mp151.dtsi 中已完成定义,这里需要在原有基础添加与硬件对应的相关信息,在文件 stm32mp157a-fsmp1a-extended.dts 末尾集成并添加 spi4 相关内容:
&spi4 {
    pinctrl-names = "default", "sleep";
    pinctrl-0 = <&spi4_pins_a>;
    pinctrl-1 = <&spi4_sleep_pins_a>;
    cs-gpios = <&gpioe 11 0>;
    status = "okay";
    m74hc595: m74hc595@0 {
        compatible = "ge,achc";
        reg = <0>;
        spi-max-frequency = <100000>;
    };
};

4) 重新编译内核和设备树文件

linux@ubuntu:$ make -j4 uImage dtbs LOADADDR=0xC2000040

5) 更新系统内核和设备树

6) 测试

系统启动后可以查看目录 /dev/
root@fsmp1a:~# ls /dev/spidev*
/dev/spidev0.0
如果系统中有多个 spidev 设备,这里可能会有很多个 spidev 设备,确定哪个文件是我们 的设备对应文件,可以通过查看/sys/bus/spi/devices/spi*/of_node/name 信息确认:
root@fsmp1a:~# cat /sys/bus/spi/devices/spi*/of_node/name
m74hc595
* 号代表当前目录下所有设备,由显示信息可以确认 spidev0.0 是当前设备。

7) 编写测试程序测试

spi_test.c
#include <stdint.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/types.h>
#include <linux/spi/spidev.h>

#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))

static void pabort(const char *s)
{
    perror(s);
    abort();
}

static const char *device = "/dev/spidev0.0";
static uint8_t mode;
static uint8_t bits = 8;
static uint32_t speed = 400000;
static uint16_t delay = 0;

int main(int argc, char *argv[])
{
    int ret = 0;
    int fd;

    if (argc != 2) {
        printf("usage: %s <device-file>\n", argv[0]);
        return 1;
    }

    fd = open(device, O_RDWR); //打开设备文件
    if (fd < 0)
    pabort("can't open device");

    /*
    * spi mode //设置 spi 设备模式
    */
    ret = ioctl(fd, SPI_IOC_WR_MODE, &mode); //写模式
    if (ret == -1)
    pabort("can't set spi mode");

    /*
    * bits per word //设置每个字含多少位
    */
    ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits); //写每个字含多少位
    if (ret == -1)
    pabort("can't set bits per word");

    /*
    * max speed hz //设置速率
    */
    ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed); //写速率
    if (ret == -1)
    pabort("can't set max speed hz");

    //打印模式,每字多少位和速率信息
    printf("spi mode: %d\n", mode);
    printf("bits per word: %d\n", bits);
    printf("max speed: %d Hz (%d KHz)\n", speed, speed/1000);

    //transfer(fd); //传输测试
    int i = 0;
    unsigned char num[20] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07,
                             0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71};
    int pos = 0;
    unsigned char buf[2];
   
    while(1) {
        pos = 1 << (i % 4);
        buf[0] = pos;
        buf[1] = num[i];
        if (write(fd, buf, 2) < 0)
            perror("write");
        i++;
        if (i == 4) {
            i = 0;
        }
        usleep(3000);
    }

    return ret;
}
交叉编译测试程序并将编译好的测试程序下载到板子上,执行程序如下,观察数码管状态:
root@fsmp1a:~# ./spi_test /dev/spidev0.0
spi mode: 0
bits per word: 8
max speed: 400000 Hz (400 KHz)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小徐的记事本

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值