STM32F103入门系列——点灯程序分析(第一篇)

main函数分析

#include "stm32f10x.h" //STM32头文件
#include "sys.h"
#include "delay.h"
#include "led.h"


int main (void){//主程序
	RCC_Configuration(); //时钟设置,见sys.c文件
	LED_Init();//LED初始化,见led.c函数
	while(1){//无限循环,用来保证程序的不断执行
		//应当注意:端口电平的设置应当和硬件的连接相一致
		//方法一:
		GPIO_WriteBit(LEDPORT,LED1,(BitAction)(1)); //LED1接口输出高电平1
		delay_us(50000); //延时1秒,延时函数见delay.c函数
		GPIO_WriteBit(LEDPORT,LED1,(BitAction)(0)); //LED1接口输出低电平0
		delay_us(50000); //延时1秒
		
		//方法二:
//		GPIO_WriteBit(LEDPORT,LED1,(BitAction)(1-GPIO_ReadOutputDataBit(LEDPORT,LED1))); //取反LED1
//		delay_ms(500); //延时1秒

		//方法三:
//		GPIO_SetBits(LEDPORT,LED1); //LED灯都为高电平(1)
//		delay_s(1); //延时1秒
//		GPIO_ResetBits(LEDPORT,LED1); //LED灯都为低电平(0)
//		delay_s(1); //延时1秒

		//方法四:
//		GPIO_Write(LEDPORT,0x0001); //直接将数值操作变量写入LED
//		delay_s(2); //延时1秒
//		GPIO_Write(LEDPORT,0x0000); //直接将数值操作变量写入LED´ÈëLED
//		delay_s(2); //延时1秒

	}
}

“#include”为头文件的添加;
以下代码是调用初始化函数,对led进行初始化。

LED_Init( );//LED初始化,见led.c函数

第一种方法:调用了固件库的GPIO_WriteBit( )函数,此函数如图:
GPIO_WriteBit
可以看到此函数有三个参数,分别是参数1:GPIOX来选择外设;参数二:来选择GPIO_pin_x来指定某个引脚;参数三:BitVa来写入制定的值,同时此值影师BitAction中的一个值。
下面的代码BitAction的值就是0.

         GPIO_WriteBit(LEDPORT,LED1,(BitAction)(1)); //LED1接口输出高电平1
		delay_us(50000); //延时1秒,延时函数见delay.c函数
		GPIO_WriteBit(LEDPORT,LED1,(BitAction)(0)); //LED1接口输出低电平0
		delay_us(50000); //延时1秒

第二种方法:仍然调用固件库的GPIO_WriteBit( )函数,唯一不同的就是函数的参数(BitAction)的值变成了
(1-GPIO_ReadOutputDataBit(LEDPORT,LED1))
可以看出在此句中调用了GPIO_ReadOutputDataBit( )函数,下面我们来分析下这个函数:
[GPIO]
由图可以看出此函数的功能为读取指定管脚的输出,有输出则为1,无输出则为0;而此处巧妙的使用 1-这个值,那么当管脚输出为1,1-1=0,此处BitAction的值将为0,从而实现灯的反转。

GPIO_WriteBit(LEDPORT,LED1,(BitAction)(1-GPIO_ReadOutputDataBit(LEDPORT,LED1))); //取反LED1
	delay_ms(500); //延时1秒

第三种方法:调用GPIO_SetBits( )函数,关于此函数在函数库中的定义是这样的:
GPIO_SetBits
此函数有两个参数,分别为GPIOx和GPIO_pin,然后此函数的功能为向指定的端口写入1,同理函数GPIO_ResetBits( )函数是向指定的函数写入0,大家可以去固件库自己翻翻对应的函数讲解,在此不和大家一一赘述。

		GPIO_SetBits(LEDPORT,LED1); //LED灯都为高电平(1)
		delay_s(1); //延时1秒
		GPIO_ResetBits(LEDPORT,LED1); //LED灯都为低电平(0)
		delay_s(1); //延时1秒


第四种方法:本方法调用了GPIO_Write函数,这哥函数乍一看是不是有点眼熟呢?它和方法一和方法二中的GPIO_WriteBit( )函数是不是有点相似呢?我们来看一下这个函数的解释:
GPIO_Write
它是向参数1中写入待写入寄存器的值,比如此处写入的就是0x001,也就是PB的第零个引脚为1;再往后写入0x000,也就是PB的第零个引脚为0。(16进制的0x001为二进制的0000 0000 0000 0001;16进制的0x000是二进制中的0000 0000 0000 0000)
这个方法和51直接写入的方法有异曲同工之妙。

       GPIO_Write(LEDPORT,0x0001); //直接数值操作将变量值写入LED
		delay_s(2); //延时1秒
		GPIO_Write(LEDPORT,0x0000); //直接数值操作将变量值写入LED
		delay_s(2); //延时1秒


led.c分析

void LED_Init(void){ //LED灯的接口初始化
    GPIO_InitTypeDef  GPIO_InitStructure; 	//结构体声明
                        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC,ENABLE);       
    GPIO_InitStructure.GPIO_Pin = LED1 | LED2; //选择端口号(0~15或all)  	
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //选择IO接口工作方式       
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //设置IO接口速度(2/10/50MHz)    
	GPIO_Init(LEDPORT, &GPIO_InitStructure);			
}

逐条分析:

GPIO_InitTypeDef  GPIO_InitStructure;

右键 go to definiation of“GPIO_InitTypeDef ”
你会看到一个结构体变量:

typedef struct
{
  uint16_t GPIO_Pin;             //引脚

  GPIOSpeed_TypeDef GPIO_Speed;  //端口速度

  GPIOMode_TypeDef GPIO_Mode;    //端口模式
}GPIO_InitTypeDef;

此时再看LED_Init函数,就可以发现他是对对应端口的总线时钟进行使能,然后再设定端口pin,再选择IO口的接线方式,最后设置IO口的速度。

 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC,ENABLE);       
    GPIO_InitStructure.GPIO_Pin = LED1 | LED2; // 选择端口号(0~15或all)  	(LED1,LED2 在LED.h中进行了宏定义)
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //选择IO接口工作方式       
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //设置IO接口速度(2/10/50MHz)    

再看最后一条:

GPIO_Init(LEDPORT, &GPIO_InitStructure);	

GPIO_Init此时一看有点眼熟了吧,这不是和LED_Init差不多么,我们使用同样的方法来分析,既然刚才是初始化LED,那么现在就是初始化GPIO,这条语句就是将你设置的 端口,工作方式,接口速度(&GPIO_InitStructure)写入LEDPORT中。(LED.h定义了#define LEDPORT GPIOB)。
下图是固件库中关于GPIO_lnit的定义。
 GPIO_Init



后记

本次点灯的分享就到这里,关于精确延时函数会在以后关于滴答定时器中进行详细的分享,才疏学浅,如有错误希望大家留言批评指正。希望大家多多留言分享,点赞关注不迷路哦!下次再见。

  • 8
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值