stm32有5组GPIO口,GPIOA  GPIOB  GPIOC  GPIOD  GPIOE

每个GPIO端口有:

    2个配置寄存器GPIOx_CRL, GPIOx_CRH(32位);

    2个数据寄存器GPIOx_IDR, GPIOx_ODR(32位);

    1个置位/复位寄存器GPIOx_BSRR(32位);

    1个复位寄存器GPIOx_BRR(16位);

    1个锁定寄存器GPIOx_LCKR(32位);

输入模式:

  —输入浮空:顾名思义也就是输入什么信号才是什么信号,对于浮空输入要保证有明确的输入信号。
  ─ 输入上拉:上拉输入模式:区别在于没有输入信号的时候默认输入高电平(因为有弱上拉)
  ─ 输入下拉:下拉输入模式:区别在于没有输入信号的时候默认输入低电平(因为有弱下拉)
  ─ 模拟输入:用于模拟量输入;仅仅拥有ADC

输出模式:

  ─ 开漏输出:随IO变化

  ─ 推挽式输出:推挽具有比较好的驱动能力。

  ─ 推挽式复用功能
  ─ 开漏复用功能

 #include "stm32f10x_gpio.h"

 int main()
{ //设置GPIOA的工作模式,何种输入方式、何种输出方式, 以及工作速率的设定;
// GPIOA->CRL = 0x33;
// //在相应引脚上设置相应电平
// GPIOA->ODR = 0x00; //输出低电平
// GPIOA->ODR = 0x03; //设置为1,0x0011,即第1位,第2位输出高电平,等同于51中的1; //设置GPIOA工作模式;
//PA0 设置为输出模式,50hz, PA8 设置为输入;
GPIOA->CRL = 0x03;
GPIOA->CRH = 0X04; while()
{
if((GPIOA->ODR & 0x0100) ==0x0100)
{
GPIOA->ODR = 0x01;
}
else
{
GPIOA->ODR = 0x00;
}
} return ;
}

位绑定:即找到需要绑定的寄存器地址;选择具体的那个位(8位中的一位);

  宏观看:就是将需要绑定的寄存器中的具体某一位映射到具体的一个32位的地址中,通过操作这个32位地址来操作寄存器的位;这样mcu运行更快;

