发新帖我要提问
12
返回列表
打印
[应用相关]

STM32点灯

[复制链接]
楼主: programmable
手机看帖
扫描二维码
随时随地手机跟帖
21
programmable|  楼主 | 2019-10-21 11:08 | 只看该作者 |只看大图 回帖奖励 |倒序浏览
现在不用库做,直接操作寄存器。



Step1 定义变量



#define RCC_APB2ENR *(volatile unsigned long *)0x40021018

#define GPIOB_CRL  *(volatile unsigned long *)0x40010C00

#define GPIOB_ODR *(volatile unsigned long *)0x40010C0C

使用特权

评论回复
22
programmable|  楼主 | 2019-10-21 11:08 | 只看该作者
Step2 进入main()函数



void main(void)

{

        RCC_APB2ENR |= 1<<3;

        GPIOB_CRL = (2<<20) | (0<<22);

        GPIOB_ODR = 1<<5;

        while (1)

        {



        }

}

保存,编译,load,OK!点亮led。

使用特权

评论回复
23
programmable|  楼主 | 2019-10-21 11:09 | 只看该作者
然后分析下为什么这样做:

Step1 要操作PB5口,首先要使能PB口的CLK,这是stm32特殊的地方,上电时默认外设时钟都是关的;然后是设置PB口的控制寄存器;最后就是送数据。

使用特权

评论回复
24
programmable|  楼主 | 2019-10-21 11:09 | 只看该作者
GPIOB的时钟通过APB2连接,所以应该设置RCC_APB2ENR,查参考手册:

使用特权

评论回复
25
programmable|  楼主 | 2019-10-21 11:09 | 只看该作者
第三位就是PB的时钟使能。然后就是找这个寄存器的地址了。再查memory  mapping(stm32f103ve.pdf)

基地址就是0x4002 1000,偏移地址:0x18,所以RCC_APB2ENR地址为基地址+偏移   地址:0x4002 1000 + 0x18 = 0x4002 1018。

使用特权

评论回复
26
programmable|  楼主 | 2019-10-21 11:10 | 只看该作者
还可以去查keil给出的头文件\Keil\ARM\INC\ST\STM32F10x\stm32f10x_map.h
#define PERIPH_BASE           ((u32)0x40000000)
#define AHBPERIPH_BASE        (PERIPH_BASE + 0x20000)
#define RCC_BASE              (AHBPERIPH_BASE + 0x1000)

加上偏移0x18,则RCC_APB2ENR的地址为:

0x4000 0000 + 0x2 0000 + 0x1000 + 0x18 = 0x4002 1018

使用特权

评论回复
27
programmable|  楼主 | 2019-10-21 11:10 | 只看该作者
于是就这样定义了:

#define RCC_APB2ENR *(volatile unsigned long *)0x40021018

0x40021018只是个值,(volatile unsigned long *)进行强制转换,说明这个值是个地址,类型是unsigned long,意思是,读写这个地址时,写入和读出的都是unsigned long类型。加了volatile确保不被编译器优化,每次直接读值。

(volatile unsigned long *)0x40021018是一个指针,不会变,但里面的值容易变,再在前面加“*”,则可以直接操作这个指针指向的地址里面的值,然后就可以直接对这个内存进行读写操作。

剩下的两个用同样的方法找到地址然后定义。

使用特权

评论回复
28
programmable|  楼主 | 2019-10-21 11:10 | 只看该作者
Step2 main()函数

    RCC_APB2ENR |= 1<<3;查手册BIT3就是PBEN时钟使能位,置“1”,其他位不管。

GPIOB_CRL = (3<<20) | (0<<22);  将PB5设置为输出,看手册得出 MODE5 是
bit 20 21 控制的,CNF5 是bit 22 23,MODE5应该设置 10(0x2) 选择 2MHZ 输出,CNF5 选择00(0x0),通用推挽模式,于是将这个值写入。

GPIOB_ODR = 1<<5;在相应的ODR为写“1”。

OK!点亮之后停在while(1)中。

使用特权

评论回复
29
programmable|  楼主 | 2019-10-21 11:11 | 只看该作者
好吧,点个灯花了半个月,写个总结又花了2天,真是了解和做出来不是一回事,做出来和写出来也不是一回事,就算写出来了也未必理解的是对的。现在差不多知道该怎么学了,突然发现还有好多东西要学。

使用特权

评论回复
30
antusheng| | 2019-10-21 11:48 | 只看该作者
这么多步骤。

使用特权

评论回复
31
caoenq| | 2019-10-22 11:10 | 只看该作者
楼主精神可嘉,大有可为。

使用特权

评论回复
32
磨砂| | 2019-11-18 10:22 | 只看该作者
才一个月已经很不错了

使用特权

评论回复
33
晓伍| | 2019-11-18 10:25 | 只看该作者
非常感谢楼主分享

使用特权

评论回复
34
八层楼| | 2019-11-18 10:30 | 只看该作者
非常不错的尝试

使用特权

评论回复
35
观海| | 2019-11-18 10:36 | 只看该作者
非常感谢楼主分享

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则