STM32 初学 led 不用库 详细分析

发布者:自由梦想最新更新时间:2015-12-28 来源: eefocus关键字:STM32  led 手机看文章 扫描二维码
随时随地手机看文章
本来只是路过,写详细一点。

我看楼主浮躁得不得了。现在什么都不要做了,先去看几遍《不要做浮躁的嵌入式工程师》这篇文章,想清楚了,
再动手吧。

我做了个实例,不用ST的库来点LED,解答你的问题

我的 KeilMDK 3.5
我的STM32板子奋斗版是 ,IC 是 STM32F103VET6
调试工具 JLINK V8
LED 接在 PB5 ,高电平点亮

既然楼主说一定懂C语言了,那么对于下面我的问题,不查百度,完全靠自己,懂多少?然后查了百度之后又能懂多少?

(一)新建 keil 工程,IC选择 ST 公司的 STM32F103VE,keil提示是否copy 启动文件,选择是。

这里有问题问楼主,
你有没有读过这个启动头文件? 51 也是同样的启动文件,51的那个启动文件有没有读过?你知道
头文件里面做了什么吗? C语言真的从 main 函数开始吗?运行时库是什么?这些资料从
什么地方知道?keil编译器的行为?
(如果你说头文件是汇编的,没有必要看,那我当我没说)

例如启动文件里面有这么一句,我的问题是 __main 这个标号在哪里实现的,注意,这里肯定不是 main 函数
这里跳到哪里去了?还有个问题 [WEAK] 这里是什么意思?有什么用????

Reset_Handler PROC
EXPORT Reset_Handler [WEAK]
IMPORT __main
LDR R0, =__main
BX R0


(二)新建一个 main.c 并且写一个 main函数,什么都不做,这和51一样了。

void main(void)
{
while (1)
{

}
}

然后因为我需要调试,则设置jlink调试器,在项目属性里面 Debug 标签,Use J-LINK/J-TRACE ,然后到
utilities 标签,同样选择J-LINK /J-TRACK ,并且选择 Setting 按钮,里面的 Programming Algorithm
还是空的,表示keil 不知道目标是什么,我添加一个 STM32F10X High-density Flash ,问题,为什么是
High-desity ?依据是什么???
全部确认返回。

这个时候已经可以编译,开发板上电,已经可以下载仿真的,虽然程序什么都没有写

(三)既然硬件,仿真器,调试都准备好了,接着就开始写程序了。
我一直推荐新手花钱买学习板和仿真器,因为可以排除硬件的问题,让初学者集中精力去写程序,而不用怀疑
硬件有问题,这点很重要。

这阶段主要是看书,了解这个IC 的架构,了解指令集,了解寄存器(别跟我说你找不到这些资料? .....)
Cortex-M3权威指南CnR2(电子书).pdf
STM3210x参考手册.pdf
学习板原理图
博客,论坛等多个帖子,务必要对整个IC有个初步的了解。这个过程有点痛苦,但是值得花这个时间。

(四)开始写 LED
既然我们要操作 IO 口,当然就要看IO口相关的知识。打开 STM3210x参考手册.pdf ,我的目的只是操作 GPIO
所以我只需要将第五章看完就OK了。章节比较多,懒得看,根据一般的经验(楼主,你缺经验了吧?),不说多
就AVR 和 PIC 而已。操作IO一般是两个步骤,第一,操作IO控制寄存器,设置IO为输出,第二就是送数据。

那么很明显,只可能是 GPIOx_CRL GPIOx_CRH , GPIOx_ODR 三个寄存器会有想要
仔细阅读这几个寄存器的介绍后知道,GPIOx_CRL 是控制 PIN 0-7 的属性的,GPIOx_CRH 控制PIN 8-15,ODR寄存器
当然就是输出数据了,将数据送到这里就行了。

然后,这几个寄存器的地址是多少?首先看 stm32f103ve.pdf 这个是官方的datasheet、,看第四章, Mmeory Mapping
为什么看这章?会英文都能猜到吧?,看 PORTB 的地址是 0x40010C00 - 0x40010FFF ,这个就是基地址了。基地址
加上偏移量就能找到具体的寄存器。

例如我需要操作 GPIOB_CRL 的偏移为 00H ,(看STM3210x参考手册.pdf) ODR 寄存器的偏移为 0CH
那么很自然得出
GPIOB_CRL = 0x40010C00
GPIOB_ODR = 0x40010C0C