地址绑定公式:

  SRAM区: 0x2000 0000 到 0x200f ffff 1M大小空间用于绑定作用;
    AliasAddr = 0x2200 0000 + ((A-0x2000 0000)*8 + n)*4     (n属于0~7,这点待确定;下面第二段代码有例子,)
           = 0x2200 0000 + (A-0x2000 0000)*32 + 4n
   此处A属于:0x2000 0000 到 0x200f ffff

  片上外设: 0x4000 0000 ~ 0x400f ffff 1M大小;
    AliasAddr = 0x4200 0000 + ((A-0x4000 0000)*8+n)*4
           = 0x4200 0000 + (A-0x400 0000)*32 + 4*n
    此处A属于:0x4000 0000 到 0x400f ffff

 #include "stm32f10x_gpio.h"

 int main()
{
//0x4200 0000 + ((A-0x4000 0000)*8+n)*4
u32 *PAO4 = (u32*)(0x42000000 + ((GPIOA_BASE+0x0C-0x40000000)*+)*);
u32 *PAI12 = (u32*)(0x42000000 + ((GPIOA_BASE+0x09-0x40000000)*+)*);
//设置GPIOA引脚上的工作模式,GPIOA: 0, GPIOA:1 推挽输出而不是复用输出, 工作速率:50hz;
// GPIOA->CRL = 0x33;
// //在相应引脚上设置相应电平;
// GPIOA->ODR = 0x00; //输出0
// GPIOA->ODR = 0x03; //设置11,输出高电平,而不再是单片机中1; //设置GPIOA工作模式;
//PA0 输出, 50hz,PA8 输入
GPIOA->CRL = 0x33333333;
GPIOA->CRH = 0X44444444; while()
{
if(((GPIOA->IDR) & 0x0100) ==0x0100) GPIOA->ODR = GPIOA->ODR | 0x01;
else GPIOA->ODR = GPIOA->ODR & ~0x01;
if(((GPIOA->IDR) & 0x0200) ==0x0200) GPIOA->ODR = GPIOA->ODR | 0x02;
else GPIOA->ODR = GPIOA->ODR & ~0x02;
if(((GPIOA->IDR) & 0x0400) ==0x0400) GPIOA->ODR = GPIOA->ODR | 0x04;
else GPIOA->ODR = GPIOA->ODR & ~0x04; if(((GPIOA->IDR) & 0x0800) ==0x0800) GPIOA->ODR = GPIOA->BSRR | 0x08; //BSRR端口位设置/复位寄存器
else GPIOA->ODR = GPIOA->BRR & ~0x08; // BRR端口位复位寄存器(GPIOx_BRR) //根据位绑定公式;
//A = GPIOA_BASE+IDR的偏移地址是GPIOA->IDR = GPIOA_BASE+0x08 n = 4;
// A = GPIOA_BASE+ODR的偏移地址是GPIOA->ODR = GPIOA_BASE+0x0C n = 4;
//n=4 ,因为是GPIOA->ODR中的第四位(0x10,从0位开始算);
// if(((GPIOA->IDR) & 0x1000) ==0x1000) *PAO4 = 1; //GPIOA->ODR = GPIOA->ODR | 0x10;
// else *PAO4 = 0; //GPIOA->ODR = GPIOA->ODR & ~0x10;
if(*PAI12 == ) *PAO4 = ;
else *PAO4 = ; if(((GPIOA->IDR) & 0x2000) ==0x2000) GPIOA->ODR = GPIOA->ODR | 0x20;
else GPIOA->ODR = GPIOA->ODR & ~0x20;
if(((GPIOA->IDR) & 0x4000) ==0x4000) GPIOA->ODR = GPIOA->ODR | 0x40;
else GPIOA->ODR = GPIOA->ODR & ~0x40;
if(((GPIOA->IDR) & 0x8000) ==0x8000) GPIOA->ODR = GPIOA->ODR | 0x80;
else GPIOA->ODR = GPIOA->ODR & ~0x80;
} return ;
}

使用#define(宏)强大功能优化代码:

 #include "stm32f10x_gpio.h"
#define GPIOA_ODR_A (GPIOA_BASE+0x0C)
#define GPIOA_IDR_A (GPIOA_BASE+0x08)
#define GPIOA_ODR_B (GPIOB_BASE+0x0C)
#define GPIOA_IDR_B (GPIOB_BASE+0x08)
#define GPIOA_ODR_C (GPIOC_BASE+0x0C)
#define GPIOA_IDR_C (GPIOC_BASE+0x08)
#define GPIOA_ODR_D (GPIOD_BASE+0x0C)
#define GPIOA_IDR_D (GPIOD_BASE+0x08)
#define GPIOA_ODR_E (GPIOE_BASE+0x0C)
#define GPIOA_IDR_E (GPIOE_BASE+0x08)

