F28335管脚分类+GPIO简介+点灯

F28335管脚分类+GPIO简介+点灯

  • 前言
  • 一、F28335管脚分类
  • 二、GPIO简介
    • 2.1 GPIO结构
      • 2.1.1 GPIO 数据寄存器
      • 2.2.2 GPIO 控制寄存器
        • **GPxCTRL**:GPIO控制寄存器
        • **GPxQSEL1/2**:GPIO量化控制寄存器1/2
        • **GPxMUX1/2** :GPIO复用选择寄存器1/2
        • **GPxDIR**:GPIO方向寄存器
        • **GPAPUD**寄存器控制引脚是否上拉;
      • 2.1.1 GPIO 中断源与低功耗唤醒源选择寄存器 _配合中断控制那块儿,还没学到
  • 三、点灯
  • 总结


前言

鲁迅曾经没说过:灯点亮就算入门


一、F28335管脚分类

详见F28335数据手册,2节Introduction.
F28335按其功能划分可分为以下几类(见2.1节 Signal Descriptions):

  • 电源引脚-CPU AND I/O POWER PINS
    包括:CPU and Logic Digital Power Pins、Digital I/O Power Pin、Digital Ground Pins

  • 晶振引脚-CLOCK

  • 复位引脚-RESET

  • 下载引脚-Jtag

  • BOOT引脚
    F28335启动方式如下,由BOOT引脚(GPIO84~87)电平逻辑控制:
    在这里插入图片描述
    开发板BOOT脚电路如下图,GPIO84~87脚均上拉到3.3v,通过MODE F(Flash)启动。

在这里插入图片描述

  • 普通引脚-GPIO AND PERIPHERAL SIGNALS

二、GPIO简介

详见 System Control and Interrupts ,.6节General-Purpose Input/Output (GPIO)

2.1 GPIO结构

GPIO时钟由SYSCLKOUT提供,其值等于CLKIN,在本例程中CLKIN为150MHz.
在这里插入图片描述
GPIO多路复用电路如下图所示(以GPIO0~27组为例):
在这里插入图片描述

2.1.1 GPIO 数据寄存器

  • GPxDAT: 存储输入模式PIN上电平逻辑(0/1),输出模式锁存器值(0/1)。防止直接修改数据寄存器使得同组I/O数据发生错误,就是这个32位的数据寄存器同时储存一组(A/B/C)I/O的电平逻辑值,无论是输入的还是输出的,当读入数据寄存器值->修改值->再写入的过程中,由于数据修改不是原子操作,如果有个别I/O口设置为输入且在你修改值还未写入的时候电平逻辑发生变化,那么对于该I/O口对应的寄存器位来说,准备写入值与当前值发生错误,emmm,毕竟是输入模式,再去读就对应不上了。输出模式尽量通过修改SET,CLEAR,TOGGLE寄存器进行操作,单bit或多位操作,不影响其它脚。
  • 在这里插入图片描述
  • GPxSET:写1拉高
  • GPxCLEAR:写1拉低
  • GPxTOGGLE:写1翻转
    A组I/O口的数据寄存器如下,每位对应一个I/O口:
struct GPIO_DATA_REGS {
...
   union  GPADAT_REG       GPADAT;       // GPIO Data Register (GPIO0 to 31)
   union  GPADAT_REG       GPASET;       // GPIO Data Set Register (GPIO0 to 31)
   union  GPADAT_REG       GPACLEAR;     // GPIO Data Clear Register (GPIO0 to 31)
   union  GPADAT_REG       GPATOGGLE;    // GPIO Data Toggle Register (GPIO0 to 31)
   ...
}   

2.2.2 GPIO 控制寄存器

A组I/O口的控制寄存器如下:

struct GPIO_CTRL_REGS {
...
   union  GPACTRL_REG  GPACTRL;   // GPIO A Control Register (GPIO0 to 31)
   union  GPA1_REG     GPAQSEL1;  // GPIO A Qualifier Select 1 Register (GPIO0 to 15)
   union  GPA2_REG     GPAQSEL2;  // GPIO A Qualifier Select 2 Register (GPIO16 to 31)
   union  GPA1_REG     GPAMUX1;   // GPIO A Mux 1 Register (GPIO0 to 15)
   union  GPA2_REG     GPAMUX2;   // GPIO A Mux 2 Register (GPIO16 to 31)
   union  GPADAT_REG   GPADIR;    // GPIO A Direction Register (GPIO0 to 31)
   union  GPADAT_REG   GPAPUD;    // GPIO A Pull Up Disable Register (GPIO0 to 31)
 ...
}
GPxCTRL:GPIO控制寄存器

