stm32c8t6寄存器方式与标准库方式流水灯

一、寄存器流水灯

0、找寄存器地址的方法

第一步,找到GPIOB的基地址
手册中没有直接给出所有的寄存器的地址,需要读者稍加计算。STM32给不同的寄存器分配了不同的地址,有点像划分了片区。在《STM32中文参考手册_V10》的第28页,有不同寄存器的地址范围。
现在,假如我们想读取PB3引脚的电平,该怎么找到相关的寄存器?
  也就是找到GPIOB的小区。结论是,所有GPIOB相关的寄存器,都住在0x4001 0C00到0x4001 0FFF范围内
  在这里插入图片描述

第二步,找到端口输入寄存器的地址偏移
找到存储数据的那个屋子,结论是0x4001 0C00+8 = 0x4001 0C08
在这里插入图片描述
第三步,找到知道数据的那个人
PB3的数据位于从右往左数第4个。
在这里插入图片描述

1、程序设计思路以及代码实现

首先要配置时钟使能。为什么配置时钟?为了省电,默认的时钟都是关闭的。配置STM32的任何资源前,都必须首先使能时钟。

(1)使能GPIO时钟(APB2外设时钟使能寄存器)

在这里插入图片描述

在这里插入图片描述

	//打开gpio A端口的时钟
	*(unsigned int *)0x40021018 |=(1<<2);
	//打开gpio B端口的时钟
	*(unsigned int *)0x40021018 |=(1<<3);
	//打开gpio C端口的时钟
	*(unsigned int *)0x40021018 |=(1<<4);

(2)端口配置低寄存器配置输出模式

每一个端口需要四位进行配置,16个端口就需要64位进行配置,所以端口配置寄存器有两个,一个是端口配置低寄存器,一个是端口配置高寄存器,但高寄存器一般没用暂时不管
在这里插入图片描述

在这里插入图片描述

	*(unsigned int *)0x40010800 &=0xFFFFFFF0;//设置位 清零
	*(unsigned int *)0x40010800 |=0x00000002;//PA0推挽输出2MHz
	
	*(unsigned int *)0x40010C04 &=0xFFFFFF0F;//设置位清零
	*(unsigned int *)0x40010C04 |=0x00000020;//PB9推挽输出2MHz
	
	*(unsigned int *)0x40011004 &=0xFF0FFFFF;//设置位清零
	*(unsigned int *)0x40011004 |=0x20000000;//PC15推挽输出2MHz

(3)端口输入数据寄存器和端口输出数据寄存器

在这里插入图片描述

端口输入数据寄存器,低16位对应16个引脚,高16位没有用
在这里插入图片描述
端口输出数据寄存器,同样是低16位对应16个引脚,高16位没有用

	*(unsigned int *)0x40010800 &=0xFFFFFFF0;//设置位 清零
	*(unsigned int *)0x40010800 |=0x00000002;//PA0推挽输出
	
	*(unsigned int *)0x40010C04 &=0xFFFFFF0F;//设置位清零
	*(unsigned int *)0x40010C04 |=0x00000020;//PB9推挽输出
	
	*(unsigned int *)0x40011004 &=0xFF0FFFFF;//设置位清零
	*(unsigned int *)0x40011004 |=0x20000000;//PC15推挽输出
	

(4)实现流水灯