怎么验证我的结论正确?先看 keil 给的头文件 KeilARMINCSTSTM32F10xstm32f10x_map.h
#define PERIPH_BASE ((u32)0x40000000)
#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000)
#define GPIOB_BASE (APB2PERIPH_BASE + 0x0C00)

这样怎么算都能算出 0x40010C00 出来吧??ODR 寄存器同理

为了点亮 LED ,我需要将 PB5 (也就是 GPIOB5)设置为输出,并且ODR相应的位写入 1 ,看资料得出 MODE5 是
bit 20 21 控制的,CNF5 是bit 22,23
MODE5应该设置 10(0x2) 选择 2MHZ 输出,CNF5 选择00(0x0),通用推挽模式,于是将这个值写入

(*volatile unsigned long)0x40010C00 = (2<<20) | (0<<22); // 为简单起见,不管其他位了

楼主你是否能看懂这句C语言??volatile 什么意思什么用?指针的本质是什么?为什么能这样用?2<<20 是什么
意思,为什么能这样用?楼主我真的不是为难你,嵌入式都这么写的,ST的头文件也是这么定义

同理,设置 ODR 寄存器
*(volatile unsigned long *)0x40010C0C = 1<<5;
*(volatile unsigned long *)0x40010C0C = 0;

STM32 没有SFR ,没有bit,没有sbit 的概念的了。是不是就不如 51 了?


下载运行,还不行,因为GPIOB 的CLK 没有使能,这时其实 GPIOB 是不能工作的,这是 STM32 特殊的地方,上电
默认外设的时钟都是关的,初学者没有注意这里,是可以原谅的,多看看书,多实践,多问问就是了。

找到问题的原因,则再 RCC_APB2ENR 设置,其中 BIT 3 就是 IOPBEN 是时钟使能位,同上,先找到 RCC_APB2ENR
的地址
#define PERIPH_BASE ((u32)0x40000000)
#define AHBPERIPH_BASE (PERIPH_BASE + 0x20000)
#define RCC_BASE (AHBPERIPH_BASE + 0x1000)
RCC_APB2ENR 的偏移是 18H ,所以最终得到地址为 0x40021018,操作方法同上

*(volatile unsigned long *)0x40021018 |= 1<<3;


最终的点LED的程序就完成了。
void main(void)
{
*(volatile unsigned long *)0x40021018 |= 1<<3;
*(volatile unsigned long *)0x40010C00 = (2<<20) | (0<<22);
*(volatile unsigned long *)0x40010C0C = 1<<5;
while (1)
{

}
}
如果将寄存器做一个定义,则程序变成如下

#define RCC_APB2ENR *(volatile unsigned long *)0x40021018
#define GPIOB_CRL *(volatile unsigned long *)0x40010C00
#define GPIOB_ODR *(volatile unsigned long *)0x40010C0C

void main(void)
{
RCC_APB2ENR |= 1<<3;
GPIOB_CRL = (2<<20) | (0<<22);
GPIOB_ODR = 1<<5;
while (1)
{

}
}

RCC_APB2ENR RCC 是时钟寄存器 , APB2 是外设2 ,ENR ,可以理解为 enable
GPIOB_CRL GPIO B control 控制寄存器
GPIOB_ODR GPIO(general purpose input output) B output data register 输出数据寄存器

都是有意义的名字,哪里难记了??而且名字都来自 ST 的官方 datasheet、这个程序跟你用 51 写的程序我还真的
没看出差别有很大 .....

加入刚才的 GPIOB 寄存器,看看 ST 的官方库是怎么定义的,
LibrariesCMSISCM3DeviceSupportSTSTM32F10xstm32f10x.h
用 UltraEdit 打开,搜索 GPIOB

#define PERIPH_BASE ((uint32_t)0x40000000)
#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000)
#define GPIOB_BASE (APB2PERIPH_BASE + 0x0C00)

没错,和keil 里面是一模一样的。


typedef struct
{
__IO uint32_t CRL;
__IO uint32_t CRH;
__IO uint32_t IDR;
__IO uint32_t ODR;
__IO uint32_t BSRR;
__IO uint32_t BRR;
__IO uint32_t LCKR;
} GPIO_TypeDef;

其中 __IO 的定义在 LibrariesCMSISCM3CoreSupportcore_cm3.h 为什么我知道在这个文件里面,因为我会
用 source insight ...

#define __IO volatile

__IO uint32_t CRL 其实就是 volatile uint32_t CRL

