K60学习笔记一:PORT端口
预备C语言知识:
一.
1.
#ifndef //#idndef用来判断后面的标识符是否为未定义的。
#elseif
#endif
在嵌入式的系统开发中,某个文件包含几个头文件,而且每个头文件都有可能都定义了同样的宏,使用#ifndef可以有效地防止对该宏的重复定义。此时第一个头文件中定义的宏变为有效定义,其他的头文件中的定义则被忽略。
2.#ifndef指令通常用于防止多次包含同意文件,也就是说,头文件可以采用类似于以下几行的设置:
#ifndef THINGS_H_
#define THINGS_H_#endif
假设多次定义了同一头文件,当于处理器第一次遇到该包含文件时,THINGS_H_是未定义的,因此程序接着定义THINGS_H_,并处理文件的其余部分,预处理器下一次遇到该文件时,THINGS_H_早已经被定义了,因此预处理器会跳过该文件的其余部分。
3.
这里有一个问题:为什么会包含同一头文件?为什么会用头文件的名字作为#define的定义?
答:许多文件自身包含了其他文件。头文件的有些语句在一个文件中只能出现一次,标准头文件使用#ifndef来避免多次包含。
编译器提供商采用下述方法来解决这个问题,用文件名标识符,并使用大写字母,用下划线来代替字符。
eg;
#ifndef _STDIO_H_
#define _STDIO_H_
#endif
4.
枚举:枚举用来声明代表整数常量的符号名称。
可以通过enum来创建一个新的类型,并指定值。
枚举类型的目的是为了提高程序的可读性(其实也可以用#define来进行声明,但是可读性不高)
枚举型类型可以默认值也可以指定值。
5.
typeof简介:它是一种高级数据格式
typeof unsigned char BYTE
//和
#define BYTE unsigned char
//具有一样的功能
//但是typeof的功能比#define更加的强大:
//eg
typeof char * STRING
STRING NAME,NUM;
//char * NAME,char * NUM;
//和
#define STRING char *
STRING NAME,NUM;
//char * NAME,NUM;//对结构体也可使用typeof
6.#include “” and #include <>
#include ""//引用的头文件为程序目录的相对路径的头文件,表示在包含文件目录中去查找(包含目录是由用户在设置环境时设置的),而不在源文件目录去查找
#include <>//引用的是编译器中类库里面的头文件,使用双引号则表示首先在当前的源文件目录中查找,若未找到才到包含目录中去查找
7.
2.对于基于IAR IDE的K60芯片的野火的函数库的PORT端口来说:
有两个文件为:PORT.h和PROT.c
二:下面详细的分析这两个文件:
1.
在PORT端口的定义中,对端口的定义用的枚举类型:
//枚举端口管教
typeof enum
{
/* PTA端口 */ //0~31PTA0, 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~63PTB0, 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;//类似于查表来确定端口数值//枚举端口
typedef enum
{PTA, PTB, PTC, PTD, PTE,PTX_MAX,
} PTX_e;
//是为了很好的表示各个端口的基地址
/*! 枚举编号 */
typedef enum
{PT0 , PT1 , PT2 , PT3 , PT4 , PT5 , PT6 , PT7 ,PT8 , PT9 , PT10, PT11, PT12, PT13, PT14, PT15,PT16, PT17, PT18, PT19, PT20, PT21, PT22, PT23,PT24, PT25, PT26, PT27, PT28, PT29, PT30, PT31,
} PTn_e;/*! 枚举PORT 配置 */
typedef enum
{//中断方式和DMA请求方式,两者只能选其中一种(可以不选)//中断方式选择IRQ_ZERO = 0x08 << PORT_PCR_IRQC_SHIFT, //低电平触发IRQ_RISING = 0x09 << PORT_PCR_IRQC_SHIFT, //上升沿触发IRQ_FALLING = 0x0A << PORT_PCR_IRQC_SHIFT, //下降沿触发IRQ_EITHER = 0x0B << PORT_PCR_IRQC_SHIFT, //跳变沿触发IRQ_ONE = 0x0C << PORT_PCR_IRQC_SHIFT, //高电平触发//DMA请求选择DMA_RISING = 0x01 << PORT_PCR_IRQC_SHIFT, //上升沿触发DMA_FALLING = 0x02 << PORT_PCR_IRQC_SHIFT, //下降沿触发DMA_EITHER = 0x03 << PORT_PCR_IRQC_SHIFT, //跳变沿触发HDS = 0x01 << PORT_PCR_DSE_SHIFT, //输出高驱动能力PF = 0x01 << PORT_PCR_PFE_SHIFT, //带无源滤波器SSR = 0x01 << PORT_PCR_SRE_SHIFT, //输出慢变化率 Slow slew rate//下拉上拉选择PULLDOWN = 0x02 << PORT_PCR_PS_SHIFT, //下拉PULLUP = 0x03 << PORT_PCR_PS_SHIFT, //上拉//功能复用选择(如果不需要改变功能复用选择,保留原先的功能复用,直接选择ALT0 )//需要查 K60 Signal Multiplexing and Pin AssignmentsALT0 = 0x00 << PORT_PCR_MUX_SHIFT,ALT1 = 0x01 << PORT_PCR_MUX_SHIFT, //GPIO 8ALT2 = 0x02 << PORT_PCR_MUX_SHIFT,ALT3 = 0x03 << PORT_PCR_MUX_SHIFT,ALT4 = 0x04 << PORT_PCR_MUX_SHIFT,ALT5 = 0x05 << PORT_PCR_MUX_SHIFT,ALT6 = 0x06 << PORT_PCR_MUX_SHIFT,ALT7 = 0x07 << PORT_PCR_MUX_SHIFT,
} port_cfg;
//枚举PORT复用配置,采用枚举赋值,增加易读性
//其实也可以直接赋值
//一开始并不明白为什么要枚举端口号和枚举编号,枚举了管脚就可以了,头文件看到这,在看一下.C文件
PORT.C
#include "common.h" //山外K60 平台常用类型声明和宏定义
PORT端口中一共有三个函数分别为:
端口初始化和复用函数(配置MUX复用功能):
extern void port_init(PTXn_e(端口号),uint32 cfg);
端口初始化和复用函数(不改变MUX复用功能):
extern void port_init_NoALT(PTXn_e(端口号),uint32 cfg);
外部中断的服务函数:
extern void port_handler(void);
在看PORT.C
#include "commom.h" //类型声明和宏定义
#include "port.h" //自己写的函数PORT_MemMapPtr PORTX[PTX_MAX] = {PORTA_BASE_PTR, PORTB_BASE_PTR, PORTC_BASE_PTR, PORTD_BASE_PTR, PORTE_BASE_PTR};
//PORT_MemMapPtr为一个结构体指针 ,PORTX[PTX_MAX]这个数组里面存的是各个端口的基地址
//现在懂得在PORT.H中关于枚举端口的意思。
void port_init(PTXn_e ,uint32 cfg)
{SIM_SCGC5 |= (SIM_SCGC5_PORTA_MASK << PTX(ptxn)); //开启PORTx端口 1.使能PORT时钟
//段地址属于基地址的一种
//4004_8038
//0100 0000 0000 0100 1000 0000 0011 1000
//#define PTX(PTxn(枚举管脚)) ((PTxn)>>5)
//右移5位,/2^5(32)
// SIM_SCGC5_PORTA_MASK = 0x200 0010 0000 0000 默认的开启了PORTA的时钟因为是/32?为什么是32,因为是2的次方数
//因此PTX(ptxn)的为0 1 2 3 4
//因此输入管脚口,就可以进行相应口的使能时钟PORT_ISFR_REG(PORTX_BASE(ptxn)) = (1<<PTn(ptxn)); // 清空标志位
//每个管脚都有相应的中断标志位
//现在理解枚举端口的含义
//#define PTn(ptxn) ((PTxn)&0x1f) 为的是中断端口的相应管脚,每个端口一共31个口,相应的管脚为1
//PORT_ISFR_REG(PORTX_BASE(ptxn))为指向端口的地址
//这一步操作的是中断状态寄存器PORT_PCR_REG(PORTX_BASE(PTxn), PTn(PTxn)) = cfg;
//复用引脚功能
//这句话可以复用的功能有:中断触发方式,无源滤波器,复用功能口,上下拉电阻
//操作的寄存器:引脚控制寄存器 n (PORTx_PCRn),每个管脚都有引脚控制寄存器
//PORT_PCR_REG(PORTX_BASE(PTxn), PTn(PTxn))把管脚定义到具体的一个管脚
//cfg根据数据手册进行搭配//由此K60芯片的管脚以初始化完毕void port_init_NoALT(PTXn_e ptxn, uint32 cfg)
{ SIM_SCGC5 |= (SIM_SCGC5_PORTA_MASK << PTX(ptxn)); //开启PORTx端口PORT_ISFR_REG(PORTX_BASE(ptxn)) = (1<<PTn(ptxn)); // 清空标志位
//清空cfg里的MUX,加载寄存器里的MUXcfg &= ~PORT_PCR_MUX_MASK; //清了MUX 字段(即不需要配置ALT,保持原来的ALT)cfg |= (PORT_PCR_REG(PORTX_BASE(ptxn), PTn(ptxn)) & PORT_PCR_MUX_MASK); //读取寄存器里配置的 MUXPORT_PCR_REG(PORTX_BASE(ptxn), PTn(ptxn)) = cfg; // 复用功能 , 确定触发模式 ,开启上拉或下拉电阻
}} //端口的外部中断功能:
首先要进行把 porta_handler 函数添加到中断向量表,不需要我们手动调用
操作:
set_vector_handler(PORTA_VECTORn , 中断函数名);
在进行这个函数解析的时候有一个很大的问题。
关于断言的使用:(一定要学好宏定义)
再开一篇····
K60学习笔记一:PORT端口相关推荐
- 智能车K60学习笔记
文章目录 K60学习笔记(开个坑,慢慢学) 基础知识 一系列定义或名称 简单位运算 中断(Interrupt) 8051 定时器中断 Kinetis K60介绍 K60模块 PORT模块 GPIO模块 ...
- CentOS学习笔记 - 4. 修改端口和禁止root登录
2019独角兽企业重金招聘Python工程师标准>>> 小技巧 改变密码和端口等配置后,不要退出当前终端. 可以新开一个终端连接一下,防止误操作不能登录,无法恢复. 修改root密码 ...
- CST学习笔记4----------初级端口
1.偶极子:离散端口,点到点,边到边 离散端口适合一点到另一点,一端到另一端(一边到他的参考),是比较简单的 波导端口需要定义一个面,分析这个面所能形成的模式 对于双极子天线: ①点到点,两个中心点& ...
- kali linux学习笔记(四) : 网络端口大全介绍
端口大全介绍 2端口:管理实用程序 3端口:压缩进程 5端口:远程作业登录 7端口:回显 9端口:丢弃 11端口:在线用户 13端口:时间 17端口:每日引用 18端口:消息发送协议 19端口:字符发 ...
- 汇编学习笔记——汇编指令
目录 汇编指令 nop指令 mov.add.sub指令 adc.sbb指令 and.or指令 移位指令 逻辑左/右移指令 循环左/右移指令 算术左/右移指令 带进位循环左/右移指令 inc指令 pus ...
- ifconfig没有命令 kali_kali学习笔记之——端口扫描工具
之前的kali学习笔记分别介绍了kali的网卡问题和隐藏ssid的扫描 蟪蛄语春秋:kali学习笔记之--wi read():Network is down问题zhuanlan.zhihu.com ...
- 汇编入门学习笔记 (十二)—— int指令、port
疯狂的暑假学习之 汇编入门学习笔记 (十二)-- int指令.port 參考: <汇编语言> 王爽 第13.14章 一.int指令 1. int指令引发的中断 int n指令,相当于引 ...
- 计算机指令int,汇编入门学习笔记 (十二)—— int指令、端口
疯狂的暑假学习之 汇编入门学习笔记 (十二)-- int指令.端口 参考: <汇编语言> 王爽 第13.14章 一.int指令 1. int指令引发的中断 int n指令,相当于引发一 ...
- CC2530学习笔记(2)—— IO端口基本操作实验(按键控制亮灯)
CC2530学习笔记(2)-- IO端口基本操作(按键控制亮灯) 关于CC2530的IO端口基本知识.IO端口有关寄存器的介绍和描述请参照:CC2530学习笔记(1)-- IO端口 电路原理图如图1 ...
- 容器云原生DevOps学习笔记——第三期:从零搭建CI/CD系统标准化交付流程
暑期实习期间,所在的技术中台-效能研发团队规划设计并结合公司开源协同实现符合DevOps理念的研发工具平台,实现研发过程自动化.标准化: 实习期间对DevOps的理解一直懵懵懂懂,最近观看了阿里专家带 ...
最新文章
- python流程控制-详解Python流程控制语句
- 2017年如何在移动端优雅的使用flex
- 无需安装Oracle,直接使用PL/SQL的方法
- 从知乎了解到,为什么Mysql禁用存储过程、外键和级联?
- 你所不知道的SQL Server数据库启动过程(用户数据库加载过程的疑难杂症)
- Conv2d中的groups参数(分组卷积)怎么理解? 【分组卷积可以减少参数量、且不容易过拟合(类似正则化)】
- vector 的删除
- 注册、登陆、审核练习
- 杭电2103---Family planning
- verilog将像素数据写入txt_【测试工具】测试数据生成工具datafaker
- codeforces 27 E. Number With The Given Amount Of Divisors(数论+dfs)
- www.050604.pw ub.php,《UFIDA用友软件维护工具》050604版使用说明
- lnmp一键安装包 php7,LNMP一键安装包 V1.7 正式版发布
- 使用java语言实现一个动态数组(详解)(数据结构)
- simulink AWGN信道使用要点
- 北京最最最牛的IT公司都在这了
- python3 列表list 内置函数
- 关于音频采样率,音频帧率,每次采集多少字节的理解
- java跳转kotlin页面_Kotlin:return与跳转
- VOL vs. VLK by Plod