找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1586|回复: 10
收起左侧

stm32单片机位带操作怎么用寄存器手册来编写?

[复制链接]
ID:302293 发表于 2023-9-6 11:45 | 显示全部楼层 |阅读模式
比如普冉F003的位带,根据寄存器手册来编写,应该怎么写,有思路的大侠指点一下
回复

使用道具 举报

ID:883242 发表于 2023-9-6 16:50 | 显示全部楼层
  1. // 把“位带地址+位序号”转换成别名地址的宏
  2. #define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x02000000+((addr & 0x000FFFFF)<<5)+(bitnum<<2))

  3. // 把一个地址转换成一个指针
  4. #define MEM_ADDR(addr)  *((volatile unsigned long  *)(addr))

  5. // 把位带别名区地址转换成指针
  6. #define BIT_ADDR(addr, bitnum)   MEM_ADDR(BITBAND(addr, bitnum))


  7. // GPIO ODR 和 IDR 寄存器地址映射
  8. #define GPIOA_ODR_Addr    (GPIOA_BASE+20)
  9. #define GPIOB_ODR_Addr    (GPIOB_BASE+20)   
  10. #define GPIOC_ODR_Addr    (GPIOC_BASE+20)  
  11. #define GPIOD_ODR_Addr    (GPIOD_BASE+20)
  12. #define GPIOE_ODR_Addr    (GPIOE_BASE+20)
  13. #define GPIOF_ODR_Addr    (GPIOF_BASE+20)      
  14. #define GPIOG_ODR_Addr    (GPIOG_BASE+20)
  15. #define GPIOH_ODR_Addr    (GPIOH_BASE+20)      
  16. #define GPIOI_ODR_Addr    (GPIOI_BASE+20)
  17. #define GPIOJ_ODR_Addr    (GPIOJ_BASE+20)      
  18. #define GPIOK_ODR_Addr    (GPIOK_BASE+20)

  19. #define GPIOA_IDR_Addr    (GPIOA_BASE+16)  
  20. #define GPIOB_IDR_Addr    (GPIOB_BASE+16)  
  21. #define GPIOC_IDR_Addr    (GPIOC_BASE+16)   
  22. #define GPIOD_IDR_Addr    (GPIOD_BASE+16)  
  23. #define GPIOE_IDR_Addr    (GPIOE_BASE+16)   
  24. #define GPIOF_IDR_Addr    (GPIOF_BASE+16)   
  25. #define GPIOG_IDR_Addr    (GPIOG_BASE+16)  
  26. #define GPIOH_IDR_Addr    (GPIOH_BASE+16)
  27. #define GPIOI_IDR_Addr    (GPIOI_BASE+16)
  28. #define GPIOJ_IDR_Addr    (GPIOJ_BASE+16)
  29. #define GPIOK_IDR_Addr    (GPIOK_BASE+16)


  30. // 单独操作 GPIO的某一个IO口,n(0,1,2...16),n表示具体是哪一个IO口
  31. #define PAout(n)   BIT_ADDR(GPIOA_ODR_Addr,n)  //输出   
  32. #define PAin(n)    BIT_ADDR(GPIOA_IDR_Addr,n)  //输入   

  33. #define PBout(n)   BIT_ADDR(GPIOB_ODR_Addr,n)  //输出   
  34. #define PBin(n)    BIT_ADDR(GPIOB_IDR_Addr,n)  //输入   

  35. #define PCout(n)   BIT_ADDR(GPIOC_ODR_Addr,n)  //输出   
  36. #define PCin(n)    BIT_ADDR(GPIOC_IDR_Addr,n)  //输入   

  37. #define PDout(n)   BIT_ADDR(GPIOD_ODR_Addr,n)  //输出   
  38. #define PDin(n)    BIT_ADDR(GPIOD_IDR_Addr,n)  //输入   

  39. #define PEout(n)   BIT_ADDR(GPIOE_ODR_Addr,n)  //输出   
  40. #define PEin(n)    BIT_ADDR(GPIOE_IDR_Addr,n)  //输入  

  41. #define PFout(n)   BIT_ADDR(GPIOF_ODR_Addr,n)  //输出   
  42. #define PFin(n)    BIT_ADDR(GPIOF_IDR_Addr,n)  //输入  

  43. #define PGout(n)   BIT_ADDR(GPIOG_ODR_Addr,n)  //输出   
  44. #define PGin(n)    BIT_ADDR(GPIOG_IDR_Addr,n)  //输入  

  45. #define PHout(n)   BIT_ADDR(GPIOH_ODR_Addr,n)  //输出   
  46. #define PHin(n)    BIT_ADDR(GPIOH_IDR_Addr,n)  //输入  

  47. #define PIout(n)   BIT_ADDR(GPIOI_ODR_Addr,n)  //输出   
  48. #define PIin(n)    BIT_ADDR(GPIOI_IDR_Addr,n)  //输入

  49. #define PJout(n)   BIT_ADDR(GPIOJ_ODR_Addr,n)  //输出   
  50. #define PJin(n)    BIT_ADDR(GPIOJ_IDR_Addr,n)  //输入  

  51. #define PKout(n)   BIT_ADDR(GPIOK_ODR_Addr,n)  //输出   
  52. #define PKin(n)    BIT_ADDR(GPIOK_IDR_Addr,n)  //输入  
