OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 5840|回复: 13

使用寄存器地址在PB5输出低电平

[复制链接]

1

主题

3

帖子

0

精华

新手入门

积分
6
金钱
6
注册时间
2023-6-27
在线时间
0 小时
发表于 2023-6-27 21:49:44 | 显示全部楼层 |阅读模式
1金钱
本人用的是战舰V3,现在想让PB5输出低电平点亮一个LED灯,我想从地址访问过程中的各个寄存器,主要就三个,一个是时钟使能,一个是端口配置的CR L,还有一个是输出数据寄存器ODR,但是编译能通过程序,始终没有得到相应的结果,检查了几遍地址还是没有发现问题,麻烦各位大佬指正一下,程序如下:#include "stm32f10x.h"
int main(void)
        {
                *( unsigned int * ) 0x40021018 |=( (1)<< 3);//打开PB端口的时钟
                *( unsigned int * ) 0x40010C00 |=( (1)<< ( 4*0) );//输出配置寄存器GPIOB_CRL将PB口配置为推挽输出(默认端口输出即为推挽模式)
                *( unsigned int *) 0x40010c0c &= ~( (1)<< (5*0));//输出数据寄存器GPIOB_ODR地址为0x40010c0c,其第五位输出零
               
        }

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

11

主题

2103

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4588
金钱
4588
注册时间
2015-1-10
在线时间
574 小时
发表于 2023-6-28 11:01:03 | 显示全部楼层
what?你这么写代码也泰裤了吧?不是直接可以结构体指向寄存器吗
回复

使用道具 举报

31

主题

1951

帖子

3

精华

论坛元老

Rank: 8Rank: 8

积分
4418
金钱
4418
注册时间
2018-5-11
在线时间
923 小时
发表于 2023-6-28 11:24:36 | 显示全部楼层
本帖最后由 warship 于 2023-6-28 11:39 编辑

既然#include "stm32f10x.h",
就要充分利用这个头文件,
寄存器的地址在这个头文件中都有定义,
实在没有必要直接用绝对地址,
简单看了一下你的代码,
STM32的寄存器基本都是32位的,
比如CRL,用 (unsigned int * )是不合适的。
另外,4*0、5*0是什么鬼?


我的开源链接 https://github.com/ShuifaHe/STM32.git  请关注,点赞支持哦。
回复

使用道具 举报

1

主题

3

帖子

0

精华

新手入门

积分
6
金钱
6
注册时间
2023-6-27
在线时间
0 小时
 楼主| 发表于 2023-6-28 11:51:30 | 显示全部楼层
warship 发表于 2023-6-28 11:24
既然#include "stm32f10x.h",
就要充分利用这个头文件,
寄存器的地址在这个头文件中都有定义,

如果要用绝对地址,那要怎么改,我试了一下改成(unsigned long*)也不行
回复

使用道具 举报

1

主题

3

帖子

0

精华

新手入门

积分
6
金钱
6
注册时间
2023-6-27
在线时间
0 小时
 楼主| 发表于 2023-6-28 11:51:58 | 显示全部楼层
阿侑kevin 发表于 2023-6-28 11:01
what?你这么写代码也泰裤了吧?不是直接可以结构体指向寄存器吗

只是练习一下,我也是新手
回复

使用道具 举报

31

主题

1951

帖子

3

精华

论坛元老

Rank: 8Rank: 8

积分
4418
金钱
4418
注册时间
2018-5-11
在线时间
923 小时
发表于 2023-6-28 11:58:52 | 显示全部楼层
天方过客 发表于 2023-6-28 11:51
如果要用绝对地址,那要怎么改,我试了一下改成(unsigned long*)也不行

用(uint32_t *)
我的开源链接 https://github.com/ShuifaHe/STM32.git  请关注,点赞支持哦。
回复

使用道具 举报

31

主题

1951

帖子

3

精华

论坛元老

Rank: 8Rank: 8

积分
4418
金钱
4418
注册时间
2018-5-11
在线时间
923 小时
发表于 2023-6-28 12:11:38 | 显示全部楼层
天方过客 发表于 2023-6-28 11:51
如果要用绝对地址,那要怎么改,我试了一下改成(unsigned long*)也不行

