野火电子论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 2562|回复: 2

STM32指南者位带操作出现warning

[复制链接]
发表于 2023-4-3 21:10:33 | 显示全部楼层 |阅读模式
具体的代码为
led部分
  1. #ifndef __LED_H_
  2. #define __LED_H_

  3. #include "stm32f10x.h"

  4. //red
  5. #define LED1_GPIO_PORT  GPIOB
  6. #define LED1_GPIO_CLK   RCC_APB2Periph_GPIOB
  7. #define LED1_GPIO_PIN   GPIO_Pin_5

  8. //green
  9. #define LED2_GPIO_PORT  GPIOB
  10. #define LED2_GPIO_CLK   RCC_APB2Periph_GPIOB
  11. #define LED2_GPIO_PIN   GPIO_Pin_0

  12. //blue
  13. #define LED3_GPIO_PORT  GPIOB
  14. #define LED3_GPIO_CLK   RCC_APB2Periph_GPIOB
  15. #define LED3_GPIO_PIN   GPIO_Pin_1

  16. //直接操作寄存器的方法控制IO
  17. #define digitalHi(p,i)  {p->BSRR=i;} //输出高电平
  18. #define digitalLo(p,i)  {p->BRR=i;}  //输出低电平
  19. #define digitalToggle(p,i)  {p->ODR ^=i;} //输出反转状态

  20. //定义控制IO的宏
  21. #define LED1_TOGGLE digitalToggle(LED1_GPIO_PORT,LED1_GPIO_PIN)
  22. #define LED1_OFF  digitalHi(LED1_GPIO_PORT,LED1_GPIO_PIN)
  23. #define LED1_ON  digitalLo(LED1_GPIO_PORT,LED1_GPIO_PIN)

  24. #define LED2_TOGGLE digitalToggle(LED2_GPIO_PORT,LED2_GPIO_PIN)
  25. #define LED2_OFF  digitalHi(LED2_GPIO_PORT,LED2_GPIO_PIN)
  26. #define LED2_ON  digitalLo(LED2_GPIO_PORT,LED2_GPIO_PIN)

  27. #define LED3_TOGGLE digitalToggle(LED3_GPIO_PORT,LED3_GPIO_PIN)
  28. #define LED3_OFF  digitalHi(LED3_GPIO_PORT,LED3_GPIO_PIN)
  29. #define LED3_ON  digitalLo(LED3_GPIO_PORT,LED3_GPIO_PIN)

  30. //基本混色
  31. //红
  32. #define LED_RED \
  33.                     LED1_ON;\
  34.                     LED2_OFF;\
  35.                     LED3_OFF;

  36. //绿
  37. #define LED_GREEN \
  38.                     LED1_OFF;\
  39.                     LED2_ON;\
  40.                     LED3_OFF;

  41. //蓝
  42. #define LED_BLUE \
  43.                     LED1_OFF;\
  44.                     LED2_OFF;\
  45.                     LED3_ON;

  46. //黄(红+绿)
  47. #define LED_YELLOW \
  48.                     LED1_ON;\
  49.                     LED2_ON;\
  50.                     LED3_OFF;

  51. //紫(红+蓝)
  52. #define LED_PURPLE \
  53.                     LED1_ON;\
  54.                     LED2_OFF;\
  55.                     LED3_ON;

  56. //青(绿+蓝)
  57. #define LED_CYAN \
  58.                     LED1_OFF;\
  59.                     LED2_ON;\
  60.                     LED3_ON;

  61. //白(红+绿+蓝)
  62. #define LED_WHITE \
  63.                     LED1_ON;\
  64.                     LED2_ON;\
  65.                     LED3_ON;

  66. //黑
  67. #define LED_BLACK \
  68.                     LED1_OFF;\
  69.                     LED2_OFF;\
  70.                     LED3_OFF;

  71. void LED_GPIO_Config(void);
  72. #endif
复制代码


  1. #include "led.h"

  2. void LED_GPIO_Config(void)
  3. {
  4.     /*定义一个GPIO_InitTypeDef类型的结构体*/
  5.     GPIO_InitTypeDef GPIO_InitStructure;
  6.     /*开启LED相关的GPIO外设时钟*/
  7.     RCC_APB2PeriphClockCmd(LED1_GPIO_CLK|LED2_GPIO_CLK|LED3_GPIO_CLK, ENABLE);
  8.     /*选择需要控制的GPIO引脚*/
  9.     GPIO_InitStructure.GPIO_Pin = LED1_GPIO_PIN;
  10.     /*设置引脚模式为通用推挽输出*/
  11.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  12.     /*设置引脚速率为50MHZ*/
  13.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  14.     /*调用库函数,初始化GPIO*/
  15.     GPIO_Init(LED1_GPIO_PORT,&GPIO_InitStructure);
  16.     /*选择要控制的GPIO引脚*/
  17.     GPIO_InitStructure.GPIO_Pin = LED2_GPIO_PIN;
  18.     /*调用库函数,初始化GPIO*/
  19.     GPIO_Init(LED2_GPIO_PORT,&GPIO_InitStructure);
  20.     /*选择要控制的GPIO引脚*/
  21.     GPIO_InitStructure.GPIO_Pin = LED3_GPIO_PIN;
  22.     /*调用库函数,初始化GPIO*/
  23.     GPIO_Init(LED3_GPIO_PORT,&GPIO_InitStructure);
  24.     /*关闭所有LED灯*/
  25.     GPIO_SetBits(LED1_GPIO_PORT,LED1_GPIO_PIN);
  26.     GPIO_SetBits(LED2_GPIO_PORT,LED2_GPIO_PIN);
  27.     GPIO_SetBits(LED3_GPIO_PORT,LED3_GPIO_PIN);
  28. }
