纯C代码模拟stm32 的结构体赋值,快速掌握stm32开发

stm32系统 的C语法一开始难度大,采用C语言模拟,能快速上手。

简单版本

//run C @ https://www.jyshare.com/compile/11/
#include <stdio.h>

// 模拟GPIO寄存器结构
typedef struct {
    unsigned int pinState : 1; // 仅模拟单个引脚的状态,0表示低电平,1表示高电平
} SimpleGPIO_TypeDef;
// 定义一个SimpleGPIO_TypeDef类型的变量,并将其地址强制转换为SimpleGPIO_TypeDef*类型


SimpleGPIO_TypeDef simulatedGPIO = {0};
//或 int  simulatedGPIO = 1;//随意数字均可

#define SIMULATED_GPIO_BASE ((SimpleGPIO_TypeDef*)&simulatedGPIO)

// 初始化结构体
typedef struct {
    unsigned int pinNumber;      // 配置的引脚编号,仅为教学目的模拟
    unsigned int initialState;   // 初始状态,0或1
} SimpleGPIO_InitTypeDef;

// 模拟GPIO初始化函数
void simpleGPIO_Init(SimpleGPIO_TypeDef* GPIOx, SimpleGPIO_InitTypeDef* initStruct) {
    if (initStruct->pinNumber == 2) { // 假设我们只模拟Pin2
        GPIOx->pinState = initStruct->initialState; // 设置初始状态
        printf("GPIO Pin2 initialized to state %d at address %p.\n", 
               initStruct->initialState, (void*)SIMULATED_GPIO_BASE);
    } else {
        printf("Invalid pin number. Simulation supports only Pin2.\n");
    }
}

int main() {
    SimpleGPIO_InitTypeDef GPIO_Config = {2, 1}; // 配置Pin2,初始状态为高电平
    
    // 使用模拟的基地址初始化模拟GPIO
    simpleGPIO_Init(SIMULATED_GPIO_BASE, &GPIO_Config);
    
    return 0;
}

 解释 &simulatedGPIO

定义了一个变量simulatedGPIO,取了其地址,模拟GPIOA的地址

SimpleGPIO_TypeDef simulatedGPIO = {0};

//或 int simulatedGPIO = 1;//随意数字均可

#define SIMULATED_GPIO_BASE ((SimpleGPIO_TypeDef*)&simulatedGPIO)

进阶版本

进阶版本,内容更多,更接近了真实的赋值,地址采用了(GPIO_TypeDef *) 0的方式,这个方式不好理解可以略过,理解以上&simulatedGPIO即可。

#include <stdio.h>
#include <stdint.h>

// 模拟GPIO结构体
typedef struct {
    uint32_t GPIO_Pin;
    uint32_t GPIO_Mode;
    uint32_t GPIO_Speed;
    uint32_t GPIO_OType;
    uint32_t GPIO_PuPd;
} GPIO_InitTypeDef;

// 模拟GPIO寄存器结构体
typedef struct {
    uint32_t MODER;
    uint32_t OTYPER;
    uint32_t OSPEEDR;
    uint32_t PUPDR;
    uint32_t IDR;
    uint32_t ODR;
    // 其他寄存器可以按需添加
} GPIO_TypeDef;

// 模拟GPIO基地址

int PortA=0x12;
int PortC=0x67;//这里没用上,地址直接用0代替
#define GPIOA ((GPIO_TypeDef *) &PortA) 
#define GPIOC ((GPIO_TypeDef *) 0) //这里也可以采用上句,更接近stm32真实地址

// 模拟GPIO引脚
#define GPIO_Pin_2  ((uint16_t)0x0004)  // PC2

