我是靠谱客的博主 跳跃八宝粥,最近开发中收集的这篇文章主要介绍【嵌入式系统原理与应用】南航嵌入式 第五章—— 数字输入输出系统设计,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

第五章 数字输入输出系统设计

文章目录

    • 第五章 数字输入输出系统设计
        • 学习目标
        • 重要内容
        • 通用输入输出端口
        • GPIO基本工作模式
        • GPIO端口保护
        • GPIO端口的中断
        • STM32F10x的GPIO相关寄存器
          • GPIO的使能
          • GPIO地址映射
        • GPIO汇编指令的操作方法
          • 汇编语言操作
          • GPIO寄存器操作
          • GPIO固件库函数操作方法
        • GPIO_Init()使用的参量
        • 实例
          • 汇编语言
          • 寄存器
          • 固件库函数
        • 其他例子
        • 数字信号的逻辑电平转换
          • 需要数字逻辑电平转换的原因
          • 常用的转换方法

学习目标

  • 掌握GPIO基本知识(重点工作模式)*
  • 熟练掌握GPIO三种基本操作方法*
  • 熟悉数字信号的逻辑电平及其转换
  • 了解数字输入输出接口的扩展
  • 熟悉输入输出接口的一般结构
  • 熟练掌握常用人机通道的原理及应用

重要内容

  • 1、GPIO的基本特性:输入缓冲、输出锁存
  • 2、GPIO工作模式:高阻(浮空)输入、开漏、推挽输出,上下拉输入、双向输入输出
  • 3、GPIO中断类型及用途
  • 4、GPIO配置寄存器及工作方式编程(汇编、寄存器及固件库方式)
  • 5、GPIO输入数据寄存器和输出数据寄存器编程(汇编、寄存器及固件库方式)
  • 6、知晓逻辑电平为何要变换,有哪些方法
  • 7、简单人机交互接口的应用(发光管、按键)

通用输入输出端口

​ GPIO端口(General Purpose Input Output Port)即通用输入/输出端口,是可编程的通用并行I/O接口,主要用于需要数字量输入/输出的场合。

​ 主要特点:输入缓冲、输出缓存

GPIO基本工作模式

image-20220525213349457

  • 高阻输入模式
    • 由于三态门控制输入状态的读取,在读无效时呈高阻状态
    • image-20220525213010933
  • 开漏输出模式
    • 在普通输出模式基础上,使输出MOS管的漏极开路的一种输出方式。
    • image-20220525212957484
    • image-20220525213001675
  • 推挽输出模式
    • GPIO推挽输出是指输出端口采用推挽放大电路以输出更大的电流。
    • image-20220525212948614
  • 准双向I/O模式
    • GPIO的准双向I/O模式就是可以在需要输入的时候读外部的数据(输入),需要输出的时候就向端口发送数据
    • image-20220525212938376
  • 端口的上下拉
    • GPIO的引脚内部可配置为上拉或下拉,如果内部没有配置方式,则可以外接上拉电阻或下拉电阻。所谓上拉指的是引脚与电源VDD或VCC之间接一个大小100K左右的电阻,下拉指的是引脚与负电源VSS或地GND之间接一个100K左右的电阻。
    • image-20220525212923910

GPIO端口保护

  • 采用二极管钳位的方式来保护
  • 采用ESD器件的方式保护

GPIO端口的中断

​ MCU在处理其他事务时,靠不断查询引脚的状态,效率是低下的,采用中断机制解决问题。

​ 当引脚有变化时产生一个中断请求,微控制器在中断服务程序中去做相应引脚中断的处理任务,从而提高了效率。

image-20220525213410352

STM32F10x的GPIO相关寄存器

  • 两个32位配置寄存器:配置输入输出模式和输出频率
    • GPIOx_CRL
    • GPIOx_CRH
    • image-20220525213841635
    • 注意:上拉时:除了CNF=10,ODR中相应位要置为1,下拉时置为0!
    • image-20220525213813958
  • 两个32位数据寄存器:存放输入16数据和数据数据(高位保留)
    • 输入寄存器GPIOx_IDR
    • 输出寄存器GPIOx_ODR
  • 两个32置复位寄存器:置位指定引脚,复位指定引脚
    • 32位置位/复位寄存器(GPIOx_BSRR)
    • 16位复位寄存器(GPIOx_BRR)
  • 一个32位锁定寄存器:锁存数据,一般很少使用
    • GPIOx_LCKR