复制代码
主函数部分

  1. #include "stm32f10x.h"
  2. #include "./led/led.h"

  3. //把“位带地址+序列号”转换成别名地址的宏
  4. #define BITBAND(addr,bitnum)  ((addr & 0xF00000000) + 0x02000000 + ((addr & 0x00FFFFF)<<5) + (bitnum << 2))
  5. //把一个地址转换成一个指针
  6. #define MEM_ADDR(addr)  *((volatile unsigned long  *)(addr))
  7. //把位带别名区地址转换成指针
  8. #define BIT_ADDR(addr, bitnum)  MEM_ADDR(BITBAND(addr, bitnum))

  9. //GPIO_ODR和IDR寄存器地址映射
  10. #define GPIOA_ODR_Addr  (GPIOA_BASE + 0x0C)
  11. #define GPIOB_ODR_Addr  (GPIOB_BASE + 0x0C)
  12. #define GPIOC_ODR_Addr  (GPIOC_BASE + 0x0C)
  13. #define GPIOD_ODR_Addr  (GPIOD_BASE + 0x0C)
  14. #define GPIOE_ODR_Addr  (GPIOE_BASE + 0x0C)
  15. #define GPIOF_ODR_Addr  (GPIOF_BASE + 0x0C)
  16. #define GPIOG_ODR_Addr  (GPIOG_BASE + 0x0C)

  17. #define GPIOA_IDR_Addr  (GPIOA_BASE + 0x08)
  18. #define GPIOB_IDR_Addr  (GPIOB_BASE + 0x08)
  19. #define GPIOC_IDR_Addr  (GPIOC_BASE + 0x08)
  20. #define GPIOD_IDR_Addr  (GPIOD_BASE + 0x08)
  21. #define GPIOE_IDR_Addr  (GPIOE_BASE + 0x08)
  22. #define GPIOF_IDR_Addr  (GPIOF_BASE + 0x08)
  23. #define GPIOG_IDR_Addr  (GPIOG_BASE + 0x08)

  24. //单独操作GPIO的某一个IO口,n(0,1,2,...15),n表示具体是哪一个IO口
  25. #define PAout(n)  BIT_ADDR(GPIOA_ODR_Addr,n)
  26. #define PAin(n)  BIT_ADDR(GPIOA_IDR_Addr,n)

  27. #define PBout(n)  BIT_ADDR(GPIOB_ODR_Addr,n)
  28. #define PBin(n)  BIT_ADDR(GPIOB_IDR_Addr,n)

  29. #define PCout(n)  BIT_ADDR(GPIOC_ODR_Addr,n)
  30. #define PCin(n)  BIT_ADDR(GPIOC_IDR_Addr,n)

  31. #define PDout(n)  BIT_ADDR(GPIOD_ODR_Addr,n)
  32. #define PDin(n)  BIT_ADDR(GPIOD_IDR_Addr,n)

  33. #define PEout(n)  BIT_ADDR(GPIOE_ODR_Addr,n)
  34. #define PEin(n)  BIT_ADDR(GPIOE_IDR_Addr,n)

  35. #define PFout(n)  BIT_ADDR(GPIOF_ODR_Addr,n)
  36. #define PFin(n)  BIT_ADDR(GPIOF_IDR_Addr,n)

  37. #define PGout(n)  BIT_ADDR(GPIOG_ODR_Addr,n)
  38. #define PGin(n)  BIT_ADDR(GPIOG_IDR_Addr,n)

  39. void SOFT_Delay(__IO uint32_t count);

  40. int main(void)
  41. {
  42.     LED_GPIO_Config();
  43.     while(1)
  44.     {
  45.         PBout(0) = 0;
  46.         SOFT_Delay(0x0FFFFF);
  47.         PBout(0) = 1;
  48.         SOFT_Delay(0x0FFFFF);
  49.         PBout(1) = 0;
  50.         SOFT_Delay(0x0FFFFF);
  51.         PBout(1) = 1;
  52.         SOFT_Delay(0x0FFFFF);
  53.         PBout(5) = 0;
  54.         SOFT_Delay(0x0FFFFF);
  55.         PBout(5) = 1;
  56.         SOFT_Delay(0x0FFFFF);
  57.     }

  58. }

  59. void SOFT_Delay(__IO uint32_t count)
  60. {
  61.     for(;count != 0;count--);
  62. }
复制代码
问题为从整型数据到较小指针,参考的是零死角玩转stm32。指针是unsigned long定义的数据型,照理说不应该比int小。头一回遇到这种报错,不知道咋解决,希望大家不吝赐教,谢谢!
回复

使用道具 举报

 楼主| 发表于 2023-4-3 21:24:18 | 显示全部楼层
问题已解决,出现问题的原因是:将位带地址+序列号转换成别名地址时,地址转换公式输入错误。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-4-3 21:26:40 | 显示全部楼层
#define BITBAND(addr,bitnum)  ((addr & 0xF00000000) + 0x02000000 + ((addr & 0x00FFFFF)<<5) + (bitnum << 2))
addr取最高位时,多打了个0,导致取不出来应该是。然后在屏蔽高两位时,少打了一位F,导致屏蔽了3位。导致地址指针乱飞,出现了意料之外的错误。
回复 支持 反对

使用道具 举报

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

本版积分规则

联系站长|手机版|野火电子官网|野火淘宝店铺|野火电子论坛 ( 粤ICP备14069197号 ) 大学生ARM嵌入式2群

GMT+8, 2024-5-14 05:13 , Processed in 0.046289 second(s), 23 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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