自学STM32---GPIO

来源:互联网 发布:非淘宝订单用电子面单 编辑:程序博客网 时间:2024/04/29 10:18
1、STM32有5组GPIO引脚,分别是GPIOA,GPIOB,GPIOC,GPIOD,GPIOE,每组GPIO有16个引脚。
2、每个引脚都有4个位来配置其端口,可以配置出不同的输入\输出模式
表1配置IO口输出方式

配置模式 CNF1 CNF2 M1  M0 

推挽式输出 0  0 1 1 50MHz速度

开漏输出 01   0   110MHz速度

复用推挽式输出 0 0 10 2MHz速度
复用开漏输出 1 1 1 1 50MHz速度
模拟输入 0 0   0   0
浮空输入 01   0   0
下拉输入 10  0  0  
上拉输入 11  0   0 

M0 M1输出速度 0  1  10MHz ;   1   0   2MHz;   1    1  50MHz
3、GPIOA->CRL(32位) 是用来配置低8个引脚的,GPIOA->CRH(32位) 是用来配置高8个引脚的。配置方式见参考手册
4、GPIOA->IDR(32位,只用到低16位配置对应16个引脚)是用来配置端口输入数据寄存器的(外设->MCU)。
5、GPIOA->ODR(32位,只用到低16位配置对应16个引脚)是用来配置端口输出数据寄存器的(MCU->外设)。
6、用软件仿真的时候,如果在一个引脚给如一个高电平,只能在Pins相应的位打上√(看程序里的第3次课代码调试)
7、位运算主要有&  |  ~(取反)  <<  >>  ^(异或)  等操作,因为都是针对寄存器编程,寄存器的引脚状态就0和1,所以一般用位运算。STM32不同于51和其他单片机,它内部有集成了2个对位运算的寄存器(BSRR对某一位置1,BRR对某一位清0)。这样运算的速度快,代码量少,效率高出很多倍。(具体见GPIO程序第4节课的例子)。(位运算与或的作用,清0,置1,隐藏)。
8、位绑定 把某一位映射到内存地址上,对地址的最低位进行操作来把引脚这一位给置1和清0.
位n 映射内存地址a
n = 0/1 a = 0 2 4 8(最低位为0)/1 3 5 7(最低位为1)
传统置1和清0需要3步完成,读  修改  写
只有STM32以下2个区的位才可以进行位绑定(可以看参考手册2.3节内存分布图)
SRAM区 0x2000 0000~0x200fffff1M(20位,2~20=1M)(n = 0~7,A=0x2000 0000~0x200fffff)
公式:AliasAddr = 0x22000000 + ((A-0x2000 0000)*8 +n)*4
      = 0x22000000 + (A-0x2000 0000)*32 +n*4
片上外设 0x4000 0000~ 0x400f ffff 1M  (n = 0~31,A=0x4000 0000~0x400f ffff)
公式:AliasAddr = 0x42000000 + ((A-0x4000 0000)*8 +n)*4
      = 0x42000000 + (A-0x4000 0000)*32 +n*4
  例子:把GPIOA的6位作为输出,GPIOA的14位作为输入,用位绑定的方式对其进行位操作
//A = GPIOA_BASE + ODR偏移地址 = GPIOA_BASE + 0x0c      n = 6
//A = GPIOA_BASE + IDR偏移地址 = GPIOA_BASE + 0x08        n = 14
//AliasAddr = 0x42000000 + (A-0x4000 0000)*32 +n*4
u32 *PAO6 = (u32 *) (0x42000000 + (0x4001080c - 0x40000000)*32 + 6*4);0c为输出的偏移地址(手册),第6位n=6
u32 *PAI14 = (u32 *) (0x42000000 + (0x40010808 - 0x40000000)*32 + 14*4);08为输入的偏移地址(手册),第14位n=14

if (*PAI14 == 1)*PAO6 = 1;//1也可以换成其他的奇数,只要满足最低位为1
else *PAO6 = 0;//0也可以换成其他的偶数,只要满足最低位为0

/***通用位绑定GPIO端口****/
#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)
位绑定的指定位的地址中的值 绑定的地址的类型    取地址最高位(2或4)  次高位  取低5位并*32   相应的位n*4
#define BitBand(Addr,BitNum)*(volatile unsigned long *)((Addr & 0xf0000000) + 0x2000000+ ((Addr & 0xfffff)<<5) + (BitNum<<2))
//在MCU运算处理器中,位运算比乘法运算要快(左移n等价于乘以2~n;右移n位等价于除以2~n),volatile关键字的作用是告诉编译器,这处的代码不需要
//去优化它,直接从源头处去读取就行了。

#define PAout(n)   BitBand(GPIOA_ODR_A,n)
#define PAin(n)    BitBand(GPIOA_IDR_A,n)
#define PBout(n)   BitBand(GPIOB_ODR_B,n)
#define PBin(n)    BitBand(GPIOB_IDR_B,n)
#define PCout(n)   BitBand(GPIOC_ODR_C,n)
#define PCin(n)    BitBand(GPIOC_IDR_C,n)
#define PDout(n)   BitBand(GPIOD_ODR_D,n)
#define PDin(n)    BitBand(GPIOD_IDR_D,n)
#define PEout(n)   BitBand(GPIOE_ODR_E,n)
#define PEin(n)    BitBand(GPIOE_IDR_E,n)

/****操作测试****/
if(PAin(14) == 1)PAout(6) = 1;
else PAout(6) = 0
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 经典家庭伦txt丝母韵欲d下载 经典家庭伦txt丝母韵欲视频 长篇都市情感小说 经典家庭伦全文 久九九久精品免费视频 91在线中文字幕香蕉人人视频 经典家庭伦txt岳丝母小丹韵欲阅读 碰超上线视频人人视频千人 91青青碰起上线视频人人 车里太挤姑妈坐我腿上做小说 经典家庭伦txt岳丝母小丹韵欲小说 我的丝母欲韵第六节 91在线中文久人人视频动漫 悉母全集动漫完整视频 类别中文动漫中的视频 腐母动漫全集视频时长 86 母汁视频动漫 久99久视频精品免费观看38 难以忍耐动漫视频中文 久九九久手机视频 乳娘家教动漫无删减在线播放 久99久精品视频只有精品 母恋人2017中文 久九九久视频精品6思思 巨母3动漫在线 久99久视频精品免费视频动漫 水柔姐大战儿子视频91 久九九久视频精品 99视频国内99视频在线观 横恋人母日语中字 玖玖视频热线视频大全 九九视频热线视频大全动漫 99ra视频这里只精品 九九久视频热线视频 九九久视频热线视频精品 九九视频本韩视频 9久9久女女视频精品mp4 久99久精品免费观看15 久99久只有视频精品18 久九九久视频精品图片 久了久视频这里精品23