【linux-IMX6ULL配置GPIO通用流程-以及时钟配置】

news2024/12/29 8:42:22

目录

  • 1. GPIO模式控制流程
    • 1.1 LED、蜂鸣器、按键
    • 1.2 GPIO控制流程
  • 2. 标准库的简要分析及实现:
    • 2.1 问题引入:
    • 2.2 代码实现:
  • 3. 时钟配置总结:
    • 3.1 时钟树概要:
    • 3.2 IMX6ULL时钟概要及时钟树:
    • 3.3 IMX6ULL时钟配置代码:

1. GPIO模式控制流程

1.1 LED、蜂鸣器、按键

  这些功能的实现都是利用了引脚的GPIO模式,通过GPIO模式进行引脚配置输出或者输入,进而实现LED、蜂鸣器、按键,的功能

1.2 GPIO控制流程

  核心配置思路如下:引脚X->寄存器A->寄存器A1->寄存器B(伪寄存器)

  • 引脚X:顾名思义,看得见,摸得着的物理引脚,一个引脚可以配置成多个模式,X可取范围是1-32,因为这个芯片是32位的,一个寄存器最多能控制32个引脚的输入和输出;
  • 寄存器A:例如对于引脚X,那么我如何把这个引脚配置成我想要的模式呢?例如配置成GPIO模式,答案就是通过寄存器A,也就是IOMUXC_SW_MUX_CTL_PAD_GPIO1_X寄存器,每个引脚都有对应的寄存器A,通过配置寄存器A来确定GPIO的工作模式
  • 寄存器A1:A和A1是一一映射的,一个引脚确定了模式,下一步就是配置电气属性,因此寄存器A1就是配置电气属性的,例如确定了GPIO的工作模式,下一步就是配置这个引脚的电气属性:就是通过寄存器A1来配置的,在数据手册中也叫:IOMUXC_SW_PAD_CTL_PAD_GPIO1_X
  • 寄存器B:引脚确定了模式和电器属性,那么下一步就是确定这个模式下如何进行工作,例如上面确定了GPIO(通用输入输出模式)那么下一步就是配置寄存器B(GPIO寄存器)进行输入或者输出、上下拉、保持、速度等功能的配置
  • 思路如下图:

2. 标准库的简要分析及实现:

2.1 问题引入:

  仔细观察一下,对于以下数据手册中引脚的寄存器地址分布,是不是每个引脚之间的寄存器地址都差4。所以知道了GPIO1_DR的地址后,剩下的寄存器地址我们都可以推出来,因此可以把这一类的寄存器放在一个结构体中,因为结构体存储数据是可以按照等字节连续存储,如何把结构体中的第一个值的地址宏定义一下,那么结构体中的其他寄存器的地址自动获得
在这里插入图片描述

2.2 代码实现:

 &emsp注意,代码把地址强制转换成了结构体指针,因为物理硬件地址不会发生变化,在一些底层的硬件编程中,需要直接访问特定的硬件寄存器。通过将寄存器的地址定义为一个结构体指针,可以方便地进行访问和操作。

//定义结构体中的首地址,那么结构体中的其他寄存器的地址自动获得
#define GPIO1_BASE                  (0x0209C000)
#define GPIO2_BASE                  (0x020A0000)
#define GPIO3_BASE                  (0x020A4000)
#define GPIO4_BASE                  (0x020A8000)
#define GPIO5_BASE                  (0x020AC000)


typedef struct 
{
	volatile unsigned int DR;							
	volatile unsigned int GDIR; 							
	volatile unsigned int PSR;								
	volatile unsigned int ICR1; 							
	volatile unsigned int ICR2; 							 
	volatile unsigned int IMR;								 
	volatile unsigned int ISR;			
	volatile unsigned int EDGE_SEL;  
}GPIO_Type;

#define GPIO1				((GPIO_Type *)GPIO1_BASE)//注意,这里把地址强制转换成了结构体指针,
                                                      //因为物理硬件地址不会发生变化
//在一些底层的硬件编程中,需要直接访问特定的硬件寄存器。
//通过将寄存器的地址定义为一个结构体指针,可以方便地进行访问和操作。
#define GPIO2				((GPIO_Type *)GPIO2_BASE)
#define GPIO3				((GPIO_Type *)GPIO3_BASE)
#define GPIO4				((GPIO_Type *)GPIO4_BASE)
#define GPIO5				((GPIO_Type *)GPIO5_BASE)

  以上就是一个简单的标准库的实现,其实可以把整个模块都按照这样的形式写出来,例如,IO口寄存器,GPIO,USART,CLOCK,等等

3. 时钟配置总结:

3.1 时钟树概要:

  对于每款MCU都有专有的时钟路线,但是这些芯片有共同点,那就是时钟树,时钟树的根就是外部的晶振,通过对外部晶振的倍频和分频可以得到几大主干道,也就是时钟树的枝干,而通过这些枝干在进行分频和倍频可以得到各个外设需要的时钟。

3.2 IMX6ULL时钟概要及时钟树:

  IMX6ULL大体上有7个PLL和8个PFD时钟总线,其余的大都是从这些时钟总线上分频得到的;其中PLL1作为ARM内核的时钟总线,是要首先进行初始化的,初始化过程中注意点ARM时钟切换频率时要先进行时钟的转接,换好后再把系统时钟接回来;配置ARM时钟时主要参考图如下:
在这里插入图片描述
  配置其他时钟主要参考是时钟树,IMX6ULL时钟树部分截图:注意时钟树中黄色的是寄存器对选择器的配置,红色的是寄存器对分频器的的控制,分频过程中注意不要直接清零,清零代表不分频,可能时钟频率会超出下线的承受范围导致板子卡死,注意有的分频过后要进行握手检测,也就是握手换频率不用关时钟,关时钟换频率不用握手;
在这里插入图片描述

3.3 IMX6ULL时钟配置代码:

#include "bsp_clk.h"
/*使能外设时钟*/
void clk_enable(void)
{
    CCM->CCGR0 = 0xFFFFFFFF;
    CCM->CCGR1 = 0xFFFFFFFF;
    CCM->CCGR2 = 0xFFFFFFFF;
    CCM->CCGR3 = 0xFFFFFFFF;
    CCM->CCGR4 = 0xFFFFFFFF;
    CCM->CCGR5 = 0xFFFFFFFF;
    CCM->CCGR6 = 0xFFFFFFFF;
}

/*初始化时钟*/
void imx6u_clkinit(void)
{
    unsigned int reg=0;
    /*初始化6u的主频为528MHz*/
    if((((CCM->CCSR)>>2) & 0x1)==0)  /*当前时钟使用的是pll1_main_clk,也就是pll1,要进行时钟切换*/
    {
        CCM->CCSR &= ~(1<<8);/*设置step_clk=osc_clk=24MHz*/
        CCM->CCSR |= (1<<2);/*pll1_main_clk=step_clk=24MHz*/
    }
    /*系统时钟切换已经设置好了,下一步就是设置PLL1=1056MHz,根据公式设置DIV_SELECT这八位为88,且使能*/
    CCM_ANALOG->PLL_ARM = ((1<<13)|((88<<0) & 0x7f));
    CCM->CACRR = 1;/*设置二分频*/
    /*现在设置好了时钟,下一步就是把时钟切换回来*/
    CCM->CCSR &= ~(1<<2);/*把这一位PLL1_SW_CLK_SEL清零就行,切换回来了,设置pll1_main_clk=1056MHz*/
    /*二位选择器,通过PLL1_SW_CLK_SEL=0/1来进行选择时钟频率*/

    /*设置PL2的4路PFD*/
    reg=CCM_ANALOG->PFD_528;
    reg &=~(0x3f3f3f3f);
    reg |=(32<<24);             /*初始化PLL2_PFD3=297MHz,利用公式的得到:*/
    reg |=(24<<16);             /*初始化PLL2_PFD2=396MHz,利用公式的得到:*/
    reg |=(16<<8);              /*初始化PLL2_PFD1=594MHz,利用公式的得到:*/
    reg |=(27<<0);              /*初始化PLL2_PFD0=352MHz,利用公式的得到:*/
    CCM_ANALOG->PFD_528=reg;    /*设置完毕*/

     /*设置PL3的4路PFD*/
    reg=0;
    reg=CCM_ANALOG->PFD_480;
    reg &=~(0x3f3f3f3f);
    reg |=(19<<24);              /*初始化PLL3_PFD3=454.7MHz,利用公式的得到:*/
    reg |=(17<<16);              /*初始化PLL3_PFD2=508.2MHz,利用公式的得到:*/
    reg |=(16<<8);               /*初始化PLL3_PFD1=540MHz,利用公式的得到:*/
    reg |=(12<<0);               /*初始化PLL3_PFD0=720MHz,利用公式的得到:*/
    CCM_ANALOG->PFD_480=reg;     /*设置完毕*/

    /*设置AHB_CLK_ROOT=132MHZ*/
    CCM->CBCMR &= ~(3<<18);
    CCM->CBCMR |= (1<<18);//四路选择器选择时钟PLL2_PFD2,即设置:PRE_PERIPH_CLK_SEL=400M(396Mhz)
    /*设置第二个选择器,通过CBCDR寄存器进行设置*/
    CCM->CBCDR &= ~(1<<25);
    while (CCM->CDHIPR & (1<<5));  /*等待握手信号*/

    reg=0;
    reg= CCM->CBCDR;
    reg &= ~(7<<10);  //先清零,这里不能直接先 CCM->CBCDR &= ~(7<<10)清零,因为清零直接变成1分频,超过了132Mhz,直接死机
    reg |= (2<<10);   //在赋值3分频
    CCM->CBCDR=reg;
    while((CCM->CDHIPR >> 1) & (0x1));/*等待握手信号*/

   /*设置IPG_CLK_ROOT=66MHz*/
   /*通过设置CBCDR寄存器的IPG_PODF位实现*/
   reg=0;
   reg = CCM->CBCDR;
   reg &= ~(3<<8);
   reg |= (1<<8);
   CCM->CBCDR=reg; /*设置完毕*/


   /*设置PERCLK_CLK_ROOT时钟为66Mhz*/
   /*设置CSCMR1寄存器的PERCLK_CLK_SEL位为0(第六位),两路选择器选择进入66MHz*/
   CCM->CSCMR1 &= ~(1<<6); /*时钟源已经选择了IPG,可以对照着时钟树进行了解*/
   /*分频器不分频*/
   CCM->CSCMR1 &= ~(0x3f << 0);/*设置完毕,1分频,66MHZ*/


}

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

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