控制采样周期,配合GPxQSEL1/2寄存器使用。GPxCTRL寄存器在配置为使用3或6个样本的窗口(具体是否使用采样窗口与进行3次或6次由GPxQSEL1/2控制)进行输入鉴定时指定输入引脚的采样周期。采样周期为SYSCLKOUT周期倍数,每个采样周期结束进行一次采样量化,具体采样量化数量在GPxQSEL 1/2寄存器指定。
例:GPACTRL寄存器如下,A组I/O口分为4部,根据Value控制采样周期,1~510*T(SYSCLKOUT)

在这里插入图片描述

  • 采样周期计算:

if:GPxCTRL[QUALPRDn] = 0 ,Sampling Period = 1 × TSYSCLKOUT
if: GPxCTRL[QUALPRDn] ≠ 0 , Sampling Period = 2×GPXCTRL[QUALPRDn] × TSYSCLKOUT
Where TSYSCLKOUT is the period in time of SYSCLKOUT;
例如:
在这里插入图片描述
在这里插入图片描述

GPxQSEL1/2:GPIO量化控制寄存器1/2

控制输入信号量化方式,下面这样。
在这里插入图片描述
三种输入量化方式:

  • 异步输入:用于不需要输入同步或外设本身执行同步的外设。例如通信端口SCI, SPI, eCAN、I2C和ePWM。如果引脚用作普通GPIO,则异步选项无效。如果引脚配置为GPIO输入,并且选择异步选项,则量化默认为同步到SYSCLKOUT。
  • 只同步到SYSCLKOUT
    与SYSCLKOUT进行同步采样,信号进来后需等到同步时钟的到达再进行采样量化,信号量化可能导致会延时一个SYSCLKOUT周期;
  • 使用采样窗口量化
    在这种模式下,信号首先被同步到系统时钟(SYSCLKOUT),然后在允许改变输入之前经过指定周期数的限定(在指定窗口时间内采样值不变),才认为该值可靠被采纳。下图显示了如何执行输入限定以消除不必要的噪声,需指定了两个参数:1)采样周期,2)采样的数量。

在这里插入图片描述

  • 采样窗口时间计算:

3次采样:
If GPxCTRL[QUALPRDn] = 0, Window Width = 2× TSYSCLKOUT
If GPxCTRL[QUALPRDn] ≠ 0, Window Width =2×2×GPXCTRL[QUALPRDn]×TSYSCLKOUT

6次采样:
If GPxCTRL[QUALPRDn] = 0, Window Width = 5× TSYSCLKOUT
If GPxCTRL[QUALPRDn] ≠ 0, Window Width =5×2×GPXCTRL[QUALPRDn]×TSYSCLKOUT
以下面例子为例:
1.某个I/O口,GPxQSEL值为 1,0,使用采样窗口,6次采样;GPXCTRL[QUALPRDn] = 1。那么:
采样周期为:
Sampling Period = 2×GPXCTRL[QUALPRDn] × TSYSCLKOUT
窗口时间为:
Window Width =5×2×GPxXCTRL[QUALPRDn]×TSYSCLKOUT
2.比如我的开发板,TSYSCLKOUT=TCLKIN=1/(150*106)=6.67ns。
那么: Sampling Period =13.34ns; Window Width =67ns;
3.最大检测延时:由于输入信号需要与SYSCLKOUT作同步,可能需要一个额外的采样周期,来检测输入信号的变化,最大的检测延时:Td = Sampling Period + TSYSCLKOUT
整体如下图所示:
在这里插入图片描述

GPxMUX1/2 :GPIO复用选择寄存器1/2

控制I/O口复用功能,通常每个I/O口可作为普通GPIO口或可选的3个外设端口之一。 在这里插入图片描述在这里插入图片描述
简略可查看GPIO外设复用选择矩阵,或者查看具体寄存器,其每两位控制一个I/O口,复位默认情况下为普通GPIO,即对应寄存器位为0,0;
例如数据手册中GPIOA的部分复用矩阵如下:
在这里插入图片描述
具体寄存器长这样,与上图GPIO15对应:
在这里插入图片描述

GPxDIR:GPIO方向寄存器

控制I/O口输入输出,写0输入,写1输出

在这里插入图片描述

GPAPUD寄存器控制引脚是否上拉;

-控制I/O是否上拉电阻
在这里插入图片描述

