STM32F103RB 实作笔记(一)- GPIOC LED 跑马灯(正点原子 STM32F103 nano开发板)程式解析

这几天被隔离管着无聊,就上淘宝买了一块《正点原子》 STM32F103 nano开发板,来练习 stm32f103 的程式。买这块开发板的原因是因为,板子已经有大部分MPU可以应用的线路包括 LED, 七节显示,IR, BUZZ, botton, 和 ST-link 等等基本需要的线路。还附上一个小塑料盒,嶲带方便,也不需要接太多的线。毕竟只是练习了解 F072 和 F103 的差别。
另外,F103的资源多,找资料方便。
下边我就把过程记录一下。(这里舍去去正点原子网站取资料的过程)

开发板

从淘宝下单后,收到的东西是这样,原有的内付程式是个24 小时的时钟。

在这里插入图片描述

跑马灯

内附的跑马灯程式是使用左上方那一排红色 LED, 线路是固定好的,所以要看看线路是用高电平还是低电平控制亮点的。
在这里插入图片描述
在这里插入图片描述
从上面两张线路图可以看到两件事

  1. LED 的上头是 VCC输入,所以,下边的控制必须是低电平(“0”)的时候,LED会被点亮。
  2. LED 是被 PC0~7 控制的,也就是 GPIOC 这一組 I/O port.

程式解析

把开发板的资料从《正点原子》的网站下载下来后,找到“程序源码”找到“寄存器”版的标准程式。(建议把中文的档名改成英文,避免MDK 不认识而无法载入)

在这里插入图片描述
再找到实验一 的程式
在这里插入图片描述
再找到 里面的 USER 档案夹 ,点击 MDK 的 Project 档,就可以载入 跑马灯的全部程式。
在这里插入图片描述
在这里插入图片描述

直接编译程式与执行

main.c 档长得大概像这样子
里面包含了两个 main(), 其中一个是被注解掉的。

#include "led.h"
#include "delay.h"
#include "sys.h"
//****************************************
//****************************************
/*int main(void)
{	

	Stm32_Clock_Init(9); 	// 计时器是给 delay()用的
	delay_init(72);	     	//  
	LED_Init();	 //按右键 用 goto xxxx 去看内容
	 /* 以下的 Main()是给只有两个onboard LED 开发板用的。程式很简单,就是两个 LED 交互一明一暗,每隔 500 ms 的亮灯。想要知道 LED0 是谁控制,就按右键 goto difinition of ‘LED0',了解。*/
	 
	while(1)  
	{	
		LED0=0;//LED0 
		LED1=1;//LED1 
		delay_ms(500);
		LED0=1;//LED0 
		LED1=0;//LED1 
		delay_ms(500);	
	}
}
 */
 int main(void)
 {	
	u8 LED=0x00;
	u8 i=0;
	
	Stm32_Clock_Init(9); 	//
	delay_init(72);	     	//
	LED_Init();	            //
	 
	while(1)
	{
		for(i=0;i<8;i++)
		{
			LED++;	
			GPIOC->BRR = LED;
			delay_ms(200);
			LED<<=1;//
		}
		LED++;	
		GPIOC->BRR = LED;
		delay_ms(200);
		LED=0xff;//
		GPIOC->BSRR = LED;
		delay_ms(200);
	}
 }

第一个 main() 的 LEDx ,我们查询的结果是定义在 LED.h 这个档案里

#ifndef __LED_H
#define __LED_H	 
#include "sys.h"
//	 									  
// 
#define LED0 PCout(0)	// PC0
#define LED1 PCout(1)	// PC1
#define LED2 PCout(2)	// PC2
#define LED3 PCout(3)	// PC3
#define LED4 PCout(4)	// PC4
#define LED5 PCout(5)	// PC5
#define LED6 PCout(6)	// PC6
#define LED7 PCout(7)	// PC7

void LED_Init(void);//
	 				    
#endif

PCout(1) 在 sys.h 档案里
在这里插入图片描述
BIT_ADDR(addr, bitnum) 也在 sys.h 档案里
在这里插入图片描述
在这里插入图片描述
这样就可以从 sys.h 档里看到许多 F103 的寄存器的address 定义 与使用了。

第二段 main()

程式如下:

 int main(void)
 {	
	u8 LED=0x00;
	u8 i=0;
	
	Stm32_Clock_Init(9); 	//
	delay_init(72);	     	//
	LED_Init();	            //
	 
	while(1)
	{
		for(i=0;i<8;i++)
		{
			LED++;	
			GPIOC->BRR = LED;
			delay_ms(200);
			LED<<=1;//
		}
		LED++;	
		GPIOC->BRR = LED;
		delay_ms(200);
		LED=0xff;//
		GPIOC->BSRR = LED;
		delay_ms(200);
	}
 }

我们只看 LED_Init(); 这个副程式,是在 LED.c 这个档案里,如下:

#include "led.h"
//	 									  
//        
//LED IO3 
void LED_Init(void)
{
	 RCC->APB2ENR|=1<<4;    // 	   
	 GPIOC->CRL&=0X00000000; 
	 GPIOC->CRL|=0X33333333;//PC0~7   		
   GPIOC->ODR|=(1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5)|(1<<6)|(1<<7);//PC.0~7  
}

这张图是 GPIOC 的定义, 及 GPIO_TypeDef 这两个是被定义在 stm32f10x.h 这个档案里。我把相关的参数都找出来放在一起,抄录在下面。

//stm32f10x.h
/*!< Peripheral memory map */
#define PERIPH_BASE           ((uint32_t)0x40000000) /*!< Peripheral base address in the alias region */
#define APB1PERIPH_BASE       PERIPH_BASE
#define APB2PERIPH_BASE       (PERIPH_BASE + 0x10000)
#define AHBPERIPH_BASE        (PERIPH_BASE + 0x20000)
#define GPIOC_BASE            (APB2PERIPH_BASE + 0x1000)
#define GPIOC                ((GPIO_TypeDef *) GPIOC_BASE)

/** 
  * @brief General Purpose I/O
  */

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;

由于 GPIOC 被指向一个结构叫 GPIO_TypeDef,这个时候 GPIOC->ODR 这一类的符号就容易看懂了。

第二段 main()里面的这一段是主要点灯的程式。

for(i=0;i<8;i++)
		{
			LED++;	//点 bit 0 用的
			GPIOC->BRR = LED; 
			/* 查资料,BRR 是’1‘的时候会把 ODR 输出重置为低电平’0‘。BRR 是’0‘的时候会,不影响当下的 ODR 内容。*/
			delay_ms(200);
			LED<<=1;//向前移动一个灯,原来的灯在等一下用 LED++ 补上
		}

而下面这一段程式是做收尾的工作:

	    LED++;	//for 回圈出来后的收尾,与回圈里是一样的
		GPIOC->BRR = LED; //for 回圈出来后的收尾,与回圈里是一样的
		delay_ms(200);  //for 回圈出来后的收尾,与回圈里是一样的
		LED=0xff;//
		GPIOC->BSRR = LED; // 把 GPIOC 设成高电位,关闭 LED
		delay_ms(200);

所以整个跑马灯是从LED0 开始,逐个点亮之后,全部熄灭,让后再一个循环。
我这一篇文章主要是在分析 header 档的运用方法。因为,c 语言要容易移植到不同的 MPU/CPU, 比较耗时间的就是改写这些 header 档。当然,各家 芯片公司都会尽量准备好这些档案。

  • 4
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值