相关文章

Spring Boot | Spring Boot 消息管理 ( 消息中间件 ) 、RabbitMQ“消息中间件“

目录: 一、"消息服务" 概述 :1.1 为什么要使用 "消息服务" ( 消息中间件 ) &#xff1f;① 异步处理② 应用解耦③ 流量削峰④ 分布式事务管理 1.2 常用 "消息中间件" 介绍 :ActiveMQ ( 广泛应用于中小型企业 )RabbitMQ ( 没有特别要求的场景下…

XBoot:基于Spring Boot 2.x的一站式前后端分离快速开发平台

XBoot&#xff1a;基于Spring Boot 2.x的一站式前后端分离快速开发平台 摘要 随着信息技术的迅速发展&#xff0c;快速构建高质量、高可靠性的企业级应用成为了迫切需求。XBoot&#xff0c;作为一个基于Spring Boot 2.x的一站式前后端分离快速开发平台&#xff0c;通过整合微信…

CSS选择器、字体文本属性、三大特性、盒子模型等

目录 导入css简介HTML的局限性CSS-网页美化CSS语法规范CSS代码风格 选择器基础选择器复合选择器 CSS字体属性字体系列字体大小字体粗细文字样式字体复合属性 CSS文本属性文本颜色对齐文本装饰文本文本缩进行间距(即行高) CSS的引入方式emmet语法元素显示模式什么是&#xff1f;…

百度下拉框负面信息如何删除?

百度头条360等搜索引擎&#xff0c;作为人们获取信息的主要途径之一。然而&#xff0c;一些知名的企业或个人可能会面临在搜索的下拉框中出现负面信息的问题&#xff0c;这可能对其声誉和形象造成不良影响。小马识途营销顾问根据自身从业经验&#xff0c;针对这类情况提出以下建…

【R语言】描述性数据分析与数据可视化

我们处理的变量可以分为两类&#xff0c;一类是连续型变量&#xff0c;另一类叫做分类型变量&#xff0c;其中对于连续型变量&#xff0c;如果服从正态分布就用平均值填充NA&#xff0c;不服从正态分布就用中位数填充NA&#xff0c;对于分类型变量&#xff0c;不管是有序的&…

记服务器被挖矿的一次排查

1、top 查看进程使用情况&#xff0c;进程名为 kswapd0 用了180%的CPU&#xff0c;我的机器是2C的&#xff0c;所以基本上算是吃掉了所有的CPU资源&#xff0c;很明显罪魁祸首就是它。 2、执行命令 netstat -antlp | grep kswapd0 查询该进程的网络信息&#xff0c;发现一个与…

漫谈音频深度伪造技术

作为人工智能时代的新型媒体合成技术&#xff0c;深度伪造技术近年来在网络媒体中的涉及领域越发广泛、出现频次越发频繁。据路透社报道&#xff0c;2023年&#xff0c;社交媒体网站上发布50万个深度伪造的语音和视频。 1、深度伪造技术的五个方面 音频深度伪造技术&#xff…

Unity 性能优化之静态批处理(三)

提示&#xff1a;仅供参考&#xff0c;有误之处&#xff0c;麻烦大佬指出&#xff0c;不胜感激&#xff01; 文章目录 前言一、静态批处理是什么&#xff1f;二、使用步骤1.勾选Static Batching2.测试静态合批效果 三、静态合批得限制1、游戏对象处于激活状态。2、游戏对象有一…

tomcat+maven+java+mysql图书管理系统1-配置项目环境