复制代码
回复

使用道具 举报

ID:1093023 发表于 2023-9-9 23:27 | 显示全部楼层
以PD7为例说明,在H文件中使用宏定义+库函数
1、对于输出状态来说:
#define  PD7_Outstatus  GPIO_ReadOutputDataBit(GPIOD,GPIO_Pin_7)  //PD7的输出状态
2、对于输入状态来说
#define  PD7_Instatus  GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_7)  //PD7的输入状态

在C文件中:
1、对PD7进行初始化,开启外设时钟,设定是输入还是输出模式等。注意,不能设定既是输入又是输出!
2、判断PD7输入的状态
if(PD7_Instatus==1){.....}
if(PD7_Instatus==0){.....}
3、判断PD7输出的状态
if(PD7_Outstatus==1){.....}
if(PD7_Outstatus==0){.....}
3、对于输出置0或置1来说,可以在H文件用宏定义,也可以在C文件中创建函数
宏定义:
#define  PD7_Out=1  GPIO_SetBits(GPIOD, GPIO_Pin_7)  //PD7输出1
#define  PD7_Out=0  GPIO_ResetBits(GPIOD, GPIO_Pin_7)  //PD7输出0
函数:
void PD7_Out(u8 Cmd)
{
       if(Cmd==0)  GPIO_ResetBits(GPIOD, GPIO_Pin_7)  //PD7输出0
else if(Cmd==1)  GPIO_SetBits(GPIOD, GPIO_Pin_7)  //PD7输出1
}
函数调用:
PD7_Out(1); //输出1
PD7_Out(0); //输出0
回复

使用道具 举报

ID:883242 发表于 2023-9-10 03:30 | 显示全部楼层
zhangqi_12345 发表于 2023-9-9 23:27
以PD7为例说明,在H文件中使用宏定义+库函数
1、对于输出状态来说:
#define  PD7_Outstatus  GPIO_ReadO ...

你先去查查什么叫位带bitband再来发言。
回复

使用道具 举报

ID:434018 发表于 2023-9-10 10:53 | 显示全部楼层
提醒:并非所有的STM32都支援bitband,如M0不支援.
回复

使用道具 举报

ID:1093023 发表于 2023-9-10 20:54 | 显示全部楼层
这些指令你看懂没?你没看懂,建议你先去学习后再吐槽
回复

使用道具 举报

ID:1093023 发表于 2023-9-10 20:59 | 显示全部楼层
frank_tw 发表于 2023-9-10 10:53
提醒:并非所有的STM32都支援bitband,如M0不支援.

还是你懂!
回复

使用道具 举报

ID:747496 发表于 2023-9-11 09:36 | 显示全部楼层
这个还是F4系列的,F1的还不一样。
如下:
#define GPIOA_ODR_Addr    (GPIOK_BASE+16)  // F103

#define GPIOA_IDR_Addr    (GPIOA_BASE+12)  //F103
回复

使用道具 举报

ID:647261 发表于 2023-9-11 10:59 | 显示全部楼层
位带操作需要硬件支持,其目的是实现类似51那样的sbit xx P0^1这样的单独操作某IO口
用宏定义函数也可以同样实现,不用一定要位带操作的
回复

使用道具 举报

ID:1092275 发表于 2023-9-13 08:03 | 显示全部楼层
位带操作需要硬件支持
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表