板子:普中科技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灯闪烁。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)