// 模拟GPIO初始化函数
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct) {
    // 模拟初始化过程
    printf("Initializing GPIO pin %d with mode %d, speed %d, output type %d, pull-up/pull-down %d\n",
           GPIO_InitStruct->GPIO_Pin, GPIO_InitStruct->GPIO_Mode, GPIO_InitStruct->GPIO_Speed,
           GPIO_InitStruct->GPIO_OType, GPIO_InitStruct->GPIO_PuPd);

    // 模拟设置寄存器
    GPIOx->MODER &= ~(3 << (2 * 2));  // 清除PC2的模式位
    GPIOx->MODER |= (GPIO_InitStruct->GPIO_Mode << (2 * 2));  // 设置PC2的模式位

    GPIOx->OSPEEDR &= ~(3 << (2 * 2));  // 清除PC2的速度位
    GPIOx->OSPEEDR |= (GPIO_InitStruct->GPIO_Speed << (2 * 2));  // 设置PC2的速度位

    GPIOx->OTYPER &= ~(1 << 2);  // 清除PC2的输出类型位
    GPIOx->OTYPER |= (GPIO_InitStruct->GPIO_OType << 2);  // 设置PC2的输出类型位

    GPIOx->PUPDR &= ~(3 << (2 * 2));  // 清除PC2的上拉/下拉位
    GPIOx->PUPDR |= (GPIO_InitStruct->GPIO_PuPd << (2 * 2));  // 设置PC2的上拉/下拉位
}

int main(void) {
    // 初始化GPIO结构体
    GPIO_InitTypeDef GPIO_PC2_InitStruct;
    GPIO_PC2_InitStruct.GPIO_Pin = GPIO_Pin_2;
    GPIO_PC2_InitStruct.GPIO_Mode = 1;  // 模拟输出模式
    GPIO_PC2_InitStruct.GPIO_Speed = 0; // 模拟低速
    GPIO_PC2_InitStruct.GPIO_OType = 0; // 模拟推挽输出
    GPIO_PC2_InitStruct.GPIO_PuPd = 0;  // 模拟无上拉/下拉

    // 初始化GPIOC的PC2引脚
    GPIO_Init(GPIOC, &GPIO_PC2_InitStruct);

    // 主循环
    while (1) {
        // 模拟主循环
        printf("Main loop\n");
        break;  // 为了简单起见,只执行一次
    }

    return 0;
} 

1理解define GPIOC ((GPIO_TypeDef *) 0)

在C语言中,`(GPIO_TypeDef *) 0`是一个强制类型转换表达式,其中`0`表示一个地址。具体来说:

- `0`:这是一个整数常量,表示内存地址`0`。在计算机系统中,地址`0`通常是一个无效的地址,因为它位于未映射的内存区域。然而,在纯C语言模拟环境中,我们使用`0`来代替实际的内存地址,以避免实际硬件的依赖。

- `(GPIO_TypeDef *)`:这是一个强制类型转换操作符,用于将整数`0`转换为指向`GPIO_TypeDef`类型的指针。这意味着我们假装地址`0`是一个指向`GPIO_TypeDef`结构体的指针。

在实际的STM32微控制器中,每个GPIO端口都有一个基地址,例如GPIOC的基地址可能是`0x40020800`。但在纯C语言模拟环境中,我们不需要实际的内存地址,因此使用`0`来代替。

总结来说,`(GPIO_TypeDef *) 0`中的`0`是一个地址,表示内存地址`0`,通过强制类型转换将其视为指向`GPIO_TypeDef`类型的指针。在纯C语言模拟环境中,这种做法允许我们编写和测试GPIO初始化代码,而不依赖实际硬件。

2 理解#define GPIO_Pin_2 ((uint16_t)0x0004)

这个宏定义的作用是将GPIO_Pin_2定义为一个16位无符号整数,其值为0x0004。具体解释如下:

  • GPIO_Pin_2:这是一个宏名称,代表GPIO端口C的第2号引脚。

  • ((uint16_t)0x0004):这是一个强制类型转换表达式。它将十六进制数0x0004转换为16位无符号整数。

在STM32微控制器中,每个GPIO引脚都有一个对应的位掩码,用于标识该引脚。例如,GPIOC的第2号引脚的位掩码是0x0004,表示该引脚在寄存器中的位置。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值