stm32_之【入门点灯】

原理学习

一.管脚的规划


eg:对于71管脚   有很多种工作模式:


PA12:可以作为普通的GPIO使用,也叫P212功能

USART1:也可以作为串口的RST管脚,即:使用请求发送的管脚

USBDP:也可以做USB接口来用

CAN_TX:

T1M1:也可以做以太网的timer来使用

但是一个管脚只能工作在一种模式!

要么做GPIO口用,要么做串口用。


二.LED亮灭的按键分析

【电路图】

K3按下,默认接地,是低电平;

K3不按,上面有个上拉电阻,拉成高电平。

/#那么怎么知道按键有没有按下?#/用CPU 判断灯的亮灭,见第二点。


1.CPU控制灯亮灭:对于CPU来说是输出一个电平到外部,以控制灯的亮灭。

第一步:配置GPIO为 输出模式

第二步:cpu->1->外部:灯亮

             cpu->0->外部:灯灭


2.CPU判断灯亮灭:对于CPU来说,是外面这个送进来的电平,来判断灯是亮还是不亮。

第一步:配置GPIO为 输入模式

第二步:外部->1->cpu读 =1:判断为灯亮

              外部->0->cpu读=0 :判断为灯灭


三.控制GPIO的寄存器 (32位)

1.GPIO组简介:

GPIO组(A...E):每组端口有16个不同的管脚(0-15号), 对于GPIOA和GPIOB,他们都有互相不相干的一寄存器。如:控制GPIOA 的寄存器为GPIOA_CRL,GPIOA_CRH等..,控制GPIOB的寄存器为GPIOB_CRH,GPIOB_CRL等..


2.你想配置成哪种模式?就去配置它的寄存器。


如:要实现71管脚的5种模式,至少要3个位(bit)存放

2^1(位)=2种 0/1(最多两种模式)                            

2^2(位)=4种 00/01/10/11(最多四种模式)             

2^3(位)=8种 000/001/010/……/111(最多八种模式)

即:1个管脚要3个位,16个端口要 16X3=48位 (bit)                                   (1bit=8字节)(1bit=1位) 

stm32的一个寄存器只有32bit,小于48bit,位不够,所以至少要两个寄存器控制。如GPIOx(x=A..E)就需要 GPIOx_CRH高位寄存器、GPIOA_CRL低位寄存器 ..等寄存器控制。


3.控制GPIO组的端口寄存器分类:(7个)

(1)配置寄存器(低寄存器GPIOx_CRL,高寄存器GPIOx_CHL) :选定GPIO的特定功能,最基本的选择作为输入还是输出端口。

(2)数据寄存器(输入寄存器GPIOx_IDR,输出寄存器GPIOx_ODR)保存GPIO的输入或将要输出的电平。

(3)位控制寄存器(GPIOx_BSSR设置/清除寄存器,GPIOx_BRR清除寄存器)设置某引脚的数据为1或0,控制输出电平。

(4)锁定寄存器(GPIOx_LCKR):设置锁定引脚后,不能更改配置。


***************详细说明*********************:


(1)端口配置高寄存器:CRH管理8-15管脚。一个管脚用四个位。



CNF8(2位)---配置    MODE8(2位)--模式






端口配置低寄存器:CRL管理0-7管脚,一个管脚用四个位。




-----------------------------------------------------------------------------------------------------------------------

实战点灯寄存器点灯/库点灯(常用)



【要求】



【电路图】



【具体步骤】


.

------------------------------

一.用库点灯


1.准备好要用到的库,明确好要编写的.c文件和.h文件:

(1)准备好要用到以下库:

STRAT UP    :   ←  startup_stm32f10x_hd.c   (启动文件)

CMISS:         :   ←   core_cm3.c  (C3核通用文件) +  system_stm32f10x.c (设置系统时钟)

FWLIB          :   ←  stm32f10x_rcc.c +  stm32f10x_gpio.c (要用到时钟和通用I/O口两个片上外设)

(2)确定用户要编写的文件  :     

USER           :   ← main.  c(主函数,控制灯亮灭)+ stm32f10x_it.c(中断函数) +  led.c (灯的配置) +                                                     led.h(灯的配置头文件)


2.配置工程环境:

进入stm32f10x_conf.h固件配置头文件,使片上外设RCC和GPIO生效,方法:去掉注释


3.编写用户文件(先配置灯,再操作灯)

led.c

/****************************************************************************
* Copyright: (C)2018 武汉凌云嵌入式实验室 www.emblinux.com
* Description: 在奋斗STM32 V5开发板上调通过; 
*LED1-PB5  
*LED2-PD6
*LED3-PD3
*hangeLog:https://blog.csdn.net/luoyir1997
*版本号     日期       作者          说明
* V1.0.0   2018.4.21   LUOYIRAN   配置灯的模式
****************************************************************************/

#include "stm32f10x.h"
#include "led.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_rcc.h"

#define DELAY_TIME   0x3FFFFF


 /*函数名:LED_GPIO_Config
 *描述:配置LED用到的I/O口
 *输入:无
 *输出:无
 */

void LED_GPIO_Config(void)
{
	/*定义一个GPIO_*_InitTypeDef类型的结构体*/
	GPIO_InitTypeDef  GPIO_InitStructure;
	
 	/*开启外设时钟*/
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);

	
	/*选择要控制的GPIOB和GPIOD引脚*/
	
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5;
	

	
	/*设置输出模式为通用推挽输出*/
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
	
	/*设置引脚速度为50MHZ*/
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	
	/*调用库函数,初始化GPIOB和GPIOD*/
	GPIO_Init(GPIOB,&GPIO_InitStructure);


	
	/*关闭所有LED灯*/
	GPIO_SetBits(GPIOB,GPIO_Pin_5);
	

	
 }
	/****************************************************************************************/
	/*在这个文件中定义了一个函数LED_GPIO_Config(),在这个函数里,实现了为点亮LED的配置*/