查了一下,
PB5在CRL中是从第20位开始,
推挽设置为3,
所以这一句应改为:
* (uint32_t *) 0x40010C00 |=( 3<< 20 );
我的开源链接 https://github.com/ShuifaHe/STM32.git  请关注,点赞支持哦。
回复

使用道具 举报

31

主题

1951

帖子

3

精华

论坛元老

Rank: 8Rank: 8

积分
4418
金钱
4418
注册时间
2018-5-11
在线时间
923 小时
发表于 2023-6-28 12:15:09 | 显示全部楼层
天方过客 发表于 2023-6-28 11:51
如果要用绝对地址,那要怎么改,我试了一下改成(unsigned long*)也不行

最后一句改为
* (uint32_t *)0x40010c0c &= ~( 1<< 5);//输出数据寄存器GPIOB_ODR地址为0x40010c0c,其第五位输出零
               
我的开源链接 https://github.com/ShuifaHe/STM32.git  请关注,点赞支持哦。
回复

使用道具 举报

0

主题

451

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3316
金钱
3316
注册时间
2016-3-19
在线时间
815 小时
发表于 2023-6-28 14:31:07 | 显示全部楼层
我习惯这样写

int main(void)
{
    * (volatile unsigned long *)0x40021018 |= (1 << 3);     // 打开PB端口的时钟

    * (volatile unsigned long *)0x40010C00 |= (1 << 20);    // 输出配置寄存器GPIOB_CRL将PB口配置为推挽输出(默认端口输出即为推挽模式)

    * (volatile unsigned long *)0x40010c0c |= (1 << 5);     // 输出数据寄存器GPIOB_ODR地址为0x40010c0c,其第五位输出一

    * (volatile unsigned long *)0x40010c0c &= ~(1 << 5);    // 输出数据寄存器GPIOB_ODR地址为0x40010c0c,其第五位输出零

    while (1)
    {

    }
}
Nothing is impossible
回复

使用道具 举报

0

主题

451

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3316
金钱
3316
注册时间
2016-3-19
在线时间
815 小时
发表于 2023-6-28 14:35:27 | 显示全部楼层
warship 发表于 2023-6-28 12:11
查了一下,
PB5在CRL中是从第20位开始,
推挽设置为3,

如果仅仅是输出高和低状态   不与实际功能关联的话     1、2、3 区别不大
微信截图_20230628143249.png
Nothing is impossible
回复

使用道具 举报

10

主题

213

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
5607
金钱
5607
注册时间
2016-12-19
在线时间
724 小时
发表于 2023-6-29 05:22:09 | 显示全部楼层
9楼是正确做法,要防止编译器优化,要加_IO
回复

使用道具 举报

16

主题

426

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2676
金钱
2676
注册时间
2018-11-8
在线时间
431 小时
发表于 2023-6-29 09:11:10 | 显示全部楼层

uint32_t * 不就是unsigned int *吗
回复

使用道具 举报

16

主题

426

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2676
金钱
2676
注册时间
2018-11-8
在线时间
431 小时
发表于 2023-6-29 09:16:01 | 显示全部楼层
建议先学学原子的寄存器代码再自己写 寄存器的写法不是这么弄的…… 左移那里肯定有问题
想输出低电平 GPIOB->BSRR |= GPIO_BSRR_BR5; 这样不仅简洁 还直观 这写一行查一下手册地址 不得累死
回复

使用道具 举报

31

主题

1951

帖子

3

精华

论坛元老

Rank: 8Rank: 8

积分
4418
金钱
4418
注册时间
2018-5-11
在线时间
923 小时
发表于 2023-6-29 09:44:20 | 显示全部楼层
本帖最后由 warship 于 2023-6-29 09:45 编辑
babyrabbit 发表于 2023-6-29 09:11
uint32_t * 不就是unsigned int *吗

查了一下头文件,
确实如此,typedef unsigned int uint32_t;


老的系统 int是16位的,
可能是我习惯了,
32位都用u32
我的开源链接 https://github.com/ShuifaHe/STM32.git  请关注,点赞支持哦。
回复

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-24 07:09

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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