目录 一、软件版本 二、具体步骤 一、软件版本 idea2022.2.1 maven是idea自带不用另外下载 tomcat8.5.99 Javajdk17 二、具体步骤 1.新建项目 稍等一会&#xff0c;创建成功如下图所示&#xff0c;主要看左方目录相同不。 给maven配置国外镜像 在左上…

前端工程化06-JavaScript模块化CommonJS规范ES Module

7、JavaScript模块化 在js开发中&#xff0c;他并没有拆分的概念&#xff0c;并不像java一样他可以拆分很多的包&#xff0c;很多的类&#xff0c;像搭积木一样完成一个大型项目的开发&#xff0c;所以js在前期的时候并不适合大型后端的项目开发&#xff0c;但是这些问题在后来…

16_Scala面向对象编程_函数

文章目录 1.声明Scala函数2.访问伴生对象3.空对象直接用的方法4.构造对象--通过object获取单例对象--直接new--scala独有apply()方式--scala有参构造--scala构造方法两大类使用辅构造如下上述代码主构造为辅助构造方法甚至可以多个多个辅助构造形参内容不能重不使用辅助构造和使…

Linux文件类型及目录和文件的权限

一、Linux 文件类型 1、Windows文件类型 2、Linux文件类型 1普通文件类型 Linux 中最多的一种文件类型, 包括 纯文本文件(ASCII)&#xff1b;二进制文件(binary)&#xff1b;数据 格式的文件(data);各种压缩文件.第一个属性为 - 2目录文件 就是目录&#xff0c; 能用 # cd 命…

【微服务】服务保护(通过Sentinel解决雪崩问题)

Sentinel解决雪崩问题 雪崩问题服务保护方案服务降级保护 服务保护技术SentinelFallback服务熔断 雪崩问题 在微服务调用链中如果有一个服务的问题导致整条链上的服务都不可用&#xff0c;称为雪崩 原因 微服务之间的相互调用&#xff0c;服务提供者出现故障服务的消费者没有…

Unity 热更--AssetBundle学习笔记 1.0【AB包资源加载工具类的实现】

合集 - Unity学习笔记(13)1.Unity学习笔记–基础2023-11-012.Unity学习笔记–入门2023-10-293.Unity学习笔记–数据持久化之PlayerPrefs的使用2023-11-194.Unity学习笔记–数据持久化XML文件(1)2023-11-205.Unity学习笔记–数据持久化XML文件&#xff08;2&#xff09;2023-12-…

ADS基础教程8-仿真库加载

目录 一、系统库介绍二、厂商库1.模型下载1&#xff09;登录官网2&#xff09;选择所需模型3&#xff09;点击下载4&#xff09;指定保存路径 二.模型加载1&#xff09;设计套件选择2&#xff09;选择解压文件3&#xff09;解压文件成功4&#xff09;添加到当前workspace5&…

在STM32中用寄存器方式点亮流水灯

文章目录 实验资料一、对寄存器的理解1.通俗认识寄存器2.深入了解寄存器&#xff08;1&#xff09;端口配置低寄存器&#xff08;配置0到7引脚的寄存器&#xff09;&#xff08;2&#xff09;端口配置高寄存器&#xff08;配置8到15引脚&#xff09; 3.GPIO口的功能描述 二、配…

在线协作,开源的设计和原型创作平台:penpot

penpot&#xff1a;面向团队&#xff0c;设计自由- 精选真开源&#xff0c;释放新价值。 概览 Penpot 是一款专为跨职能团队量身定制的开源设计软件&#xff0c;与行业领先的 Figma 齐名&#xff0c;提供了一个强大而灵活的在线设计解决方案。其最大的亮点在于&#xff0c;用户…

五一假期零碎时间练习学习过的内容(商城版)

目录 1 总览1.1 技术架构1.2 其他1.2.1 数据库1.2.2 后端部分1.2.2.1 复习feign1.2.2.2 复习下网关网关的核心功能特性&#xff1a;网关路由的流程断言工厂过滤器工厂全局过滤器 过滤器执行顺序解决跨域问题 1.2.2.3 es部分复习 1.2.3 前端部分 2 day1 配置网关2.1 任务2.2 网关…

5.3 调制与解调

信号的调制与解调是通信系统中一对基本的概念&#xff0c;涉及将信息&#xff08;语音、视频、数据等&#xff09;在发送之前进行处理以便在传输介质&#xff08;如无线电波、电话线等&#xff09;上有效传输&#xff0c;以及在接收端恢复这些信息的过程。 一、调制&#xff0…

Java | Leetcode Java题解之第60题排列序列

题目&#xff1a; 题解&#xff1a; class Solution {public String getPermutation(int n, int k) {int[] factorial new int[n];factorial[0] 1;for (int i 1; i < n; i) {factorial[i] factorial[i - 1] * i;}--k;StringBuffer ans new StringBuffer();int[] valid…