海思芯片上GPIO和PWM操作

2023-11-02

一、GPIO的配置

    GPIO的设置一般为三步:1 设置gpio端口复用、2 设置GPIO口的方向、3 读取或者写入GPIO值;第一步不是每个GPIO口都是要配置的,如果你设置的GPIO端口有复用功能,那么你需要对GPIO对应复用寄存器进行配置,例如:文档中GPIO5_5是有复用功能的,0:PWM_OUT0  ; 1:GPIO5_5,所以把复用寄存器设置为1就是表示为GPIO5_5;但有些GPIO端口是没有复用功能的,例如GPIO0_0,这个就不需要复用寄存器的设置;

1、设置gpio端口复用

     所谓复用,就是指一个端口能同时干很多事,但是具体你要求他干啥,是需要设置的,这就是管脚复用寄存器的作用。
举个例子,如果我们想设置GPIO5_5,需要首先找到对应的管脚复用寄存器地址;通过手册查询,如果你想让这个管脚作为io口使用,需要给复用控制寄存器muxctrl_reg54这个寄存器里写0x01;管脚复用寄存器的基地址为0x120f_0000,muxctrl_reg54的偏移地址0xD8,所以这个寄存器的地址为0x120f00D8;

通过HIS自带的himm命令输入以下即可:
himm 0x120F00D8 0x01;

     这样GPIO5_5对应管脚的功能就设置为了IO口,还有一个问题需要注意:在设置寄存器的时候要查看该寄存器其他bit位的作用,不要盲目的直接设置你需要设置的bit位,可能会其他bit给清除了,所以最好的做法是先读出寄存器的值,然后或上设置的位的值,再设置寄存器,这样就不会改变其他bit位的值;

                                     

 

                                  

2 设置GPIO口的方向

    所谓方向,就是你是把io做输入用还是输出用。比如如果你的板子外接了个电池模块,你希望电池模块在没电的时候,能够给你的板子一个信号,告诉你没电了,这时你就需要将io口作为输入使用。反过来,如果你需要告诉外接的什么设备什么事情,那就要将io口做输出,设置GPIO口的方向,实际上就是写 GPIO_DIR寄存器。同样的,首先需要找地址,对于GPIO5的基地址为:0x121A_0000;GPIO_DIR的偏移地址为0x400,得到GPIO5_5的寄存器地址为0x121A_0400;然后GPIO_DIR寄存器里有8位,每一位对应一个GPIO的方向,如果你想把GPIO5_5的方向设为输出,则需要把BIT5置1;

输入命令:himm  0x121A0400  0x20(二进制 0010 0000)

                                         

                                  

3 读取或者写入GPIO值

    GPIO_DATA为GPIO数据寄存器,用来对输入或输出数据进行缓存;当配置GPIO_DIR中对应位为输出时,写入GPIO_DATA 寄存器的值将会输出到相应的管脚(注意需要配置正确的管脚复用);如果配置为输入时,将会读取相应输入管脚的值。

注意:当GPIO_DIR相应的比特配置为输入时,有效读取的结果将返回管脚的值;当配置为输出的时候,有效读取的结果将返回写入的值。GPIO_DATA 寄存器利用PADDR[9:2]实现了读写寄存器比特的屏蔽操作。该寄存器对应256个地址空间。PADDR[9:2]分别对应GPIO_DATA[7:0],当相应的bit 为高时,则可以对相应的位进行读写操作;反之,若对应bit 为低则不能进行操作。

例如:
若地址为0x3FC(0b11_1111_1100),则对GPIO_DATA[7:0]这8bit 操作全部有效。
若地址为0x200(0b10_0000_0000),则仅对GPIO_DATA[7]的操作有效。

同样的,首先需要找地址,对于GPIO5的基地址为:0x121A_0000;GPIO_DATA 的偏移地址为0x3FC,得到GPIO5_5的寄存器地址为0x121A_03FC,如果你想把GPIO5_5写入值为1时,则需要把BIT5置1;

输入命令:himm 0x121A03FC 0x20(二进制 0010 0000)

                               