为什么用结构体?因为结构体的成员的地址分配(RAM中)是连续(不知道楼主是否懂得,这还是C语言的问题),
而 STM32 的一个模块的功能寄存器都是连续的,每个寄存器都是相当于 基地址加偏移,跟上面的理论一致

于是就有了结构体指针的用法
跟踪库函数的源代码,例如 GPIO 的 初始化函数
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct)

以结构体指针的形式传递 IO 口 GPIO_TypeDef* GPIOx

访问 CRL 寄存器则用成员的形式 GPIOx->CRL;

不需要担心这样做的效率,因为都是地址,也就是指针,最终的效率是直接寄存器操作,效率是非常高的。

看不懂库函数,归根究底就是C语言功底不行。不要以为写过几行51就懂C语言了,远的很呢。

还有,STM 的库下载的时候包含了很多很多例子,库函数怎么使用在例子里面有很详细的介绍,不用写几行代码,
都是复制例子做实验,也很很容易的。

总结楼主的几个问题
1,ARM 没有SFR,也不需要,SFR 是51的关键字,没有理由 51 有 ARM 就要有。例如ACC,ARM 就没有,但是有
R0-R15 ,这些就是架构(architecture 的区别了)
2,STM32 的寄存器在官方头文件上面已经全部有定义了,上面已经阐述了。(你看不懂不代表没有吧?)
3,不带库函数的LED程序已经实现了。

想进步唯一的办法是多看书,多看代码,多写,多思考,少说话,楼主太浮躁了,反省一下吧。
关键字:STM32  led 引用地址:STM32 初学 led 不用库 详细分析

上一篇:STM32在调试过程中常见问题和解决办法
下一篇:stm32f10x_conf.h 与 stm32f10x.h

推荐阅读最新更新时间:2024-03-16 14:41

