2、恩智浦-车规级-MCU :S32K11X GPIO实验

2、恩智浦 车规级 MCU S32K11X:GPIO实验

1、GPIO 简介

S32K11X系列芯片总共有五个GPIO口,GPIOAGPIOE(称为:PORTA5PORTA0、PORTA7、PORTA13~PORTA10、PORTB7 PORTB0、PORTB13、PORTC9PORTC0、PORTC16PORTC14、PORTD3PORTD0、PORTD15、PORTD16~PORTD15、PORTE5 ~PORTE4、PORTE9 ~PORTE8)。

GPIO信号描述

2、GPIO 通用寄存器

2.1、GPIO端口内存映射~GPIO ports memory map

注意:在S32K11x中,GPIO只能通过0x400F_F000的交叉接口访问。

2.2、GPIO寄存器重置值~GPIO register reset values

GPIO寄存器支持支持8/16/32位;

2.3、GPIO寄存器描述
2.3.1、GPIO Memory map

GPIOA base address: 400F_F000h

GPIOB base address: 400F_F040h

GPIOC base address: 400F_F080h

GPIOD base address: 400F_F0C0h

GPIOE base address: 400F_F100h

2.3.2、PDOR-端口数据输出寄存器~Port Data Output Register

此寄存器配置在每个通用输出引脚上驱动的逻辑级别。

2.3.3、PSOR-端口集输出寄存器~Port Set Output Register

此寄存器配置是否设置PDOR的字段。

0:PDORn中对应的位不改变;

1:PDORn中对应的位被设置为逻辑1;

2.3.4、PCOR-端口清除输出寄存器~Port Clear Output Register

此寄存器配置是否清除PDOR的字段。

0:PDORn中对应的位不改变;

1:PDORn中对应的位被清除为逻辑0;

2.3.5、PTOR-端口切换输出寄存器:Port Toggle Output Register

此寄存器可切换在每个通用输出引脚上驱动的逻辑级别。

0:PDORn中对应的位不改变;

1:PDORn中对应的位被设置为其现有逻辑状态的倒数;

2.3.6、PDIR-端口数据输入寄存器:Port Data Input Register

这个寄存器捕获被驱动到每个通用输入引脚中的逻辑级别

0:引脚逻辑级别为逻辑0,或未配置为由数字功能使用;

1:引脚逻辑级别为逻辑1;

2.3.7、PDDR-端口数据方向寄存器:Port Data Direction Register

PDDR为输入或输出配置单个端口引脚

0:引脚被配置为GPIO功能的通用输入。如果在GPIOx_PIDR寄存器中的端口输入被禁用,则引脚将为高z;

1:引脚被配置为GPIO功能的通用输出

2.3.8、PIDR-端口输入禁用寄存器:Port Input Disable Register**

此寄存器禁止每个通用引脚作为输入

0:引脚配置为通用输入,只要引脚配置用于任何数字功能;

1:引脚未配置为通用用途输入。相应的端口数据输入寄存器位将读取为零;

3、GPIO函数封装

3.1、用枚举类型定义全部IO口

typedef enum
{
    /*  PTA端口    */ //0~31
    PTA0,  PTA1,  PTA2,  PTA3,  PTA4,  PTA5,  PTA6,  PTA7,  PTA8,  PTA9,  PTA10, PTA11, PTA12, PTA13, PTA14, PTA15,
    PTA16, PTA17, PTA18, PTA19, PTA20, PTA21, PTA22, PTA23, PTA24, PTA25, PTA26, PTA27, PTA28, PTA29, PTA30, PTA31,

    /*  PTB端口    */ //32~63
    PTB0,  PTB1,  PTB2,  PTB3,  PTB4,  PTB5,  PTB6,  PTB7,  PTB8,  PTB9,  PTB10, PTB11, PTB12, PTB13, PTB14, PTB15,
    PTB16, PTB17, PTB18, PTB19, PTB20, PTB21, PTB22, PTB23, PTB24, PTB25, PTB26, PTB27, PTB28, PTB29, PTB30, PTB31,

    /*  PTC端口    */
    PTC0,  PTC1,  PTC2,  PTC3,  PTC4,  PTC5,  PTC6,  PTC7,  PTC8,  PTC9,  PTC10, PTC11, PTC12, PTC13, PTC14, PTC15,
    PTC16, PTC17, PTC18, PTC19, PTC20, PTC21, PTC22, PTC23, PTC24, PTC25, PTC26, PTC27, PTC28, PTC29, PTC30, PTC31,

    /*  PTD端口    */
    PTD0,  PTD1,  PTD2,  PTD3,  PTD4,  PTD5,  PTD6,  PTD7,  PTD8,  PTD9,  PTD10, PTD11, PTD12, PTD13, PTD14, PTD15,
    PTD16, PTD17, PTD18, PTD19, PTD20, PTD21, PTD22, PTD23, PTD24, PTD25, PTD26, PTD27, PTD28, PTD29, PTD30, PTD31,

    /*  PTE端口    */
    PTE0,  PTE1,  PTE2,  PTE3,  PTE4,  PTE5,  PTE6,  PTE7,  PTE8,  PTE9,  PTE10, PTE11, PTE12, PTE13, PTE14, PTE15,
    PTE16, PTE17, PTE18, PTE19, PTE20, PTE21, PTE22, PTE23, PTE24, PTE25, PTE26, PTE27, PTE28, PTE29, PTE30, PTE31,
} PTXn_e;