二、PWM 管脚配置
    上面也说了,对于gpio端口复用功能,可以通过配置复用寄存器muxctrl_reg54,把这个gpio端口配置为PWM_OUT0的功能,配置为PWM管脚功能的歩聚:1、配置gpio复用;2、设置CORE PWM 参数;3、使能CORE 对应的PWM;

1、配置gpio复用

按照上面说明,只需要把muxctrl_reg54复用寄存器配置为0,即为PWM_OUT0功能,

执行命令:himm 0x120F00D8 0x00

2、设置CORE PWM 参数

根据所需的PWM 输出频率和占空比,计算出对应的PWM 计数周期数和高电平计数值。
计数周期数计算公式为:
    pwm_ period = (24000000 / Freq) −1
高电平计数值计算公式为:
    pwm_ duty = (24000000/ Freq)*duty −1

例如,芯片CORE电源调压控制由PWM0信号控制,如果需要PWM0 输出频率为
200KHz, 占空比为75%,配置步骤如下:

Pwm_period=(24000000/200000)-1 = 119
Pwm_duty=(24000000/200000) x 0.75-1=89

设置CORE PWM 参数:设置PERI_PMC0 [15:0]=0x77, PERI_PMC0 [31:16]=0x59;

PCM的基地址为0x120E_0000,PERI_PMC0的偏移地址:0x0000

执行命令: himm 0x120E0000  0x00590077

                           

3、使能CORE 对应的PWM

使能CORE 对应的PWM: 设置PERI_PMC4 [0]=1;

PCM的基地址为0x120E_0000,PERI_PMC4的偏移地址:0x0010

执行命令:himm 0x120E0010 0x01

PERI_PMC4

                                          

                             

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