GPIO的使能

​ GPIO连接在APB2总线上,使用RCC寄存器来选择是否打开

GPIO地址映射

image-20220525214104822


GPIO汇编指令的操作方法

汇编语言操作
初始化GPIOx端口:	
	LDR Rn,=GPIOx_CRL  or  GPIO_CRH
	LDR Ri,=Command
	STR Ri,[Rn]	;写控制寄存器初始化GPIOx端口
读GPIOx端口数据:
	LDR Rn,=GPIOx_IDR
	LDRH Ri,[Rn]
写数据到GPIOx端口:
	LDR Rn,=GPIOx_ODR
	LDR Ri,=Data
	STRH Ri,[Rn]
GPIO寄存器操作
GPIOx_CRL配置寄存器:		GPIOx->CRL	如GPIOA->CRL
GPIOx_CRH配置寄存器:		GPIOx->CRH	如GPIOB->CRH
GPIOx_IDR输入数据寄存器:		GPIOx->IDR	如GPIOC->IDR
GPIOx_ODR输入数据寄存器:		GPIOx->CRL	如GPIOD->ODR
初始化GPIOx端口:	
	GPIOx->CRL=Command;//写控制寄存器L初始化GPIOx端口
	GPIOx->CRH=Command;//写控制寄存器H初始化GPIOx端口
读GPIOx端口数据:
	u16 DataP;
	DataP=GPIOx->IDR;
写数据到GPIOx端口:
	GPIOx->ODR=data;//data为16位无符号数
GPIO固件库函数操作方法
一、初始化GPIO端口
1、用RCC_APB2PeriphClockCmd()函数使能GPIO时钟
2、用GPIO_Init()函数初始化GPIO端口
二、读GPIO端口数据
1、用GPIO_ReadInputDataBit()函数读取指定GPIO引脚的电平状态
2、用GPIO_ReadInputData()函数读取指定GPIO整个端口的16位数据
三、写GPIO端口数据
1、用GPIO_SetBits()函数置位多个指定I/O引脚(高电平输出)
2、用GPIO_ResetBits()函数复位多个指定I/O引脚(低电平输出)
3、用GPIO_WriteBit()函数写指定一个I/O引脚高低电平
4、用GPIO_Write()函数写指定一个完整GPIO端口16位数据

GPIO_Init()使用的参量

一、输出时
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_n;//n=0~15定义引脚
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//输出频率10MHz,2MHz,50MHz
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//输出工作模式	
	GPIO_Init(GPIOx, &GPIO_InitStructure);//调用初始化GPIO函数
二、输入时
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_n;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//输入工作模式	
	GPIO_Init(GPIOx, &GPIO_InitStructure);
引脚定义:可多个引脚合并定义,中间用|,如GPIO_Pin_1|GPIO_Pin_2
输入工作模式:		
			GPIO_Mode_AIN		模拟输入 
			GPIO_Mode_IN_FLOATING 	浮空输入
	  		GPIO_Mode_IPD 		下拉输入
			GPIO_Mode_IPU 		上拉输入
输出模式:			
			GPIO_Mode_Out_OD		开漏输出
			GPIO_Mode_Out_PP		推挽输出
  			GPIO_Mode_AF_OD		多功能开漏输出
  			GPIO_Mode_AF_PP		多功能推挽输出	

实例

​ 如图所示,写出除使能GPIO时钟外,让LED1和LED4亮,LED2和LED5灭的汇编语言程序
片段。
​ APB2时钟使能寄存器RCC地址:0x40021018
​ GPIOD_CRL地址=0x40011400
​ GPIOD_CRH地址=0x40011404
​ GPIOD_ODR地址=0x4001140C

image-20220525215122627