#define PTX(PTX_n)  (PTX_n>>5)  //获取模块号 PTX_n/32
#define PTn(PTX_n)  (PTX_n&0x1f)//获取引脚号 PTX_n%32

虽然116没有这么多引脚,但便于后期:14X系列移植;

GPIO.h

//定义管脚状态
typedef enum GPIO_CFG
{
  //这里的值不能改!!!
  GPI         = 0x00,                       //定义管脚输入方向      GPIOx_PDDRn里,0表示输入,1表示输出
  GPO         = 0x01,                       //定义管脚输出方向
  
  GPI_DOWN    = 0x02,                       //输入下拉              PORTx_PCRn需要PE=1,PS=0
  GPI_UP      = 0x03,                       //输入上拉              PORTx_PCRn需要PE=1,PS=1
  GPI_PF      = 0x10,                       //输入,带无源滤波器,滤波范围:10 MHz ~ 30 MHz 。不支持高速接口(>=2MHz)  0b10000           Passive Filter Enable
  GPI_DOWN_PF = GPI_DOWN | GPI_PF ,         //输入下拉,带无源滤波器
  GPI_UP_PF   = GPI_UP   | GPI_PF ,         //输入上拉,带无源滤波器
  
  GPO_HDS     = 0x41,                       //输出高驱动能力   0b100 0001    High drive strength
  GPO_SSR     = 0x05,                       //输出慢变化率     0b101         Slow slew rate
  GPO_HDS_SSR = GPO_HDS | GPO_SSR,          //输出高驱动能力、慢变化率
} GPIO_CFG;  //最低位为0,肯定是输入;GPI_UP 和 GPI_UP_PF的最低位为1,其他为输出



void GPIO_PinInit(PTXn_e ptx_n, GPIO_CFG dir, uint8_t data);
void GPIO_PinWrite(PTXn_e ptx_n, uint8_t data);
void GPIO_PinReverse(PTXn_e ptx_n);
uint8_t GPIO_PinRead(PTXn_e ptx_n);

GPIO.c

#include "GPIO.h"

/* 定义五个指针数组保存 GPIOX 的地址 */
GPIO_MemMapPtr GPIOX[5] = {PTA, PTB, PTC, PTD, PTE}; //定义五个指针数组保存 GPIOX 的地址
PORT_MemMapPtr PORTX[5] = {PORTA, PORTB, PORTC, PORTD, PORTE};


/******************************************************************************
*函  数:GPIO_PinInit
*功 能:GPIO初始化函数
*参  数:
				 ptx_n:引脚号
				 dir  :引脚状态
				 data :引脚输出电平 0:低电平 1:高电平
*返回值:无
*备  注:无
*******************************************************************************/
void GPIO_PinInit(PTXn_e ptx_n, GPIO_CFG dir, uint8_t data)
{
	
	  uint8_t ptx,ptn;
    
    ptx = PTX(ptx_n);
    ptn = PTn(ptx_n);
	
	   /* 使能端口时钟 */
    PCC->PCCn[PCC_PORTA_INDEX + ptx] = PCC_PCCn_CGC_MASK;
	
	    /* 清除之前的复用功能 */
    PORTX[ptx]->PCR[ptn] &= ~(uint32)PORT_PCR_MUX_MASK;

	    /* 设置复用功能为GPIO即普通IO口 */
    PORTX[ptx]->PCR[ptn] |= PORT_PCR_MUX(1);
	
	    /* 配置GPIO模式 */
    PORTX[ptx]->PCR[ptn] |= dir;
	
	    /* 设置GPIO方向 */
    if(dir) 
    {
        GPIOX[ptx]->PDDR |= (uint32)(1<<ptn);
    }
    else  
    {
        GPIOX[ptx]->PDDR &= ~(uint32)(1<<ptn);
    }
    
    /* 设置端口默认状态 */
    if(data)
    {
        GPIOX[ptx]->PDOR |=  (uint32)(1<<ptn);   
    }
    else 
    {
        GPIOX[ptx]->PDOR &= ~(uint32)(1<<ptn);
    }
}