//函数封装
void A_LED_LIGHT(){
	*(unsigned int *)0x4001080C=0x0<<0;		//PA0低电平
	*(unsigned int *)0x40010C0C=0x1<<9;		//PB9高电平
	*(unsigned int *)0x4001100C=0x1<<15;		//PC15高电平
}
void B_LED_LIGHT(){
	*(unsigned int *)0x4001080C=0x1<<0;		//PA0高电平
	*(unsigned int *)0x40010C0C=0x0<<9;		//PB9低电平
	*(unsigned int *)0x4001100C=0x1<<15;		//PC15高电平
}
void C15_LED_LIGHT(){
	*(unsigned int *)0x4001080C=0x1<<0;		//PA0高电平
	*(unsigned int *)0x40010C0C=0x1<<9;		//PB9高电平
	*(unsigned int *)0x4001100C=0x0<<15;		//PC15低电平	
}
//主函数
	while(1)
	{
		A_LED_LIGHT();
		Delay_ms(100);
		B_LED_LIGHT();
		Delay_ms(100);
		C15_LED_LIGHT();
		Delay_ms(100);

寄存器流水灯2

(5)修改代码点亮PC13

修改(3)中代码

	*(unsigned int *)0x40010800 &=0xFFFFFFF0;//设置位 清零
	*(unsigned int *)0x40010800 |=0x00000002;//PA0推挽输出
	
	*(unsigned int *)0x40010C04 &=0xFFFFFF0F;//设置位清零
	*(unsigned int *)0x40010C04 |=0x00000020;//PB9推挽输出
	
	*(unsigned int *)0x40011004 &=0xFF0FFFFF;//设置位清零
	*(unsigned int *)0x40011004 |=0x00200000;//PC13推挽输出
	

寄存器流水灯1

二、标准库方式流水灯

1、程序流程

与上一过程大致相同,但是用库函数实现

#include "stm32f10x.h"                  // Device header
#include "Delay.h"

int main(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//使能GPIOA时钟
	
	GPIO_InitTypeDef GPIO_InitStructure;//创建结构体
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//设置推挽输出
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;//作用于所有端口
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//输出模式50MHz
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	while (1)
	{
		GPIO_Write(GPIOA, ~0x0001);	//0000 0000 0000 0001
		Delay_ms(1000);
		GPIO_Write(GPIOA, ~0x0002);	//0000 0000 0000 0010
		Delay_ms(1000);
		GPIO_Write(GPIOA, ~0x0004);	//0000 0000 0000 0100
		Delay_ms(1000);
		GPIO_Write(GPIOA, ~0x0008);	//0000 0000 0000 1000
		Delay_ms(1000);
		GPIO_Write(GPIOA, ~0x0010);	//0000 0000 0001 0000
		Delay_ms(1000);
		GPIO_Write(GPIOA, ~0x0020);	//0000 0000 0010 0000
		Delay_ms(1000);
		GPIO_Write(GPIOA, ~0x0040);	//0000 0000 0100 0000
		Delay_ms(1000);
		GPIO_Write(GPIOA, ~0x0080);	//0000 0000 1000 0000
		Delay_ms(1000);
	}
}

标准库流水灯1s闪烁

2、新建项目文件,添加标准外设库文件详细过程

参考b站up主江科大自化协
1、打开keil,点击Project,选择New uVision Project
2、创建工程我是stm32f103c8t6中等容量
Device选择stm32f103c8
在这里插入图片描述
3、弹出工程小助手暂时不用在这里插入图片描述
4准备好stm32启动文件,粘贴到工程目录下的Start文件目录下

在这里插入图片描述
在这里插入图片描述
5、stm32外设寄存器描述文件和51单片机头文件REGX52.H作用类似,描述寄存器及其地址,两个System文件主要用来配置时钟,也粘贴到Start文件目录

在这里插入图片描述
6添加内核寄存器描述文件,同样复制到Start目录下

在这里插入图片描述
7、keil目录中创建文件夹并添加文件

在这里插入图片描述
8、添加文件目录路径

在这里插入图片描述
9、设置文件编码在这里插入图片描述

10、设置Debugger我用的STLink所以设置的STLink

在这里插入图片描述

11、设置下载后立即复位,并把下方的容量改为128K

在这里插入图片描述

12、新建库函数文件夹Library并添加库函数文件

在这里插入图片描述
在这里插入图片描述
13、在keil中新建目录
在这里插入图片描述

14、conf文件用来配置库函数文件包含关系
两个it结尾的文件用来存放中断函数(interrupt)

在这里插入图片描述
添加到keil,User目录
在这里插入图片描述
15、包含标准外设库
在这里插入图片描述

在这里插入图片描述

16、再次添加头文件路径

在这里插入图片描述

3、用Keil仿真逻辑分析仪探究软件延时与准确周期差别

按照图示勾选

在这里插入图片描述
Dialog DLL填写途中蓝色的值
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

	while(1)
	{
		A_LED_LIGHT();
		Delay_ms(1000);
		B_LED_LIGHT();
		Delay_ms(1000);
		C13_LED_LIGHT();
		Delay_ms(1000);
	}

我在主程序中设置的三盏灯每盏灯轮流亮1000ms即1s
在波形图中低电平持续时间实际为0.666982s
高电平持续时间实际为1.333964s
差距较大

https://blog.csdn.net/weixin_48896613/article/details/125664514
https://blog.csdn.net/qq_45689790/article/details/114077879
https://blog.csdn.net/qq_43279579/article/details/110320013

好的,以下是使用Keil5编写的一个控制STM32C8T6开发板上的小灯流水灯的程序: ```c #include "stm32f10x.h" void delay(uint32_t time) { while(time--); } int main(void) { // 初始化GPIO端口 RCC->APB2ENR |= RCC_APB2ENR_IOPAEN; // 使能GPIOA时钟 GPIOA->CRL &= ~(GPIO_CRL_MODE0 | GPIO_CRL_CNF0); // PA0输出模式 GPIOA->CRL &= ~(GPIO_CRL_MODE1 | GPIO_CRL_CNF1); // PA1输出模式 // 初始化按钮GPIO端口 RCC->APB2ENR |= RCC_APB2ENR_IOPBEN; // 使能GPIOB时钟 GPIOB->CRH &= ~GPIO_CRH_MODE11; // PB11输入模式 GPIOB->CRH &= ~GPIO_CRH_CNF11; // PB11浮空输入 GPIOB->CRL &= ~GPIO_CRL_MODE1; // PB1输入模式 GPIOB->CRL &= ~GPIO_CRL_CNF1; // PB1浮空输入 while (1) { if ((GPIOB->IDR & GPIO_IDR_IDR11) != GPIO_IDR_IDR11) { // 按钮按下时,流水灯亮灭 GPIOA->BSRR = GPIO_BSRR_BS0; // PA0输出高电平 GPIOA->BSRR = GPIO_BSRR_BR1; // PA1输出低电平 delay(1000000); GPIOA->BSRR = GPIO_BSRR_BR0; // PA0输出低电平 GPIOA->BSRR = GPIO_BSRR_BS1; // PA1输出高电平 delay(1000000); } else { // 按钮未按下时,小灯熄灭 GPIOA->BSRR = GPIO_BSRR_BR0; // PA0输出低电平 GPIOA->BSRR = GPIO_BSRR_BR1; // PA1输出低电平 } } } ``` 这段代码会不断地检测按钮是否按下,如果按下了,则小灯会以流水灯方式亮灭,否则小灯会熄灭。其中,PA0接小灯的正极,PA1接小灯的负极;PB11和PB1分别连接按钮。 请注意,此代码假设你已经正确配置了Keil5和STM32C8T6开发板的环境。如果你还没有配置好环境,你需要先进行相应的配置才能正确编译和下载代码到开发板上。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值