一.查询和配置GPIOX的A.B.C端口的的地址
经过手册的查询,发现GPIOX的所有地址都位与APB2的总线上,各有相应的偏移地址
经过查询可知GPIOA的地址开始于0X4001 0800, GPIOB的地址开始于0x4001 0c00,GPIOC的地址开始与0X4001 1000。
由于我的实验选择的是PA2,PB6,PC15口,PA和PB选择就要选择CRL端口低八位寄存器,PC15就要选择CRH端口高八位寄存器。所以在配置PC15的寄存器时要配置GPIOC的输入地址要选择为0X40011004,输出地址CDR要选择为0X4001 100C
如上PA2和PB6也要配置相应的输入寄存器地址和输出寄存器地址,总体的地址代码如下
#define RCC_AP2ENR *((unsigned volatile int*)0x40021018)
#define GPIOA_CRL *((unsigned volatile int*)0x40010800)
#define GPIOA_ORD *((unsigned volatile int*)0x4001080C)
#define GPIOB_CRL *((unsigned volatile int*)0x40010C00)
#define GPIOB_ORD *((unsigned volatile int*)0x40010C0C)
#define GPIOC_CRH *((unsigned volatile int*)0x40011004)
#define GPIOC_ORD *((unsigned volatile int*)0x4001100C)
这样一来就配置完ABC输出端口的地址了,然后分别配置ABC端口的外设时钟使能,分别配置给PA2,PB6,PC15
RCC_AP2ENR|=1<<2;
RCC_AP2ENR|=1<<3;
RCC_AP2ENR|=1<<4;
分别给GPIOA,GPIOB,GPIOC增添外设时钟使能。
然后分别对CRL,CRH输入寄存器输入相应的值,对其地址的数据进行更改,然后分别使用各个的输出寄存器将值带出后清零熄灯,然后下一个灯在亮起来如此循环总体代码如下:
#define RCC_AP2ENR *((unsigned volatile int*)0x40021018)
#define GPIOA_CRL *((unsigned volatile int*)0x40010800)
#define GPIOA_ORD *((unsigned volatile int*)0x4001080C)
#define GPIOB_CRL *((unsigned volatile int*)0x40010C00)
#define GPIOB_ORD *((unsigned volatile int*)0x40010C0C)
#define GPIOC_CRH *((unsigned volatile int*)0x40011004)
#define GPIOC_ORD *((unsigned volatile int*)0x4001100C)
void Delay_ms( volatile unsigned int t)
{
unsigned int i;
while(t--)
for (i=0;i<800;i++);
}
void A_LED_LIGHT(){
GPIOA_ORD=0x0<<2;
GPIOB_ORD=0x1<<6;
GPIOC_ORD=0x1<<15;
}
void B_LED_LIGHT(){
GPIOA_ORD=0x1<<2;
GPIOB_ORD=0x0<<6;
GPIOC_ORD=0x1<<15;
}
void C_LED_LIGHT(){
GPIOA_ORD=0x1<<2;
GPIOB_ORD=0x1<<6;
GPIOC_ORD=0x0<<15;
}
int main()
{
int j=100;
RCC_AP2ENR|=1<<2;
RCC_AP2ENR|=1<<3;
RCC_AP2ENR|=1<<4;
GPIOA_CRL&=0xFFFFF0FF;
GPIOA_CRL|=0x00000200;
GPIOA_ORD|=1<<2;
GPIOB_CRL&=0xF0FFFFFF;
GPIOB_CRL|=0x02000000;
GPIOB_ORD|=1<<6;
GPIOC_CRH&=0x0FFFFFFF;
GPIOC_CRH|=0x30000000;
GPIOC_ORD|=0x1<<15;
while(j)
{
A_LED_LIGHT();
Delay_ms(10000000);
B_LED_LIGHT();
Delay_ms(10000000);
C_LED_LIGHT();
Delay_ms(10000000);
}
}
但要注意在使用keilv5的时候新建工程后新建项目后要点击魔法笔配置环境debug如下
output窗口中一定要将生成hex文件勾选出来,这样才能生成hex文件,默认是不勾选的。
二.烧录程序
代码如上构建出相应的hex文件,然后使用USB转TTL端口将生成的HEX文件烧录到我们的stm32f103c8t6芯片上,相应的接法为TTL-C8T6,GND-GND,3V3-3V3,TXD-A10,RXD-A9,然后打开FLYMUC点击搜索端口,将相应端口录入将BPS调到256000,
然后点击读取器件信息确认芯片链接成功
最后点击开始编程出现以下信息便是程序烧录成功
三.运行LED灯
最后将芯片插入面包板,面包板的相应逻辑为上下各五行,每同一列的五行端口是相等的,将芯片插入后用杜邦线链接PA2,PB6,PC15与各自的LED灯,LED灯的接法为长脚接正极,短脚接面包板的内10行,在将杜邦线接触的ABC端口与LED灯的短脚等价,最后将芯片的3V3接入面包板的正极,再插入电源就可以正常运行了然后得出以下结果
以上,循环亮三个LED灯,完成流水灯的制作。
四 总结
此次用STM32F103C8T6芯片制作流水灯的实验让我对用寄存器地址调用的方式进行了初步的学习,进一步使用了寄存器地址输出与时钟使能的配置,在使用串口烧录程序和面包板使用的过程中遇到了不少的问题,去网上学习和请教同学慢慢的学会了使用,有了很大的进步。
一.查询和配置GPIOX的A.B.C端口的的地址
经过手册的查询,发现GPIOX的所有地址都位与APB2的总线上,各有相应的偏移地址
经过查询可知GPIOA的地址开始于0X4001 0800, GPIOB的地址开始于0x4001 0c00,GPIOC的地址开始与0X4001 1000。
由于我的实验选择的是PA2,PB6,PC15口,PA和PB选择就要选择CRL端口低八位寄存器,PC15就要选择CRH端口高八位寄存器。所以在配置PC15的寄存器时要配置GPIOC的输入地址要选择为0X40011004,输出地址CDR要选择为0X4001 100C
如上PA2和PB6也要配置相应的输入寄存器地址和输出寄存器地址,总体的地址代码如下
#define RCC_AP2ENR *((unsigned volatile int*)0x40021018)
#define GPIOA_CRL *((unsigned volatile int*)0x40010800)
#define GPIOA_ORD *((unsigned volatile int*)0x4001080C)
#define GPIOB_CRL *((unsigned volatile int*)0x40010C00)
#define GPIOB_ORD *((unsigned volatile int*)0x40010C0C)
#define GPIOC_CRH *((unsigned volatile int*)0x40011004)
#define GPIOC_ORD *((unsigned volatile int*)0x4001100C)
这样一来就配置完ABC输出端口的地址了,然后分别配置ABC端口的外设时钟使能,分别配置给PA2,PB6,PC15
RCC_AP2ENR|=1<<2;
RCC_AP2ENR|=1<<3;
RCC_AP2ENR|=1<<4;
分别给GPIOA,GPIOB,GPIOC增添外设时钟使能。
然后分别对CRL,CRH输入寄存器输入相应的值,对其地址的数据进行更改,然后分别使用各个的输出寄存器将值带出后清零熄灯,然后下一个灯在亮起来如此循环总体代码如下:
#define RCC_AP2ENR *((unsigned volatile int*)0x40021018)
#define GPIOA_CRL *((unsigned volatile int*)0x40010800)
#define GPIOA_ORD *((unsigned volatile int*)0x4001080C)
#define GPIOB_CRL *((unsigned volatile int*)0x40010C00)
#define GPIOB_ORD *((unsigned volatile int*)0x40010C0C)
#define GPIOC_CRH *((unsigned volatile int*)0x40011004)
#define GPIOC_ORD *((unsigned volatile int*)0x4001100C)
void Delay_ms( volatile unsigned int t)
{
unsigned int i;
while(t--)
for (i=0;i<800;i++);
}
void A_LED_LIGHT(){
GPIOA_ORD=0x0<<2;
GPIOB_ORD=0x1<<6;
GPIOC_ORD=0x1<<15;
}
void B_LED_LIGHT(){
GPIOA_ORD=0x1<<2;
GPIOB_ORD=0x0<<6;
GPIOC_ORD=0x1<<15;
}
void C_LED_LIGHT(){
GPIOA_ORD=0x1<<2;
GPIOB_ORD=0x1<<6;
GPIOC_ORD=0x0<<15;
}
int main()
{
int j=100;
RCC_AP2ENR|=1<<2;
RCC_AP2ENR|=1<<3;
RCC_AP2ENR|=1<<4;
GPIOA_CRL&=0xFFFFF0FF;
GPIOA_CRL|=0x00000200;
GPIOA_ORD|=1<<2;
GPIOB_CRL&=0xF0FFFFFF;
GPIOB_CRL|=0x02000000;
GPIOB_ORD|=1<<6;
GPIOC_CRH&=0x0FFFFFFF;
GPIOC_CRH|=0x30000000;
GPIOC_ORD|=0x1<<15;
while(j)
{
A_LED_LIGHT();
Delay_ms(10000000);
B_LED_LIGHT();
Delay_ms(10000000);
C_LED_LIGHT();
Delay_ms(10000000);
}
}
但要注意在使用keilv5的时候新建工程后新建项目后要点击魔法笔配置环境debug如下
output窗口中一定要将生成hex文件勾选出来,这样才能生成hex文件,默认是不勾选的。
二.烧录程序
代码如上构建出相应的hex文件,然后使用USB转TTL端口将生成的HEX文件烧录到我们的stm32f103c8t6芯片上,相应的接法为TTL-C8T6,GND-GND,3V3-3V3,TXD-A10,RXD-A9,然后打开FLYMUC点击搜索端口,将相应端口录入将BPS调到256000,
然后点击读取器件信息确认芯片链接成功
最后点击开始编程出现以下信息便是程序烧录成功
三.运行LED灯
最后将芯片插入面包板,面包板的相应逻辑为上下各五行,每同一列的五行端口是相等的,将芯片插入后用杜邦线链接PA2,PB6,PC15与各自的LED灯,LED灯的接法为长脚接正极,短脚接面包板的内10行,在将杜邦线接触的ABC端口与LED灯的短脚等价,最后将芯片的3V3接入面包板的正极,再插入电源就可以正常运行了然后得出以下结果
以上,循环亮三个LED灯,完成流水灯的制作。
四 总结
此次用STM32F103C8T6芯片制作流水灯的实验让我对用寄存器地址调用的方式进行了初步的学习,进一步使用了寄存器地址输出与时钟使能的配置,在使用串口烧录程序和面包板使用的过程中遇到了不少的问题,去网上学习和请教同学慢慢的学会了使用,有了很大的进步。
举报