2.1.1 GPIO 中断源与低功耗唤醒源选择寄存器 _配合中断控制那块儿,还没学到

struct GPIO_INT_REGS {
   union  GPIOXINT_REG     GPIOXINT1SEL; // XINT1 GPIO Input Selection
   union  GPIOXINT_REG     GPIOXINT2SEL; // XINT2 GPIO Input Selection
   union  GPIOXINT_REG     GPIOXNMISEL;  // XNMI_Xint13 GPIO Input Selection
   union  GPIOXINT_REG     GPIOXINT3SEL; // XINT3 GPIO Input Selection
   union  GPIOXINT_REG     GPIOXINT4SEL; // XINT4 GPIO Input Selection
   union  GPIOXINT_REG     GPIOXINT5SEL; // XINT5 GPIO Input Selection
   union  GPIOXINT_REG     GPIOXINT6SEL; // XINT6 GPIO Input Selection
   union  GPIOXINT_REG     GPIOXINT7SEL; // XINT7 GPIO Input Selection
   union  GPADAT_REG       GPIOLPMSEL;   // Low power modes GP I/O input select
}; 

三、点灯

  1. 在之前的基础上,新建.c .h文件,条件头文件路径在这里插入图片描述在这里插入图片描述
  2. 敲代码
    .c
//LED初始化设置
 void LED_Init(void)
{
     EALLOW;                                    //关闭写保护
     SysCtrlRegs.PCLKCR3.bit.GPIOINENCLK = 1;   //开启GPIO时钟

     GpioCtrlRegs.GPBMUX2.bit.GPIO60 = 0;       //引脚设置为通用GPIO功能
     GpioCtrlRegs.GPBMUX2.bit.GPIO61 = 0;

     GpioCtrlRegs.GPBPUD.bit.GPIO60 = 0;        //设置GPIO有上拉电阻
     GpioCtrlRegs.GPBPUD.bit.GPIO61 = 0;

     GpioCtrlRegs.GPBDIR.bit.GPIO60 = 1;        //设置GPIO方向为输出
     GpioCtrlRegs.GPBDIR.bit.GPIO61 = 1;

     GpioDataRegs.GPBSET.bit.GPIO60 = 1;        //设置GPIO输出高电平
     GpioDataRegs.GPBSET.bit.GPIO61 = 0;        //设置GPIO输出低电平

     EDIS;                                      //开启写保护
}
 void LED_Toggle(void)
 {
     GpioDataRegs.GPBTOGGLE.bit.GPIO60 = 1;
     GpioDataRegs.GPBTOGGLE.bit.GPIO61 = 1;
 }

TI的DSP为了提高安全性能,将很多关键寄存器作了保护处理。通过状态寄存器1(ST1)的位6设置与复位,来决定是否允许DSP指令对关键寄存器进行操作。
可在System Control and Interrupts文件中查看具体哪些寄存器有写保护;
在这里插入图片描述
其实每个寄存器下边都会有说明的 This register is EALLOW protected.
在这里插入图片描述
DSP由于在上电复位时,会清除EALLOW位,使能EALLOW保护。在受保护时,CPU对受保护寄存器的所有写操作都会被忽略,只允许CPU读、JTAG读和JTAG写操作。如果通过执行EALLOW指令设置了该位,则允许CPU自由地向受保护的寄存器写入。在修改寄存器之后,可以通过执行EDIS指令来清除EALLOW位来再次保护它们。

   EALLOW;//关闭写保护
   GpioCtrlRegs.GPAMUX1.bit.GPIO4 = 0;
   EDIS;//开启写保护

.h

#ifndef APP_LEDS_LEDS_H_
#define APP_LEDS_LEDS_H_

void delay(void);//随便写一个拉
void LED_Init(void);
void LED_Toggle(void);
#endif /* APP_LEDS_LEDS_H_ */

and main 巴拉巴拉

#include "DSP2833x_Device.h"     // DSP2833x Headerfile Include File
#include "DSP2833x_Examples.h"   // DSP2833x Examples Include File
#include "leds.h"

void main(void)
{

   InitSysCtrl();

   LED_Init();
   for(;;)
   {
       delay();
       LED_Toggle();
   }
}

总结

