#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
暂无评论