//使用volatile关键字使得编译器不优化volatile关键字之后的代码;还有个其他功能待定
#define BitBand(Addr, BitNum) *((volatile unsigned long *)((Addr&0xF0000000)+0x2000000 +((Addr&0xfffff)<<5)+(BitNum<<2)))
#define PAout(n) BitBand(GPIOA_ODR_A, n)
#define PAin(n) BitBand(GPIOA_IDR_A, n) int main()
{
//0x4200 0000 + ((A-0x4000 0000)*8+n)*4
u32 *PAO4 = (u32*)(0x42000000 + ((GPIOA_BASE+0x0C-0x40000000)*+)*);
u32 *PAI12 = (u32*)(0x42000000 + ((GPIOA_BASE+0x09-0x40000000)*+)*);
//设置GPIOA引脚上的工作模式,GPIOA: 0, GPIOA:1 推挽输出而不是复用输出, 工作速率:50hz;
// GPIOA->CRL = 0x33;
// //在相应引脚上设置相应电平;
// GPIOA->ODR = 0x00; //输出0
// GPIOA->ODR = 0x03; //设置11,输出高电平,而不再是单片机中1; //设置GPIOA工作模式;
//PA0 输出, 50hz,PA8 输入
GPIOA->CRL = 0x33333333;
GPIOA->CRH = 0X44444444; while()
{
if(((GPIOA->IDR) & 0x0100) ==0x0100) GPIOA->ODR = GPIOA->ODR | 0x01;
else GPIOA->ODR = GPIOA->ODR & ~0x01;
if(((GPIOA->IDR) & 0x0200) ==0x0200) GPIOA->ODR = GPIOA->ODR | 0x02;
else GPIOA->ODR = GPIOA->ODR & ~0x02;
if(((GPIOA->IDR) & 0x0400) ==0x0400) GPIOA->ODR = GPIOA->ODR | 0x04;
else GPIOA->ODR = GPIOA->ODR & ~0x04; if(((GPIOA->IDR) & 0x0800) ==0x0800) GPIOA->ODR = GPIOA->BSRR | 0x08; //BSRR端口位设置/复位寄存器
else GPIOA->ODR = GPIOA->BRR & ~0x08; // BRR端口位复位寄存器(GPIOx_BRR) //根据位绑定公式;
//A = GPIOA_BASE+IDR的偏移地址是GPIOA->IDR = GPIOA_BASE+0x08 n = 4;
// A = GPIOA_BASE+ODR的偏移地址是GPIOA->ODR = GPIOA_BASE+0x0C n = 4;
//n=4 ,因为是GPIOA->ODR中的第四位(0x10,从0位开始算);
// if(((GPIOA->IDR) & 0x1000) ==0x1000) *PAO4 = 1; //GPIOA->ODR = GPIOA->ODR | 0x10;
// else *PAO4 = 0; //GPIOA->ODR = GPIOA->ODR & ~0x10;
if(*PAI12 == ) *PAO4 = ;
else *PAO4 = ; // if(((GPIOA->IDR) & 0x2000) ==0x2000) GPIOA->ODR = GPIOA->ODR | 0x20;
// else GPIOA->ODR = GPIOA->ODR & ~0x20;
// if(((GPIOA->IDR) & 0x4000) ==0x4000) GPIOA->ODR = GPIOA->ODR | 0x40;
// else GPIOA->ODR = GPIOA->ODR & ~0x40;
// if(((GPIOA->IDR) & 0x8000) ==0x8000) GPIOA->ODR = GPIOA->ODR | 0x80;
// else GPIOA->ODR = GPIOA->ODR & ~0x80;
if(PAin()==) PAout()=;
else PAout()=;
if(PAin()==) PAout()=;
else PAout()=;
if(PAin()==) PAout()=;
else PAout()=;
} return ;
}