led.h

#ifndef __LED_H
#define __LED_H 

#include "stm32f10x.h"
/*定义0-ON  1-OFF*/
#define ON 0
#define OFF 1
														
void LED_GPIO_Config(void);

#endif /*__LED_H*/
	         

main.c

/****************************************************************************
*Copyright: (C)2018 武汉凌云嵌入式实验室 www.emblinux.com
*Author:luoyiran  QQ: 969303624
*Description: 本例在奋斗STM32 V5开发板上调通过;
*LED1-PB5  LED2-PD6 LED3-PD3
*文件名:main.c
*描述:点亮LED5
*hangeLog:https://blog.csdn.net/luoyir1997
*版本号     日期       作者          说明
* V1.0.0   2018.4.21   LUOYIRAN   配置灯的模式
****************************************************************************/
#include "stm32f10x.h"
#include "led.h"

void Delay(u32 nCount);


int main (void) 
{
	LED_GPIO_Config();
	
  GPIO_SetBits(GPIOB, GPIO_Pin_5);                     //亮
	Delay(0x0FFFFEF);
}

void Delay(u32 nCount)//简单的延时函数
{

	for( ; nCount != 0; nCount--);
		 
}  

4.编译、下载,因为用的盗版JLINK,跳出东西就点否,就好了。

至此,我们就把LED5点亮啦!



2.寄存器点灯


【要点分析】

0X40001 0C00是起始地址,无符号int 类型,定义用 unsigned int。从这个地址开始取值,取32位,32/8=4个字节

reg =0x4001 0c00  这俩类型一样。但是*reg 是个指针。所以要强制类型转换。

reg 寄存器是 unsigned int*类型的 -->强制转化成:

    =

【代码编写】 3步 

一.设置初始地址
LED5的地址是:0X4001 0C010
reg=0X4001 0C010
这是个整数类型的无符号数 应该用unsigned int 
*reg 是指针。要使用强制定义将指针类型转化。


为了防止软、硬件改变寄存器设置,所以要在定义前加volatile
编译器很聪明
假如一开始设置了reg=30;
if reg==30
{
};
后面if以后的PD操作就会被省略,从而寄存器设置被软件改变
因此正确的写法是:
volatile unsigned int*  reg(ungined int*)=0x4001 0c10
---------------------------------------------------------
位操作方法总结:
要1,或1                             
要0,取反与1


或01
0 01 
1 
与01
0 01
1 1
-----------------------------------------------------------------------------------------------------

二。设置模式
GPIOX_CRL低配置寄存器
地址偏移0x00
【31:0】【CF7+MOD7:CF0+MODE0】
【3:2】 【1:0】
CF0 bit  MODE0 bit


现在我们要求工作模式在:推挽输出,50MHZ,得设置CRL寄存器的CNF和MODE位值,
即:要求将GPIOX_CRL中的数据位设置成:
MODE5的位数据【21:20】=11
CNF5 的位数据【23:20】=00

A)MODE5【21:20】=11
11=0x3
将3左移20位:
 0000 0000 0000 0000 00/00/ 0000 0000 0000 0000 0011 (32位)
 0000 0000 0000 0000 00/11/ 0000 0000 0000 0000 0000  


则20和21位为1,原地址 *reg or 1=1
其他数据位为0,原地址 *reg or 0=不变


∴代码为。
*reg|=11<<20;


------------------------------------------------------------------
B)CNF5【23:22】=00

11=0X3

将11左移22位:
     0000 0000 0000 0000 /00/00 0000 0000 0000 0000 0011 (32位)
     0000 0000 0000 0000 /11/00 0000 0000 0000 0000 0000 (移动后)
  ~
取反 1111 1111 1111 1111 /00/11 1111 1111 1111 1111 1111


则22和23位为0,原地址*reg & 0 =0
其他数据位为1,原地址*reg & 1 =不变


∴代码为。
*reg &=~(0x03<<22);


----------------------------------------------------------
三。输出高电平


方法一:
ODR端口输出寄存器


地址偏移0X08
【16:31】【位保留】
【15:0】 【ODR15:ODR0】   ODR(out )输出位


输出电平,如点LED5,
设置ODR5=1  输出一个高电平
设置ODR5=0  输出一个低电平
--------------------------------------------------------
方法二:
(GPIOx_BSRR)(x=A..E)端口设置/清除寄存器
地址偏移0X10
【31:16】【BR15:BR0】   BRY  (bit reset)清除位    写1清0  BRY=1引脚输出低电平
【0:15】 【BS15:BS0】   BSY (bit set)设置位     写1置1  BSY=1引脚输出高电平


·注意:这两个位写0都是无效的.


如点/灭LED5,需要设置GPIOB5的BSRR位来输出电平:
BS5=1 输出一个高电平 
BR5=1 输出一个低电平


现在我们要灯亮,得设置BSRR寄存器的BSY位值
  BS5bit
  【5】=1
∴代码为。
volatile unsigned int *reg=(unsinged int*)0x4001 0c10;
*regI1<<5;




现在我们要灯灭,得设置BSRR寄存器的BRY位值
 BR5bit
【21】=1
∴代码为。
volatile unsigned int*reg=(unsinged int*)0x4001 0c10;
*regI1<<21;




----------------------------------------------------------------



 



猜你喜欢

转载自blog.csdn.net/luoyir1997/article/details/79953938