概述
本文主要介绍如何在学会了点亮一个led灯的基础上使用GPIOA、GPIOB、GPIOC这3个端口控制LED灯,轮流闪烁,间隔时长0.5秒,即流水灯
准备
STM32最小系统核心板(STM32F103C8T6)
USB TO TTL
面板板
8只红黄绿LED
杜邦线若干
接线图
上图为ST-link的接线图,用USB TO TTL的话按照下图接,没标的地方与上图相同
程序的编译及运行
新建一个工程,新建start组和user组,
将启动文件加到新建的start组中,
新建main.c文件加到新建的user组中
启动文件在文末的“资料”中
使能A时钟
本文用到的是PA0~PA7端口,所以使能A时钟
在时钟使能寄存器表格中查到使能A时钟的位置是2
在位2中查到1时A时钟开启
使能代码为0x00000004(十六进制)
所以使能的代码是
RCC->APB2ENR=0x00000004;
为端口配置低寄存器
CNFY选用00:推挽输出
MODEy选用11:最大速度50hz
同时设置7个端口二进制代码为
0011 0011 0011 0011
0011 0011 0011 0011
转化为六进制为0x33333333
代码为
GPIOA->CRL=0x33333333
为输出端口设置高低电平
以点亮PA0 端口的led为例
将ODR0置为高电平,即ODR0值为1
十六进制表示为0x0000 0001
因为是低电平有效,所以需要用”~“符号取反
即为~0x0000 0001
以此类推
点亮PA1端口的led代码为~0x0000 0002,
点亮PA2端口的led代码为~0x0000 0004,
…
点亮PA1端口led代码为
GPIOA->ODR=~0x00000001;
使用延时函数
要实现流水灯,就要保持前一个led亮一段时间再中断,然后轮到下一个led亮,再中断,再下一个led亮,由此反复。
这时就要在两个led灯点亮的操作中插入一个延时函数进行延时
在Target中新建一个组(存放工程的文件夹中也要创建一个新文件夹,里面存放延时函数的文件),名为System,用来存放其他用到的函数
*延时函数文件在文末的“资料”中
将文件夹中的延时函数文件加到system组中
别忘了加上文件的路径
在main.c 中引用延时头文件,再在每两个“ 为端口设低电平”的操作之间加入延时函数就ok了
完整代码
#include "stm32f10x.h" // Device header
#include "Delay.h" //引用延迟函数
int main(void)
{
RCC->APB2ENR=0x00000004; //使能A时钟
GPIOA->CRL=0x33333333; //为8个端口配置寄存器
while(1)
{
GPIOA->ODR=~0x00000001; //为A0端口置低电平,“~"是取反符,因为是低电平有效,所以取反
Delay_ms(500); //延时500ms
GPIOA->ODR=~0x00000002; //为A1端口置低电平
Delay_ms(500);
GPIOA->ODR=~0x00000004; //为A2端口置低电平
Delay_ms(500);
GPIOA->ODR=~0x00000008; //为3端口置低电平
Delay_ms(500);
GPIOA->ODR=~0x00000010; //为A4端口置低电平
Delay_ms(500);
GPIOA->ODR=~0x00000020; //为A5端口置低电平
Delay_ms(500);
GPIOA->ODR=~0x00000040; //为A6端口置低电平
Delay_ms(500);
GPIOA->ODR=~0x00000080; //为A7端口置低电平
Delay_ms(500);
}
}
编译生成.hex文件,再将其烧录进单片机里
结果
流水灯结果
用PC13端口作为流水灯之一
按上面的方法使能C时钟
整合A时钟的使能代码为:
RCC->APB2ENR=0x00000014;
为PC13配置寄存器
PA0~PA6端口
代码为:
GPIOA->CRH=0x00300000; //为PC13配置寄存器
GPIOA->CRL=0x03333333; //为PA0~PA6端口配置寄存器
为PC13加电平
PA0~PA6加电平方式上文已经写,此处就省略了
完整代码如下:
#include "stm32f10x.h" // Device header
#include "Delay.h" //引用延迟函数
int main(void)
{
RCC->APB2ENR=0x00000014; //使能A、C时钟
GPIOA->CRH=0x00300000; //为PC13配置寄存器
GPIOA->CRL=0x03333333; //为PA0~PA6端口配置寄存器
while(1)
{
GPIOC->ODR=~0x00002000; //为PC13端口置低电平
Delay_ms(500);
GPIOA->ODR=~0x00000001; //为A0端口置低电平,“~"是取反符,因为是低电平有效,所以取反
Delay_ms(500); //延时500ms
GPIOA->ODR=~0x00000002; //为A1端口置低电平
Delay_ms(500);
GPIOA->ODR=~0x00000004; //为A2端口置低电平
Delay_ms(500);
GPIOA->ODR=~0x00000008; //为3端口置低电平
Delay_ms(500);
GPIOA->ODR=~0x00000010; //为A4端口置低电平
Delay_ms(500);
GPIOA->ODR=~0x00000020; //为A5端口置低电平
Delay_ms(500);
GPIOA->ODR=~0x00000040; //为A6端口置低电平
Delay_ms(500);
}
}
运行之后发现PC13端led一直不亮,PA6端led亮了大概一秒,其他五个led正常闪烁,解决办法还在寻找中。
资料
链接:https://pan.baidu.com/s/1xtBAEdt0cRZvsYTI3rlZew
提取码:3232