随记2021/12/06 #c sizeof usage \ 103 GPIO

#c

sizeof 用法

sizeof (a) //一般为数组

sizeof b  //这个变量字符大小

printf sizeof 用 %lu

数组变量本身表达地址

int a[10],int *p = a // 无需用&来取地址

但是数组单元表达的是变量 需要用&来取地址

a == &a[0];

[]运算符可以对数组做 也可以对指针做

p[0] <<==>> a[0]

这是c语言的条件编译,常用于防止重复调用报错,例如 再main.c里已经调用了 head.h头文件,而led.c里也调用了head.h,则使用条件编译可以防止程序崩溃

/*
* C 语言知识,条件编译
* #if 为真
* 执行这里的程序
* #else
* 否则执行这里的程序
* #endif
*/

#32 f103

GPIO (英语:General-purpose input/output),通用型之输入输出的简称,功能类似8051的P0—P3,其接脚可以供使用者由程控自由使用,PIN脚依现实考量可作为通用输入( GPI )或通用输出( GPO )或通用输入与输出( GPIO ),如当clk generator, chip select等。

时钟振荡器产生的频率,使用时钟是为了控制打开和关闭外设,可以节省和降低功耗。

32的电灯,由cpu给GPIO(片内外设)指令,GPIO收到指令后,开始配置自己的寄存器(每一个片内外设都有自己的寄存器,寄存器看芯片手册),然后控制IO口的输出模式(51的是直接拉高拉低IO口点平),以此来达到控制灯的亮灭。

mian.c
#include "bsp_led.h"

void Delay( uint32_t count )
{
	for(; count!=0; count--);
}

int main(void)
{
	// 来到这里的时候,系统的时钟已经被配置成72M。
	LED_GPIO_Config();
	
	while(1)
	{
		//GPIO_SetBits(LED_G_GPIO_PORT, LED_G_GPIO_PIN);
		LED_G(OFF);
		Delay(0xFFFFF);
		//GPIO_ResetBits(LED_G_GPIO_PORT, LED_G_GPIO_PIN);
		LED_G(ON);
		Delay(0xFFFFF);
	}
}
bsp_led.c
// bsp :board support package 板级支持包
#include "bsp_led.h"

void LED_GPIO_Config(void)
{
	GPIO_InitTypeDef  GPIO_InitStruct;
	
	RCC_APB2PeriphClockCmd(LED_G_GPIO_CLK, ENABLE);
	
	GPIO_InitStruct.GPIO_Pin = LED_G_GPIO_PIN;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	
	GPIO_Init(LED_G_GPIO_PORT, &GPIO_InitStruct);	
}

lbsp_led.h
#ifndef __BSP_LED_H
#define __BSP_LED_H

#include "stm32f10x.h"

#define LED_G_GPIO_PIN              GPIO_Pin_0
#define LED_G_GPIO_PORT             GPIOB
#define LED_G_GPIO_CLK              RCC_APB2Periph_GPIOB


#define    ON        1
#define    OFF       0

// \  C语言里面叫续行符,后面不能有任何的东西

#define   LED_G(a)   if(a) \
	                       GPIO_ResetBits(LED_G_GPIO_PORT, LED_G_GPIO_PIN); \
                     else  GPIO_SetBits(LED_G_GPIO_PORT, LED_G_GPIO_PIN);

void LED_GPIO_Config(void);

#endif /* __BSP_LED_H */

外设寄存器 结构体 的定义 封装GPIO寄存器

 //寄存器的值常常是芯片外设自动更改的,即使 CPU 没有执行程序,也有可能发生变化
 //编译器有可能会对没有执行程序的变量进行优化
 //volatile 表示易变的变量,防止编译器优化,
 #define __IO volatile
 typedef unsigned int uint32_t; 
 typedef unsigned short uint16_t;  // GPIO 寄存器结构体定 义
 typedef struct
 {
 __IO uint32_t CRL; // 端口配置低寄存器, 地址偏移 0X00
 __IO uint32_t CRH; // 端口配置高寄存器, 地址偏移 0X04
 __IO uint32_t IDR; // 端口数据输入寄存器, 地址偏移 0X08
 __IO uint32_t ODR; // 端口数据输出寄存器, 地址偏移 0X0C
 __IO uint32_t BSRR; // 端口位设置/清除寄存器,地址偏移 0X10
 __IO uint32_t BRR; // 端口位清除寄存器, 地址偏移 0X14
 __IO uint32_t LCKR; // 端口配置锁定寄存器, 地址偏移 0X18
 } GPIO_TypeDef;

结构体定义仅仅只是定义,外设存储器映射才能实现操作结构体就能给寄存器赋值 //映射就是将寄存器地址跟结构体地址对应起来,将这些外设地址一个个定义成宏

/* 片上外设基地址 */
#define PERIPH_BASE ((unsigned int)0x40000000)
/*APB2 总线基地址 */
#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000)
/* AHB 总线基地址 */
#define AHBPERIPH_BASE (PERIPH_BASE + 0x20000)
/*GPIO 外设基地址 */
#define GPIOA_BASE (APB2PERIPH_BASE + 0x0800)
#define GPIOB_BASE (APB2PERIPH_BASE + 0x0C00)
#define GPIOC_BASE (APB2PERIPH_BASE + 0x1000)
#define GPIOD_BASE (APB2PERIPH_BASE + 0x1400)
#define GPIOE_BASE (APB2PERIPH_BASE + 0x1800)
#define GPIOF_BASE (APB2PERIPH_BASE + 0x1C00)
#define GPIOG_BASE (APB2PERIPH_BASE + 0x2000)
/*RCC 外设基地址 */
#define RCC_BASE (AHBPERIPH_BASE + 0x1000)
完成映射后,把外设的基地址强制类型转换成相应的外设结构体寄存器指针,把指针声明成外设名,这样就方便理解操作,简约大方
 / GPIO 外设声明
2 #define GPIOA ((GPIO_TypeDef *) GPIOA_BASE)
3 #define GPIOB ((GPIO_TypeDef *) GPIOB_BASE)
4 #define GPIOC ((GPIO_TypeDef *) GPIOC_BASE)
5 #define GPIOD ((GPIO_TypeDef *) GPIOD_BASE)
6 #define GPIOE ((GPIO_TypeDef *) GPIOE_BASE)
7 #define GPIOF ((GPIO_TypeDef *) GPIOF_BASE)
8 #define GPIOG ((GPIO_TypeDef *) GPIOG_BASE)

这些事c语言封装

版权声明:本文为CSDN博主「我不喝忘情水」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/m0_59458126/article/details/121759038

生成海报
点赞 0

我不喝忘情水

我还没有学会写个人说明!

暂无评论

相关推荐

SQL585A是一款电子点烟器咪头专用芯片

概述 SQL585A是一款电子点烟器专用芯片。 SQL585A集成 4.0A的放电MOS开关,无需外部MOS,大大降低BOM成本。放电支持 10S超时保护, 以及微秒级快速响应的短路保护,

蓝桥杯嵌入式学习总结

重要引脚 GPIO功能PA1TIM2_CH2 / SER(74LS595串行数据输入引脚) / 频率可调脉冲PA2TIM2_CH3 / USART2_TX / RCK(74LS595串行存储时钟输入引脚) / 频率可调脉冲PA3USART2_