stm32f103c8基于寄存器和标准外设库编写流水灯
一.寄存器
目录
1.创建工程
先创建一个自命名的工程,再将stm32的启动文件放入工程中去,
2.设置hex文件
找到魔法棒,然后选择output,点击creat hex file,如果要选择指定的文件存放地址,也可以在上方的slect folder for objects上选择指定文件夹存放。
3.编写代码
创一个main的c文件进行编写.
main2.c
#define GPIOB_BASE 0x40010C00
#define GPIOC_BASE 0x40011000
#define GPIOA_BASE 0x40010800
#define RCC_APB2ENR (*(unsigned int *)0x40021018)
#define GPIOB_CRL (*(unsigned int *)0x40010C00)
#define GPIOC_CRH (*(unsigned int *)0x40011004)
#define GPIOA_CRL (*(unsigned int *)0x40010800)
#define GPIOB_ODR (*(unsigned int *)0x40010C0C)
#define GPIOC_ODR (*(unsigned int *)0x4001100C)
#define GPIOA_ODR (*(unsigned int *)0x4001080C)
void SystemInit(void);
void Delay_ms(volatile unsigned int);
void Delay_ms( volatile unsigned int t)
{
unsigned int i;
while(t--)
for (i=0;i<800;i++);
}
int main(){
// 开启时钟
RCC_APB2ENR |= (1<<3); // 开启 GPIOB 时钟
RCC_APB2ENR |= (1<<4); // 开启 GPIOC 时钟
RCC_APB2ENR |= (1<<2); // 开启 GPIOA 时钟
// 设置 GPIO 为推挽输出
// 设置 GPIOB 最后四位为 0001 (B0)
GPIOB_CRL |= (1<<0); // 最后一位设置为1
GPIOB_CRL &= ~(0xE); // 倒数二、三、四位设置为0
// 设置 GPIOC 前四位为 0001 (C15)
GPIOC_CRH |= (1<<28); // 第四位设置为1
GPIOC_CRH &= ~(0xE0000000); // 前三位设置为0
// 设置 GPIOA 最后四位为 0001 (A0)
GPIOA_CRL |= (1<<0); // 最后一位设置为1
GPIOA_CRL &= ~(0xE); // 倒数二、三、四位设置为0
// 3个LED初始化为不亮(即高点位)
GPIOB_ODR |= (1<<0); // 最后一位设置为1
GPIOC_ODR |= (1<<15); // 倒数第15位设置为1
GPIOA_ODR |= (1<<0); // 最后一位设置为1
while(1){
GPIOB_ODR &= ~(1<<0); // 点灯1
Delay_ms(1000);
GPIOB_ODR |= (1<<0); // 灭灯1
Delay_ms(1000);
GPIOC_ODR &= ~(1<<15); // 点灯2
Delay_ms(1000);
GPIOC_ODR |= (1<<15); // 灭灯2
Delay_ms(1000);
GPIOA_ODR &= ~(1<<0); // 点灯3
Delay_ms(1000);
GPIOA_ODR |= (1<<0); // 灭灯3
Delay_ms(1000);
}
}
void SystemInit(){
}
然后进行编译
4.硬件连接
在此使用的两个硬件为 usb to ttl 和stm32f103c8t6
GND 连 GND
3V3 连 3V3
TXD 连 A10
RXD 连 A9
插入图片 4-5
然后连led灯,
可根据程序得知,3个led灯分别于A0,B0,C15相接。然后还需要3.3接正极,此外,led灯的长的一段连正极,短的一端连负极。
5.结果
插入图片 4-7
注:如果没有串口助手可自行百度下载。
二.标准外设库
1.下载标准外设库并使用
先到相应的官网进行下载,网址为https://www.st.com/zh/embedded-software/stm32-standard-peripheral-libraries.html
下载完毕之后,再进行标准库的导入,导入可参考https://www.bilibili.com/video/BV1rF411m7TY/?spm_id_from=333.999.0.0.和https://www.bilibili.com/video/BV1zk4y1w71E/?spm_id_from=333.788&vd_source=70cfb857bfc9e5d05f2da6cca5c941af
2.进行编程
在项目中新建一个文件,来放时延函数
delay.c
#include "delay.h"
//
//如果需要使用OS,则包括下面的头文件即可.
#if SYSTEM_SUPPORT_OS
#include "includes.h" //ucos 使用
#endif
void delay_ms(u16 nms)
{
u32 temp;
SysTick->LOAD=nms*9000; //时间加载(SysTick->LOAD为24bit)
SysTick->VAL =0x00; //清空计数器
SysTick->CTRL=0x01 ; //开始倒数
do
{
temp=SysTick->CTRL;
}while((temp&0x01)&&!(temp&(1<<16))); //等待时间到达
SysTick->CTRL=0x00; //关闭计数器
SysTick->VAL =0X00; //清空计数器
//u16 i=0;
//while(nms--){
//i=10000;
//while(i--);
//}
}
#endif
delay.h
#ifndef __DELAY_H
#define __DELAY_H
#include "sys.h"
void delay_ms(u16 nms);
#endif
然后编写主函数
#include "stm32f10x.h" // Device header
#include "delay.h"
int main(void)
{
//时钟配置
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//开启PA5口的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);//开启PB9口的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);//开启PC14口的时钟
//输入输出模式设置,输出速度设置
GPIO_InitTypeDef GPIO_InitStructureA, GPIO_InitStructureB, GPIO_InitStructureC;
// 配置A5
GPIO_InitStructureA.GPIO_Mode = GPIO_Mode_Out_PP;// 点灯用推挽输出
GPIO_InitStructureA.GPIO_Pin = GPIO_Pin_5;// 选择5号引脚
GPIO_InitStructureA.GPIO_Speed = GPIO_Speed_50MHz;//选择输出速度
//配置B9
GPIO_InitStructureB.GPIO_Mode = GPIO_Mode_Out_PP;// 点灯用推挽输出
GPIO_InitStructureB.GPIO_Pin = GPIO_Pin_9;// 选择9号引脚
GPIO_InitStructureB.GPIO_Speed = GPIO_Speed_50MHz;//选择输出速度
//配置C14
GPIO_InitStructureC.GPIO_Mode = GPIO_Mode_Out_PP;// 点灯用推挽输出
GPIO_InitStructureC.GPIO_Pin = GPIO_Pin_14;// 选择14号引脚
GPIO_InitStructureC.GPIO_Speed = GPIO_Speed_50MHz;//选择输出速度
GPIO_Init(GPIOA, &GPIO_InitStructureA);// GPIOA外设的5号引脚配置为推挽输出、50MHz速度
GPIO_Init(GPIOB, &GPIO_InitStructureB);//GPIOB外设的9号引脚配置为推挽输出、50MHz速度
GPIO_Init(GPIOC, &GPIO_InitStructureC);//GPIOC外设的14号引脚配置为推挽输出、50MHz速度
while(1)
{
//A亮
GPIO_WriteBit(GPIOA, GPIO_Pin_5, Bit_RESET);//Bit_RESET电平0,Bit_SET电平1
delay_ms(1000);
//B亮
GPIO_WriteBit(GPIOA, GPIO_Pin_5, Bit_SET);
GPIO_WriteBit(GPIOB, GPIO_Pin_9, Bit_RESET);
delay_ms(1000);
//C亮
GPIO_WriteBit(GPIOB, GPIO_Pin_9, Bit_SET);
GPIO_WriteBit(GPIOC, GPIO_Pin_14, Bit_RESET);
delay_ms(1000);
GPIO_WriteBit(GPIOC, GPIO_Pin_14, Bit_SET);
}
}
3.调试
4.硬件连接
usb to ttl 和stm32f103c8t6的连接与寄存器的一致,
但3个led灯在程序中分别与A5,B9,C14相连
5.结果
6.观察波形
通过keil的仿真实验最后得出的波形为
三.总结
相比于寄存器,标准外设库可以直接调用函数,更加方便,而且波形比较准确,虽然比较推崇标准库,但对于初学者来说应该两个都要了解一些。