/******************************************************************************
*函  数:GPIO_PinWrite
*功 能:设置IO口输出高低电平
*参  数:
				 ptx_n:引脚号
				 data:  0-低电平 1-高电平
*返回值:无
*备  注:无
*******************************************************************************/
void GPIO_PinWrite(PTXn_e ptx_n, uint8_t data)
{
    uint8_t ptx,ptn;
    
    ptx = PTX(ptx_n);
    ptn = PTn(ptx_n);
    
    /* 设置端口默认状态 */
    if(data)
    {
        GPIOX[ptx]->PDOR |=  (uint32)(1<<ptn);   
    }
    else 
    {
        GPIOX[ptx]->PDOR &= ~(uint32)(1<<ptn);
    }
}

/******************************************************************************
*函  数:GPIO_PinReverse
*功 能:翻转GPIO输出
*参  数:
				ptx_n:引脚号
*返回值:无
*备  注:GPIO_PinReverse(PTA8);//取反PTA8管脚电平
*******************************************************************************/
void GPIO_PinReverse(PTXn_e ptx_n)
{
    uint8_t ptx,ptn;
    
    ptx = PTX(ptx_n);
    ptn = PTn(ptx_n);//获取引脚号 PTX_n%32
    
    GPIOX[ptx]->PTOR ^= (1<<ptn);
}

/******************************************************************************
*函  数:GPIO_PinRead
*功 能:获取IO口电平
*参  数:
				ptx_n:引脚号
*返回值:无
*备  注:无
*******************************************************************************/
uint8_t GPIO_PinRead(PTXn_e ptx_n)
{
    uint8_t ptx,ptn;
    
    ptx = PTX(ptx_n);
    ptn = PTn(ptx_n);
    
    return ( (GPIOX[ptx]->PDIR >> ptn) & 0x1 );
}

4、GPIO-LED实验

LED_App.c

#include "LED_App.h"
#include "GPIO.h"

#define LED1  PTB2     //LEDIO
 
void LED_Init(void)
 {
		GPIO_PinInit(LED1,GPO,0);
 
 }
 
void LED_ON()
{
	GPIO_PinWrite(LED1,0);
	
}

void LED_OFF()
{
	GPIO_PinWrite(LED1,1);
}

void LED_Reverse()
{
	GPIO_PinReverse(LED1);

}

void led_delayms(int ms)
{
    volatile uint32_t i = 0;
	while(ms--)
	{
		for (i = 0; i < 10000; ++i)
		{
			__asm("NOP"); /* delay */
		}
	}
}


void Test_LED(void)
{
	LED_Init();
    while(1)
    {
			LED_ON();
			led_delayms(100);
			LED_OFF();
			led_delayms(100);
		}
	
}

LED_App.h

#ifndef __LED_APP_H_
#define __LED_APP_H_
void LED_Init(void);
void LED_ON();
void LED_OFF();
void LED_Reverse();
void led_delayms(int ms);
void Test_LED(void);



#endif

main.c

#include <stdio.h>
#include "S32K116.h"	/* include peripheral declarations S32K116 */
#include "clocks_and_modes_S32K11x.h"
#include "GPIO.h"
#include "LED_App.h"

//关闭看门狗
void WDOG_disable (void)
{
  WDOG->CNT=0xD928C520;     /* Unlock watchdog 		*/
  WDOG->TOVAL=0x0000FFFF;   /* Maximum timeout value 	*/
  WDOG->CS = 0x00002100;    /* Disable watchdog 		*/
}

int main(void)
{
	WDOG_disable();
	SOSC_init_40MHz(); 	/* Initialize system oscillator for 40 MHz xtal */
	RUN_mode_48MHz();		/* Init clocks: 48 MHz sys, core and bus, 24 MHz flash. */
	
	Test_LED();
	
	return 0;
	
}


项目的程序工程已经放在下面公众号里面,可以关注公众号:Kevin的学习站,输入关键字:“055”,就可以获取啦!创作不易,但您的点赞、关注、收藏就是对我最大的鼓励!
在这里插入图片描述

  • 6
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Kevin的学习站

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

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

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

打赏作者

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

抵扣说明:

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

余额充值