Melexis最新LIN RGB LED 控制器可简化使用方式
全球微电子工程公司 Melexis宣布引入新一代LIN RGB (W) LED 控制器IC产品。作为车内氛围灯解决方案的全球领导者,全新的MLX81113 将支持基于 LIN 的 RGB LED 车内氛围灯应用(也称为 LIN RGB)进一步发展,LIN RGB 几乎已经获得全球所有OEM 的认可。与广受欢迎的 MLX81108 相比,MLX81113 具有更大的片上内存、更高的恒流源输出和更强的 EMC 稳定性。此外,MLX81113 符合 ISO 26262 功能安全要求,满足 ASIL-A 等级。 MLX81113 提高了片上系统功能,配备有 MLX16 FX 16 位 RISC 微控制器、2 KB RAM 和 3
[汽车电子]
Melexis最新LIN RGB <font color='red'>LED</font> 控制器可简化使用方式
STM32的IO口输入输出模式的理解
最近在看数据手册的时候,发现在Cortex-M3里,对于GPIO的配置种类有8种之多: (1)GPIO_Mode_AIN 模拟输入 (2)GPIO_Mode_IN_FLOATING 浮空输入 (3)GPIO_Mode_IPD 下拉输入 (4)GPIO_Mode_IPU 上拉输入 (5)GPIO_Mode_Out_OD 开漏输出 (6)GPIO_Mode_Out_PP 推挽输出 (7)GPIO_Mode_AF_OD 复用开漏输出 (8)GPIO_Mode_AF_PP 复用推挽输出 一、推挽输出:可以输出高、低电平,连接数字器件;推挽结构一般是指两个三极管分别受两个互补信号的控制,总是在一个三极管导通的时候另一个截止。高
[单片机]
<font color='red'>STM32</font>的IO口输入输出模式的理解
使用STM32控制无源蜂鸣器发声播放音乐
一、无源蜂鸣器和有源蜂鸣器 有源蜂鸣器内含振荡源,只要一通电就发声,但发生频率固定,音色单一;无源蜂鸣器内部不含振荡源,内部结构相当于电磁场扬声器,可以通过给他输出一定频率的信号才能发声。 人耳能听到的频率范围在20Hz--20kHz之间,通过STM32的GPIO引脚快速切换高低电平输出就能实现无源蜂鸣器的发声,切换的频率不同,发出的音调就不一样。 二、音乐播放的实现 一段音乐就是不同频率的声音按一定的时间节拍转换发出。所以音乐包含音调和节拍信息。 C调各音符频率如下: 音符 频率 Hz 音符 频率 Hz 低1 Do 262 中1 Do 523 低2 Re 294 中2 Re 587 低3 Mi
[单片机]
stm32中断解剖(非外部中断)
如果只使用TIME2全局中断,则不需要void EXTI_Config(void)//外部中断配置。只要void NVIC_Configuration(void)//嵌套中断配置和stm32f10x_it.c库文件中的void TIM2_IRQHandler(void)。具体如下配置。注意此处与外部中断的配置的区别切勿混淆。 疑问? 1.为什么不需要配置RCC_APB2Periph_AFIO 2 查看固件库手册 发现NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQn; //选择外部中断3号线 与 NVIC_InitStructure.NVIC_IRQChannel = TIM2
[单片机]
<font color='red'>stm32</font>中断解剖(非外部中断)
mini2440A 裸机编程:串口控制LED灯的亮灭
要求 在PC上发送L11控制开发板led1亮,发送L10控制开发板led1灭; 在PC上发送L21控制开发板led2亮,发送L20控制开发板led2灭; 在PC上发送L31控制开发板led3亮,发送L30控制开发板led3灭; 在PC上发送L41控制开发板led4亮,发送L40控制开发板led4灭; PC使用串口助手发送; 代码 #include string.h #include stdlib.h //0x50000020(L) //0x50000023(B) //(字节) UART 通道0 发送缓冲寄存器 #define UTXH0 (*(volatile unsigned int *)0x50
[单片机]
LED恒流精准控制技术详解
提到LED驱动精准度通常会想到恒流误差,其实驱动精度并不仅仅限于电流精度一项。LED是一款典型的电流驱动型器件,精准控制LED驱动电流,可决定包括光效率、电源效率、散热和产品亮度等在内的许多参数。驱动LED主要在于控制它的电流。无论是直接增、缩驱动电流,还是占空比(PWM)减小开关时间比,均是控制电流方式,但达到的目的却不相同。本文将阐述不同的驱动在不同应用中的区别。    分布式恒流驱动原理介绍   在以往的白炽灯和节能灯市场,大公司所形成的规格有限的主流灯具型号, LED很难再继续遵守。LED有它的应用灵活性,在日后的设计中会带来较多的电源规格。我们要避免过多的电源规格,不给日后量产带来诸多障碍。本着在不限制设计灵活性同时
[电源管理]
<font color='red'>LED</font>恒流精准控制技术详解
STM32外设DMA使用总结
STM32外设DMA使用总结: 1、根据需要选择DAM模式: (1)循环模式—DMA_Mode = DMA_Mode_Circular (2)正常模式—DMA_Mode = DMA_Mode_Normal 2、对于DMA1的Chanel3,对应外设为USART3的RX 试想:如果串口接收中断和DAM中断同时打开,CPU如何相应? (1)中断优先级不同:这好说,支持嵌套中断(NVIC)的Cortex-M3自然优先服务中断优先级高的 (2)中断优先级相同:处理原则,先来先处理;若同时到来,中断号低的优先处理 查询手册可知,DMA(IRQn number 13)会先于USART3(39)被CPU处理 3、设置DMA模式为循环模式,则:
[单片机]
薄型LED背光来势汹汹,CCFL几无立足之地
  装载薄型导光板薄型LED Backlight在笔记本电脑面板市场正快速成长。DisplaySearch最新的每季LED Backlight面板出货与预测报告中指出,笔记本电脑使用的面板当中,薄型LED Backlight的比重将由2010年第四季的16%成长到2010年的31%。报告并指出,LED Backlight在笔记本电脑面板的渗透率由2009年第一季的36%扩大到2010年第一季的81.5%,展望到今年年底预计渗透率将高达97.7%;换言之传统的CCFL Backlight在Notebook PC市场将接近完全退出的状态。   DisplaySearch表示,目前在笔记本电脑面板的LED Backlight的部份有两
[电源管理]
薄型<font color='red'>LED</font>背光来势汹汹,CCFL几无立足之地
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
502 Bad Gateway

502 Bad Gateway


openresty
设计资源 培训 开发板 精华推荐

502 Bad Gateway

502 Bad Gateway


openresty
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

502 Bad Gateway

502 Bad Gateway


openresty
502 Bad Gateway

502 Bad Gateway


openresty
502 Bad Gateway

502 Bad Gateway


openresty
随便看看
    502 Bad Gateway

    502 Bad Gateway


    openresty
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
502 Bad Gateway

502 Bad Gateway


openresty