海思芯片上GPIO和PWM操作 的相关文章

  • Windows下appcontainer进程和普通进程之间有ipc的方式吗?

    我正在尝试在 Windows 中的 appcontainer 进程和普通进程之间建立 ipc 我在Windows appcontainer中做了一个进程 感谢这个article https www malwaretech com 2015
  • 多进程之Binder的意外死亡及权限校验

    Android多进程系列 Android 多进程通讯之几个基本问题 Android多进程之Binder的使用 Android多进程之手动编写Binder类 Android多进程之Binder解绑监听的问题 Android 多进程之Messe
  • 使用匿名binder实现client向server端的死亡通知

    一 引言 因为binder是跨进程通信 难免会遇到服务端出现异常挂死的情况 这个时候需要通知到客户端进行相应的处理 在网络通信中是非常常见的机制 当然 在binder中 Android也为我们写好了相关的框架 但通过binder源码分析 你
  • IBinder 解析

    远程对象的基础接口 是一个为了在执行进程中和进程间调用时的高性能 而设计的轻量级 远程调用 机制的核心部分 这个接口描述了和远程对象交互的抽象协议 不要直接实现这个接口 而是通过继承 Binder 来实现 IBinder的关键 API 是与
  • 信号会通过哪些方式干扰管道通信?

    我对信号一无所知 对管道也只有一点了解 从评论来看zdim s在这里回答 https stackoverflow com questions 48558093看来信号可能会干扰父进程和子进程之间的管道通信 有人告诉我 如果你使用IO Sel
  • C++ 和 Java 之间的低延迟 IPC

    对于以下情况 实现 C Java IPC 的最佳方法是什么 最近有人问类似的问题 https stackoverflow com questions 5900887 ipc between java and c applications 但
  • 是否可以像IPC一样使用Mac OS X XPC在进程之间交换消息?如何?

    据 Apple 介绍 Lion 中引入的新 XPC Services API 为与 Grand Central Dispatch GCD 和 launchd 集成的基本进程间通信提供了一种轻量级机制 似乎可以使用这个 API 作为一种 IP
  • 后台进程重定向到 COPROC

    在下面的测试脚本中 我运行一个基本协进程 echo内置 在后台运行 附加其标准输出 bin bash TEST 1 coproc bin sleep 100 echo gt COPROC 1 该脚本总是失败 没有明显的原因 给出输出 tes
  • PHP - 访问用 C++ 创建的共享内存

    几天以来 我一直在努力让以下事情发挥作用 我有一个微型 C 程序 它从串行端口连续读取一些数据 该数据存储在共享内存中 如下所示 HANDLE hMapFile hMapFile CreateFileMapping INVALID HAND
  • boost find in共享内存方法陷入c++多进程项目中

    我正在使用 boost 的 ipc 库来保存复杂的对象 包括图像 在共享内存中 由多个进程使用 我们称这个对象为MyImage 共享内存是一个循环缓冲区 保存了几个MyImage一次对象 在我的代码中 有两个 或更多 进程写入共享内存中的一
  • 有没有一种简单的方法可以清除C中的管道

    我有一个所有子进程都使用的管道 但在子进程使用该管道与父进程通信之前 我需要清除它 以便父进程正确读取它 C 中有一个简单的函数可以做到这一点吗 清除 管道的方法是从管道中读取数据 直到缓冲区为空 这对你没有帮助 我猜测您真正的问题是父级可
  • Java中如何通知特定线程

    如何在线程间通信中调用特定线程 在下面的程序中我有两个线程t1 and t2 当我打电话时t1 notify 它提出 Exception in thread Thread 1 java lang IllegalMonitorStateExc
  • 尝试使用 POSIX 消息队列创建消息队列时权限被拒绝

    我正在使用以下代码片段创建一个消息队列Linux 编程接口 http man7 org tlpi if mq open my message queue O CREAT O RDWR NULL 1 perror mq creation fa
  • 将参数发送到驻留在另一个进程中的应用程序实例

    我有一个单实例应用程序 c WPF net3 51 检查应用程序是否已实例化是通过互斥体完成的 如果应用程序已在运行 我会从已打开的应用程序实例中打开一个新窗口 到目前为止效果很好 但是 由于应用程序扩展 我现在必须将 e Args 或至少
  • 与修改后的 python 解释器进行进程间通信

    TL DR 当 stdin stdout 不可用时 如何生成不同的 python 解释器 从 python 内部 并在父级和子级之间创建通信通道 我希望我的 python 脚本执行修改后的Python解释器并通过某种IPC 例如multip
  • Windows服务之间如何通信

    我有 2 个使用 C 创建的 Windows 服务 我希望其中一个服务调用第二个 Windows 服务中的函数 我该怎么做呢 EDIT 问题是我必须运行该应用程序 我不需要它们 相反服务进程也很好 但我need这2个应用程序进行通信 这2个
  • 将文本插入另一个应用程序的文本框中

    如何使用 C 或 C 将文本插入另一个应用程序的文本框中 我很久以前就这样做过 似乎还记得一些有关使用应用程序 HWND 的事情 但由于应用程序的每个实例都发生了变化 我觉得我不记得完整的故事了 我是否可以以某种方式获取正在运行的应用程序的
  • 是否可以在由同一父进程创建的两个子进程之间建立管道(LINUX,POSIX)

    我有多个孩子由同一个父母 分叉 我尝试构建pipe所有这些子进程之间的连接就像一个链表结构 孩子 1 向孩子 2 发送数据 孩子 2 向孩子 3 孩子 N 向孩子 1 发送数据 有没有正确的方法可以做到这一点 此外 如果我在进程之间创建和通
  • 首选的跨平台 IPC Perl 模块是什么?

    我想创建一个简单的 IO 对象 它代表一个向另一个程序打开的管道 我可以在应用程序运行时定期写入另一个程序的 STDIN 我希望它是防弹的 因为它可以捕获所有错误 并且是跨平台的 我能找到的最佳选择是 open sub io read lo
  • 如何在同一设备上运行的 Android 应用程序之间传输文件?

    我正在编写一个与 RESTful 服务交互的 Android 应用程序 该 Web 服务本质上是一个文件系统 并提供元数据以及对文件的 CRUD 访问 我的应用程序检索元数据 并通过ContentProvider 我需要添加与我的应用程序在

随机推荐