智能车学习(二)—— GPIO学习
一、概述
使用的是蓝宇的底层,主要有初始化管脚,设置管脚状态,反转管脚状态等。
二、代码重述:
1、头文件gpio.h
#ifndef GPIO_H //防止重复定义(gpio_H 开头) #define GPIO_H #include "common.h" //包含公共要素头文件 /* * 定义管脚方向 */ typedef enum GPIO_CFG { //这里的值不能改!!! GPI = 0, //定义管脚输入方向 GPIOx_PDDRn里,0表示输入,1表示输出 GPO = 1, //定义管脚输出方向 } GPIO_CFG; #define HIGH 1u #define LOW 0u // 端口号地址偏移量宏定义 #define PORTA 0 #define PORTB 1 #define PORTC 2 #define PORTD 3 #define PORTE 4 //=========================================================================== //函数名称:gpio_init //函数返回:无 //参数说明:port:端口号+引脚号(gpio_cfg.h中宏定义,格式为PTXY,eg:PTA0) by BlueMountain 2015/10/8 // // dir:引脚方向(0=输入,1=输出) // state:引脚初始状态(0=低电平,1=高电平) //功能概要:初始化端口指定引脚作为GPIO引脚的功能,并定义为输入或输出,若是输出, // 还指定初始状态是低电平或高电平 //=========================================================================== void gpio_init(PTxn port, uint8_t dir, uint8_t state); //============================================================================ //函数名称:gpio_set //函数返回:无 //参数说明:port:端口号+引脚号(gpio_cfg.h中宏定义,格式为PTXY,eg:PTA0) by BlueMountain 2015/10/8 // pin:引脚号(0~31,实际取值由芯片的物理引脚决定) // state:引脚初始状态(0=低电平,1=高电平) //功能概要:设定引脚状态为低电平或高电平 //============================================================================ void gpio_set(PTxn port, uint8_t state); //=========================================================================== //函数名称:gpio_get //函数返回:指定引脚的状态(1或0) //参数说明:port:端口号+引脚号(gpio_cfg.h中宏定义,格式为PTXY,eg:PTA0) by BlueMountain 2015/10/8 // pin:引脚号(0~31,实际取值由芯片的物理引脚决定) //功能概要:获取指定引脚的状态(1或0) //=========================================================================== uint8_t gpio_get(PTxn port1); //=========================================================================== //函数名称:gpio_reverse //函数返回:无 //参数说明:port:端口号+引脚号(gpio_cfg.h中宏定义,格式为PTXY,eg:PTA0) by BlueMountain 2015/10/8 // pin:引脚号(0~31,实际取值由芯片的物理引脚决定) //功能概要:反转指定引脚输出状态。 //=========================================================================== void gpio_reverse(PTxn port1); #endif //防止重复定义(gpio_H 结尾)
2、gpio.c
#include "gpio.h" //包含本构件头文件 //注意这边有两个枚举 //各端口基地址放入常数数据组PORT_ARR[0]~PORT_ARR[4]中 const PORT_MemMapPtr PORT_ARR[]={PORTA_BASE_PTR,PORTB_BASE_PTR, PORTC_BASE_PTR,PORTD_BASE_PTR,PORTE_BASE_PTR}; //GPIO口基地址放入常数数据组GPIO_ARR[0]~GPIO_ARR[4]中 const GPIO_MemMapPtr GPIO_ARR[]={PTA_BASE_PTR,PTB_BASE_PTR, PTC_BASE_PTR,PTD_BASE_PTR,PTE_BASE_PTR}; //=========================================================================== //函数名称:gpio_init //函数返回:无 //参数说明:port:端口号+引脚号(gpio_cfg.h中宏定义,格式为PTXY,eg:PTA0) by BlueMountain 2015/10/8 // // dir:引脚方向(0=输入,1=输出) // state:引脚初始状态(0=低电平,1=高电平) //功能概要:初始化端口指定引脚作为GPIO引脚的功能,并定义为输入或输出,若是输出, // 还指定初始状态是低电平或高电平 //=========================================================================== void gpio_init(PTxn port, uint8_t dir, uint8_t state) { //局部变量声明 uint8_t portl; uint8_t pin ; PORT_MemMapPtr port_ptr; //声明port_ptr为PORT结构体类型指针 GPIO_MemMapPtr gpio_ptr; //声明gpio_ptr为GPIO结构体类型指针 portl = port/32 ; //port1=0、1、2、3、4 pin = port%32 ; //pin A口1-2 4-5 12-17 B口0-3 8-11 16-19 C口0-13 16-17 // D口0-7 E口0-5 20-25 29-31 //根据带入参数port,给局部变量port_ptr、gpio_ptr赋值(获得两个基地址) port_ptr = PORT_ARR[portl]; //获得PORT模块相应口基地址 gpio_ptr = GPIO_ARR[portl]; //获得GPIO模块相应口基地址 //因为管脚有复用功能 根据带入参数pin,指定该引脚功能为GPIO功能(即令引脚控制寄存器的MUX=0b001) port_ptr->PCR[pin] = PORT_PCR_MUX(1); //根据带入参数dir,决定引脚为输出还是输入 if (1 == dir) //希望为输出 { BSET(pin,gpio_ptr->PDDR); //数据方向寄存器的pin位=1,定义为输出 gpio_set(port, state); //调用gpio_set函数,设定引脚初始状态 } else { //希望为输入 BCLR(pin,gpio_ptr->PDDR); //数据方向寄存器的pin位=0,定义为输入 gpio_set(port, state); //调用gpio_set函数,设定引脚初始状态 } } //============================================================================ //函数名称:gpio_set //函数返回:无 //参数说明:port:端口号+引脚号(gpio_cfg.h中宏定义,格式为PTXY,eg:PTA0) by BlueMountain 2015/10/8 // state:引脚初始状态(0=低电平,1=高电平) //功能概要:设定引脚状态为低电平或高电平 //============================================================================ void gpio_set(PTxn port1, uint8_t state) { //局部变量声明 GPIO_MemMapPtr gpio_ptr; //声明port_ptr为GPIO结构体类型指针 uint8_t port; uint8_t pin ; port = port1/32 ; pin = port1%32 ; //根据带入参数port,给局部变量gpio_ptr赋值(GPIO基地址) gpio_ptr = GPIO_ARR[port]; //根据带入参数state,决定引脚为输出1还是0 if (1==state) {BSET(pin,gpio_ptr->PDOR);} else {BCLR(pin,gpio_ptr->PDOR);} } //=========================================================================== //函数名称:gpio_get //函数返回:指定引脚的状态(1或0) //参数说明:port:端口号+引脚号(gpio_cfg.h中宏定义,格式为PTXY,eg:PTA0) by BlueMountain 2015/10/8 // pin:引脚号(0~31,实际取值由芯片的物理引脚决定) //功能概要:获取指定引脚的状态(1或0) //=========================================================================== uint8_t gpio_get(PTxn port1) { //局部变量声明 GPIO_MemMapPtr gpio_ptr; //声明port_ptr为GPIO结构体类型指针(首地址) uint8_t port; uint8_t pin ; port = port1/32 ; pin = port1%32 ; //根据带入参数port,给局部变量port_ptr赋值(GPIO基地址) gpio_ptr = GPIO_ARR[port]; //返回引脚的状态 return ((BGET(pin,gpio_ptr->PDIR))>=1 ? 1:0); } //=========================================================================== //函数名称:gpio_reverse //函数返回:无 //参数说明:port:端口号+引脚号(gpio_cfg.h中宏定义,格式为PTXY,eg:PTA0) by BlueMountain 2015/10/8 // pin:引脚号(0~31,实际取值由芯片的物理引脚决定) //功能概要:反转指定引脚输出状态。 //=========================================================================== void gpio_reverse(PTxn port1) { //局部变量声明 GPIO_MemMapPtr gpio_ptr; //声明port_ptr为GPIO结构体类型指针(首地址) uint8_t port; uint8_t pin ; uint8_t state ; port = port1/32 ; pin = port1%32 ; //反转指定引脚输出状态 //根据带入参数port,给局部变量port_ptr赋值(GPIO基地址) gpio_ptr = GPIO_ARR[port]; state = ((BGET(pin,gpio_ptr->PDIR))>=1 ? 1:0) ; // BSET(pin,gpio_ptr->PTOR); if (0==state) {BSET(pin,gpio_ptr->PDOR);} else {BCLR(pin,gpio_ptr->PDOR);} }
三、学习的思考
就目前看到的gpio的设置是不全面的,少了上拉,下拉等等的输入状态的设置,无法使用中断,所以在后续的学习应该可以找到。代码的话,可以直接进行调用。