点亮一个灯,啊不,两个

  • 26
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
PIO(General-Purpose Input/Output)——通用输入/输出口;       DSP28335 GPIO模块分为三类IO口:PORTA(0-31),PORTB(32-63),PORTC(64-87) 对GPIO模块的设置主要通过三类寄存器来完成,分别是:控制寄存器、数据寄存器、中断寄存器。 1、控制寄存器   GPxCTRL;    // GPIO x Control Register (GPIO0 to 31)               //设置采样窗周期T=2*GPXCTRL*Tsysclk;   GPxQSEL1;   // GPIO x Qualifier Select 1 Register (GPIO0 to 15)(32-47)               GPxQSEL2;   // GPIO x Qualifier Select 2 Register (GPIO16 to 31)(48-63)               //每两位控制一个引脚,确定是3周期采样还是6周期采样或者不用采样   GPxMUX1;    // GPIO x Mux 1 Register (GPIO0 to 15)(32-47)(64-79)   GPxMUX2;    // GPIO x Mux 2 Register (GPIO16 to 31)(48-63)(80-95)               //配置各个引脚的功能,0:I/O功能,1:外设功能。   GPxDIR;     // GPIO x Direction Register (GPIO0 to 31)(32-63)(64-95)               //配置每个引脚是输入还是输出,0:数字量输入;1:数字量输出。   GPxPUD;     // GPIO x Pull Up Disable Register (GPIO0 to 31)(32-63)(64-95)               //使能或禁止内部上拉 0:开启上拉,1:禁止上拉 2、数据寄存器   GPxDAT;     // GPIO Data Register (GPIO0 to 31)(32-63)(64-95)   GPxSET;     // GPIO Data Set Register (GPIO0 to 31)(32-63)(64-95)——置位   GPxCLEAR;   // GPIO Data Clear Register (GPIO0 to 31)(32-63)(64-95)   GPxTOGGLE;  // GPIO Data Toggle Register (GPIO0 to 31)(32-63)(64-95)—反转
下面是一个简单的Linux GPIO心跳点灯程序的示例: ```c #include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <unistd.h> #include <sys/mman.h> #define GPIO_BASE 0x3F200000 // 树莓派GPIO控制器的基地址 #define GPIO_LEN 0xB4 // 控制器的长度 // GPIO控制器的物理地址指针 volatile unsigned *gpio; // GPIO输出引脚号 #define GPIO_PIN 17 // 定义GPIO寄存器的偏移量 #define GPFSEL1 0x04 // GPIO功能寄存器1 #define GPSET0 0x1C // GPIO输出寄存器(置1) #define GPCLR0 0x28 // GPIO输出寄存器(清0) #define GPPUD 0x94 // GPIO上下拉寄存器 #define GPPUDCLK0 0x98 // GPIO上下拉时钟寄存器 // GPIO功能寄存器的模式(输出) #define GPIO_MODE_OUT 0b001 // 定义延时函数 void delay(int millis) { usleep(millis * 1000); } // 初始化GPIO控制器 void setupGPIO() { int fd = open("/dev/mem", O_RDWR | O_SYNC); if (fd < 0) { printf("无法打开/dev/mem,需要root权限运行\n"); exit(-1); } gpio = (unsigned *)mmap(NULL, GPIO_LEN, PROT_READ | PROT_WRITE, MAP_SHARED, fd, GPIO_BASE); close(fd); if (gpio == MAP_FAILED) { printf("mmap失败\n"); exit(-1); } } // 设置GPIO引脚功能模式 void setGPIOFunction(int pin, int mode) { int regnum = pin / 10; int offset = (pin % 10) * 3; unsigned mask = 0b111 << offset; gpio[GPFSEL1 + regnum] = (gpio[GPFSEL1 + regnum] & ~mask) | (mode << offset); } // 将GPIO引脚置为高电平 void setGPIOHigh(int pin) { gpio[GPSET0] = 1 << pin; } // 将GPIO引脚置为低电平 void setGPIOLow(int pin) { gpio[GPCLR0] = 1 << pin; } // 配置GPIO引脚的上下拉电阻 void setGPIOPullUpDown(int pin, int pud) { gpio[GPPUD] = pud; delay(1); gpio[GPPUDCLK0] = 1 << pin; delay(1); gpio[GPPUD] = 0; gpio[GPPUDCLK0] = 0; } int main() { setupGPIO(); setGPIOFunction(GPIO_PIN, GPIO_MODE_OUT); setGPIOPullUpDown(GPIO_PIN, 0); while (1) { setGPIOHigh(GPIO_PIN); delay(500); setGPIOLow(GPIO_PIN); delay(500); } return 0; } ``` 编译方法: ```bash gcc -o gpio-led gpio-led.c ``` 需要在root用户下运行,可以使用sudo命令执行。执行后,GPIO17引脚将会不停地闪烁。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值