N32是Cortex-M4内核,看用户手册发现N32G457是有位带别名区的
手册中有这样两段话:
对于N32的库中有关GPIO有GPIO_Module结构体,其中POD和PID为控制十六个管脚的输出与输入寄存器,使用位带别名区可以将单个管脚1bit的控制位扩展到32位,实现类似PA0 = 1;代码操作IO输出。
/**
* [url=home.php?mod=space&uid=2666770]@Brief[/url] General Purpose I/O
*/
typedef struct
{
__IO uint32_t PL_CFG;
__IO uint32_t PH_CFG;
__IO uint32_t PID;
__IO uint32_t POD;
__IO uint32_t PBSC;
__IO uint32_t PBC;
__IO uint32_t PLOCK_CFG;
uint32_t RESERVED0;
__IO uint32_t DS_CFG;
__IO uint32_t SR_CFG;
} GPIO_Module;
实现手册内的公式,最终代码如下
/**
* @author: Pomin
* @date: 2022-10-29 20:12:56
* @github: https://github.com/POMIN-163
* @lastedit: 2022-12-22 16:42:50
* @description: 别名区
**/
#ifndef _ALIAS_REG_H
#define _ALIAS_REG_H
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
#include <stdio.h>
#include "n32g45x.h"
// 位带操作
// 公式:
// 最终地址 = 别名区基址 + ((A ‐ 外设基址)*8 + n)*4 = 别名区基址 + (A ‐ 外设基址)*32 + n*4
// 解释:
// 原地址相对外设基址偏移值膨胀 32 倍得到外设在别名区的基址
// 原 1 bit变为 32bit, + n*4 找到第n个管脚 (*4)是表示四个字节即 32bit
#define MCU_PERIPH_BASE PERIPH_BASE // 外设基址
#define MCU_PERIPH_BB_BASE PERIPH_BB_BASE // 别名区基址
#define MEM_ADDR(addr) (*((volatile unsigned long *)(addr))) // 一个数字转为地址并取值
#define DIFF_ADDR(addr) ((uint32_t)(addr) - (uint32_t)MCU_PERIPH_BASE) // 地址相对外设基址偏移
#define BIT_BAND(addr) ((MCU_PERIPH_BB_BASE + (DIFF_ADDR(addr) << 5))) // 位带膨胀后的基址
#define BIT_REG(reg, bit) ((uint32_t *)BIT_BAND(&(reg)))[bit] // 算出原来的1bit 膨胀后的地址
// #define BIT_REG(reg, bit) MEM_ADDR((BIT_BAND(&(reg)) + (((uint32_t)(bit)) << 2)))
#define PA ((uint32_t *)BIT_BAND(&(GPIOA->POD))) // 此写法可以写成 PA[10] = 1;
#define PB ((uint32_t *)BIT_BAND(&(GPIOB->POD)))
#define PC ((uint32_t *)BIT_BAND(&(GPIOC->POD)))
#define PD ((uint32_t *)BIT_BAND(&(GPIOD->POD)))
#define PE ((uint32_t *)BIT_BAND(&(GPIOE->POD)))
#define PF ((uint32_t *)BIT_BAND(&(GPIOF->POD)))
#define PG ((uint32_t *)BIT_BAND(&(GPIOG->POD)))
#define PAout(n) BIT_REG(GPIOA->POD, n) // 此写法可以写成 PAout(1) = 1;
#define PBout(n) BIT_REG(GPIOB->POD, n)
#define PCout(n) BIT_REG(GPIOC->POD, n)
#define PDout(n) BIT_REG(GPIOD->POD, n)
#define PEout(n) BIT_REG(GPIOE->POD, n)
#define PFout(n) BIT_REG(GPIOF->POD, n)
#define PGout(n) BIT_REG(GPIOG->POD, n)
#define PAin(n) BIT_REG(GPIOA->PID, n)
#define PBin(n) BIT_REG(GPIOB->PID, n)
#define PCin(n) BIT_REG(GPIOC->PID, n)
#define PDin(n) BIT_REG(GPIOD->PID, n)
#define PEin(n) BIT_REG(GPIOE->PID, n)
#define PFin(n) BIT_REG(GPIOF->PID, n)
#define PGin(n) BIT_REG(GPIOG->PID, n)
#ifdef __cplusplus
}
#endif
#endif // _ALIAS_REG_H
用位带别名区控制闪灯
while (1) {
delay_ms(500);
PA[8] ^= 1;
PB[4] ^= 1;
PB[5] ^= 1;
}
功能正常
更多回帖