汇编语言
LDR R0,=0x40011400	;GPIOD_CRL
LDR R1,[R0]		;加载控制寄存器到R1
LDR R2,=0x20022200	;选择PD2,PD3,PD4,PD7为2MHz推挽输出,其它为输入
ORRS R1,R1,R2		;#0x20022200=0010 0000 0000 0010 0010 0010 0000 0000
LDR R2,=0x2FF222FF
ANDS R1,R1,R2		;#0x2FF222FF=0010 1111 1111 0010 0010 0010 1111 1111
STR R1,[R0]		;写到控制寄存器CRL中
LDR R0,=0x4001140C	;GPIOD_ODR
LDR R1,[R0]
ANDS R1,R1,#0xEB		;1110 1011
ORRS R1,R1,#0x88		;1000 1000
STRH R1,[R0]		;写入输出数据寄存器ODR
寄存器
u32 CtrlPort=0;
CtrlPort=GPIOD->CRL;//取CRL值
CtrlPort|=0x20022200;
CtrlPort&=0x2FF222FF;
GPIOD->CRL=CtrlPort;
GPIOD->ODR|=(1<<3)|(1<<7);
GPIOD->ODR&=~(1<<2)&~(1<<4);
固件库函数
GPIO_InitTypeDef  GPIO_InitStructure; 
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE); GPIO_InitStructure.GPIO_Pin=GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_7;/*PD2/3/4/7为输出引脚*/
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;  	/*速度2MHz*/
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;	/*推挽输出*/
GPIO_Init(GPIOD, &GPIO_InitStructure);		/*初始化GPIOD端口*/
GPIO_SetBits(GPIOD,GPIO_Pin_3|GPIO_Pin_7);    /*PD3:LED2、PD7:LED5为1灭*/
GPIO_ResetBits(GPIOD,GPIO_Pin_2|GPIO_Pin_4);    /*PD2:LED1、PD4:LED4为0亮*/

其他例子

【例5.1】假设PD2、PD3、PD4和PD7为推挽输出作为LED发光二极管(LED1~LED4)输出控制,0亮,1灭,PD11、PD12、PC13和PA0为上拉输入,作为KEY1~KEY4四个按键输入,设置各PORTA、PORTC和PORTD工作频率为10MHz出。并让LD1~LD4全部灭。

GPIO_InitTypeDef  GPIO_InitStructure; 
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOC
	|RCC_APB2Periph_GPIOD, ENABLE); /*使能GPIOA,C,D端口时钟*/
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_11|GPIO_Pin_12;		/*PD11/12输入*/
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;/*高阻输入*/
GPIO_Init(GPIOD, &GPIO_InitStructure);			/*初始化GPIOD端口*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 ;
GPIO_Init(GPIOC, &GPIO_InitStructure);	
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 ;
GPIO_Init(GPIOA, &GPIO_InitStructure);	
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_7;//PD2/3/4/7入
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;  	/*速度10MHz*/
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;	/*推挽输出*/
GPIO_Init(GPIOD, &GPIO_InitStructure);			/*初始化GPIOD端口*/
GPIO_SetBits(GPIOD,GPIO_Pin_2|GPIO_Pin_3| GPIO_Pin_4| GPIO_Pin_7|);	    /*PD2:LED1、PD3:LED3、PD4:LED3、PD7:LED4全为1灭*/

数字信号的逻辑电平转换

需要数字逻辑电平转换的原因

​ 不同逻辑电平之间如果不进行逻辑电平的变换,由于逻辑电平的不一致,使发送的 0 和 1 信息到达接收端无法正确识别 0 和 1 逻辑信息,即无法进行正确地相互交互,因此对于不同逻辑电平必须进行逻辑电平的转换方能连接。

常用的转换方法
  • (1)限流电阻加钳位二极管方式进行同逻辑电平转换接口
  • (2)用电阻与三极管构成的逻辑电平转换接口
  • (3)仅用两只电阻组成的逻辑电平转换接口
  • (4)用专用逻辑电平转换芯片进行逻辑电平转换
  • (5)采用光电耦合器实现逻辑电平隔离转换

最后

以上就是跳跃八宝粥为你收集整理的【嵌入式系统原理与应用】南航嵌入式 第五章—— 数字输入输出系统设计的全部内容,希望文章能够帮你解决【嵌入式系统原理与应用】南航嵌入式 第五章—— 数字输入输出系统设计所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(45)

评论列表共有 0 条评论

立即
投稿
返回
顶部