stm32之GPIO的更多相关文章

  1. STM32的GPIO口的输出开漏输出和推挽输出

    本文来自cairang45的博客,讲述了STM32的GPIO口的输出开漏输出和推挽输出, 作者博客:http://blog.ednchina.com/cairang45 本文来自: 高校自动化网(Ww ...

  2. STM32的GPIO使用的函数剖析

    转载http://blog.csdn.net/wuwuhuizheyisheng/article/details/8239599 STM32的GPIO总结 作者:JCY 该文是自己学习了一段STM32 ...

  3. stm32之GPIO(二)

    输入上拉:当IO口作为输入时,比如按键输入,而按键是与地连接,按下时为低电平,则没按下时该IO口应为高电平,上拉即是该IO口通过一个电阻与电源相连,则没按下时为高电平,按下即为低电平. 输入下拉:同理 ...

  4. STM32配置GPIO前须先打开其时钟,否则配置失败

    @2018-5-9 17:11:38 STM32配置GPIO前须先打开其时钟,否则配置失败

  5. STM32 F4 GPIO Modes

    STM32 F4 GPIO Modes Goal: creating a visual summary of GPIO configuration modes. The summary at the ...

  6. STM32的GPIO工作原理 | 附电路图详细分析

    STM32的GPIO介绍 STM32引脚说明 GPIO是通用输入/输出端口的简称,是STM32可控制的引脚.GPIO的引脚与外部硬件设备连接,可实现与外部通讯.控制外部硬件或者采集外部硬件数据的功能. ...

  7. STM32之GPIO操作

    啊哈.没办法.外国人的芯片就喜欢用英文来命名,所以中文的:通用输入/输出  就用GPIO来代替..谁叫哥们都不是外国人呢.好啦.胡扯了一下,借用唐伯虎点秋香的话:小小书童,可笑可笑... 知道了GPI ...

  8. STM32学习笔记(三) STM32的GPIO的深入学习

    STM32的开发学习主要涉及软硬件两个部分的实现,包含众多外设和总线的理解配置.STM32的整个学习曲线并不陡峭,但入门却相当困难,因此在学习之初,多动手实验和测试相当重要,GPIO作为整个STM32 ...

  9. STM32 常用GPIO操作函数记录

    STM32读具体GPIOx的某一位是1还是0 /** * @brief Reads the specified input port pin. * @param GPIOx: where x can ...

随机推荐

  1. kali nessus 安装插件失败解决方法

    code码获取: http://www.tenable.com/products/nessus/select-your-operating-system 首先切换到nessus安装目录下: 1.nes ...

  2. Understanding and Selecting a SIEM/LM: Correlation and Alerting

    Continuing our discussion of core SIEM and Log Management technology, we now move into event correla ...

  3. 没有开发者账号,如何解锁wp8设备

    原文 http://www.cnblogs.com/vsdot/p/3263454.html 问题的引入 好了,问题的由来是这样的,我想把我开发的wp8手机部署到手机上,可是竟然出现了下面的问题: [ ...

  4. Angulajs 定时器使用

    在Angulajs的control中,不能利用 window.setInterval和 setTimeout 来操作定时器,因为这样做,虽然设置定时器会成功,但对$scope中的数据进行设置时,不会自 ...

  5. 一个int 数组,里面数据无任何限制,要求求出所有这样的数a[i],其左边的数都小于等于它,右边的数都大于等于它。能否只用一个额外数组和少量其它空间实现。

    一个int数组, 比如 array[],里面数据无任何限制,要求求出 所有这样的数array[i],其左边的数都小于等于它,右边的数都大于等于它.能否只用一个额外数组和少量其它空间实现. 分析:这题很 ...

  6. 用Visual C++设计“精灵”窗体

    随着Microsoft凭借Windows在操作系统上取得的巨大成绩,Windows用户界面也日益成为业界标准.统一的界面给广大用户对应用软件的学习与使用带来了很大方便.但每天都面对同一副面孔,日久天长 ...

  7. USACO 2001 OPEN

    第1题 绿组. 奶牛接力赛[relay] 题目描述 农夫约翰已经为一次赛跑选出了K(2≤K≤40)头牛组成了一支接力队.赛跑在农夫约翰所拥有的农场上进行,农场的编号为1到Ⅳf4≤Ⅳ< 800), ...

  8. UBER司机奖励政策

    高峰时段: 早高峰:早6:30-8:30点 晚高峰:晚4:00-7:00点 *周六日只有晚高峰 其他时间均为平峰时段 滴滴快车单单2.5倍,注册地址:http://www.udache.com/如何注 ...

  9. CSDN资源页面挂掉了?

    想上传几个文件,结果打不开了

  10. STM32菜鸟成长记录---RS485通讯协议的应用

    写作原因:近来蛋闲?非也  !  昨天一同事合作的项目代码出现的bug-----他的上位机每200ms给我发送命令向我这边下位机读取一些数据,在此过程会按下按键做一些另外操作并给他返回数据:(通信是通 ...