IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> 使用寄存器点亮一个LED灯 普中科技stm32(stm32f1103zeb6) -> 正文阅读

[嵌入式]使用寄存器点亮一个LED灯 普中科技stm32(stm32f1103zeb6)

板子:普中科技stm32F1(芯片stm32f1103zet6

1 程序如下:

#include "stm32f10x.h"  //导入头文件

typedef unsigned int u32;//typedef是系统关键字之一,用来给数据类型取一个“别名”,这里就是把unsigned int取名为u16,之后可以用u16定义无符号整型变量了,如,u16 a,b;

void SystemInit()
{
	
}


void delay(u32 i)
{
	while(i--);
}


int main()
{
	RCC_APB2ENR|=1<<4;  //开启GPIOC端口时钟
	GPIOC_CRL&=~(0x0f<<(4*0));
	GPIOC_CRL|=(3<<4*0);
	GPIOC_BSRR=(1<<(16+0));
	while(1)
	{
		GPIOC_BSRR=(1<<(16+0));  //点亮LED
		delay(0xfffff);
		GPIOC_BSRR=(1<<(0));   //熄灭LED
		delay(0xfffff);
	}
}

2首先研究开发板的电路图(红色标号相同说明这两个硬件是连在一起的,即LED1和芯片的26号引脚连在一起),要想点亮灯,需要让26(pc0)引脚输出低电平,即可点亮,即二极管的阳极是3.3,阴极是0,所以二极管导通发光(二极管和LED就认为是一个东西吧,其实也就是一个东西)。

该段程序是使用老师教的自建的寄存器

启动文件是系统带的,可以自己查找,这里已经给出,采用汇编语言编写,芯片插电的时候就会从该文件启动一些必要的功能程序,例如初始化的堆栈、指针,pc初始化程序计数器、设置中断、中断的向量表、入口地址。程序在启动时会进入SystemInit这个函数,所以在main.c文件中写了SystemInit{}空函数,不写这个会报错,虽然没用它实现系统初始化功能,但还是得写。,执行完这个,就要执行MAIN(),启动文件更多功能在“普中STM32F1**开发攻略”和“Cortex M3,涉及了寄存器得指令”可查得?。

3 编写控制LED程序

我们要实现的功能:点亮第一个LED,即D1指示灯亮

(1)要操作STM32寄存器,需要使用c语言对其封装,封装的这部分程序放在STM32F10x.h中

让26号管脚(pc0看芯片图,pc0就是26号管脚)输出低电平,需要对其操作,即对GPIO(通用io口)的配置,所以让GPIO配置为输出模式,,对IO口没有特殊要求,都配置为推挽的输出,还有输出的速度,输出是高电平还是低电平(对ODR进行操作),这些都通过查手册GPIO那一章了解到,

要对寄存器以下封装:

stm32f10x.h 文件

#define PERIPH_BASE      ((unsigned int)0x40000000) //定义GPIO外设的基地址,即BLOCK2的首地址
#define APB2PERIPH_BASE  (PERIPH_BASE + 0x00010000)
#define GPIOC_BASE       (APB2PERIPH_BASE + 0x1000)
#define GPIOC_CRL 	 	 *(unsigned int*)(GPIOC_BASE+0x00)
#define GPIOC_CRH 	 	 *(unsigned int*)(GPIOC_BASE+0x04)
#define GPIOC_IDR 	 	 *(unsigned int*)(GPIOC_BASE+0x08)
#define GPIOC_ODR 	 	 *(unsigned int*)(GPIOC_BASE+0x0C)
#define GPIOC_BSRR 	 	 *(unsigned int*)(GPIOC_BASE+0x10)
#define GPIOC_BRR 	 	 *(unsigned int*)(GPIOC_BASE+0x14)
#define GPIOC_LCKR 	 	 *(unsigned int*)(GPIOC_BASE+0x18)
#define AHBPERIPH_BASE   (PERIPH_BASE + 0x20000)
#define RCC_BASE 		 (AHBPERIPH_BASE + 0x1000)
#define RCC_APB2ENR 	 *(unsigned int*)(RCC_BASE+0x18) 

A:? ? 首先要明白GPIO 这个外设挂接在BLOCK2(所有片内外设都在这个区)区,所以要定于GPIO外设的总线基地址

#define PERIPH_BASE      ((unsigned int)0x40000000) //定义GPIO外设的基地址,即BLOCK2的首地址

BLOCK2的首地址查芯片手册: 普中科技stm32-F1\6--芯片资料\开发板芯片数据手册\STM32F103ZET6.pdf的第四章memory mapping,

B.外设分了很多,GPIO(挂接到APB2)是挂接在APB1、APB2总线、AHB总线,就得找到对应挂接总线的位置,开发攻略里有

#define APB2PERIPH_BASE  (PERIPH_BASE + 0x00010000)

?C.APB2里面挂接了很多外设,例如所以需要知道GPIOC对应的APB2基地址的偏移量:

#define GPIOC_BASE       (APB2PERIPH_BASE + 0x1000)

用上表的GPIOC起始地址减一下APB2的基地址,就可以算出偏移量

D. GPIOC里面封装了好多寄存器,CR\IDR\ODR\BSRR等等。

#define GPIOC_CRL 	 	 *(unsigned int*)(GPIOC_BASE+0x00)
#define GPIOC_CRH 	 	 *(unsigned int*)(GPIOC_BASE+0x04)
#define GPIOC_IDR 	 	 *(unsigned int*)(GPIOC_BASE+0x08)
#define GPIOC_ODR 	 	 *(unsigned int*)(GPIOC_BASE+0x0C)
#define GPIOC_BSRR 	 	 *(unsigned int*)(GPIOC_BASE+0x10)
#define GPIOC_BRR 	 	 *(unsigned int*)(GPIOC_BASE+0x14)
#define GPIOC_LCKR 	 	 *(unsigned int*)(GPIOC_BASE+0x18)

查中文参考手册的第8章

正式对寄存器开始操作了,例如GPIOC_CRL(端口配置低寄存器),不能直接对这个(GPIOC_BASE+0x00)地址写在这儿,keilb并不能识别这是地址,只认为这是立即数,要让它知道是地址,就将这个地址强制转换成指针类型unsigned int*,(*是指针运算符),要求的地址里面的数据,还得再加一个指针*,通过这样的一个宏定义,后面通过?GPIOC_CRL这个名字就能操控这个寄存器的内容了

E.操控GPIO还需要对时钟RCC进行开启,只有开启时钟才能对GPIO进行控制(必须,在操作任何外设之前都应该开启该外设的时钟),找到GPIO外设的时钟基地址,

#define AHBPERIPH_BASE   (PERIPH_BASE + 0x20000)
#define RCC_BASE 		 (AHBPERIPH_BASE + 0x1000)
#define RCC_APB2ENR 	 *(unsigned int*)(RCC_BASE+0x18)

(2)开始点亮LED

#include "stm32f10x.h"  //导入头文件

typedef unsigned int u32;//typedef是系统关键字之一,用来给数据类型取一个“别名”,这里就是把unsigned int取名为u16,之后可以用u16定义无符号整型变量了,如,u16 a,b;

void SystemInit()
{
	
}


void delay(u32 i)
{
	while(i--);
}


int main()
{
	RCC_APB2ENR|=1<<4;  //开启GPIOC端口时钟
	GPIOC_CRL&=~(0x0f<<(4*0));
	GPIOC_CRL|=(3<<4*0);
	GPIOC_BSRR=(1<<(16+0));
	while(1)
	{
		GPIOC_BSRR=(1<<(16+0));  //点亮LED
		delay(0xfffff);
		GPIOC_BSRR=(1<<(0));   //熄灭LED
		delay(0xfffff);       
	}
}
	RCC_APB2ENR|=1<<4;  //开启GPIOC端口时钟

?

查看中文参考手册的6.3章:RCC_APB2ENR,看到第四位1控制时钟开启IOPC,但是又不影响其他的位,通过或运算防止对其他位的干扰,

?

下面对GPIOC_CRL寄存器模式进行配置(通用推挽输出和输出模式最大速度50HZ):

?

	GPIOC_CRL&=~(0x0f<<(4*0));  //将寄存器低四位置零

CRL寄存器控制低八位引脚,CRH寄存器控制高八位引脚,GPIOC0是低八位,所以用CRL寄存器来配置,需要哪些控制,工作模式(输出功能)、并且是推挽输出, 0是指控制第零位 LED灯,4是指寄存器低四位,0x0f是1111,取反再进行与操作,就不会影响其他位的值。即令值为1111,再左移(4*0)位,相当。

GPIOC_CRL|=(3<<4*0);   //配置GPIOC_CRL第四位

我猜3应该是配置11,不移位,并且当MOOE不为00的时候,这个寄存器的端口GPIOC就是输出模式。?

GPIOC的模式控制好了,接下来就是控制pc0(LED)输出数据,因为最终要控制灯嘛,要让灯点亮就输出0嘛。就要用到8.2.4的端口输出数据寄存器(GPIOX_ODR)或者端口位设置/清除寄存器(GPIOx_BSRR),

端口位设置清除寄存器也可以对其进行输出操作,通过它控制端口输出寄存器来控制输出电平,

?

?

GPIOC_BSRR=(1<<(16+0));   //控制输出为低电平

?赋值为1后,左移i6位,+0是第0个LED,要是第二个,就要加2,即第16位进行清除操作

然后就编译,烧录,LED灯闪烁。

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2021-07-26 12:14:17  更:2021-07-26 12:14:43 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/27 10:17:57-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计