GD32 IO口位操作

实现类似51单片机的IO口位控制,GD32F103/105/407

#ifndef __SYS_H
#define __SYS_H	

															    
	 
//位带操作,实现51类似的GPIO控制功能
//具体实现思想,参考<<CM3权威指南>>第五章(87页~92页).
//IO口操作宏定义
#define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2)) 
#define MEM_ADDR(addr)  *((volatile unsigned long  *)(addr)) 
#define BIT_ADDR(addr, bitnum)   MEM_ADDR(BITBAND(addr, bitnum)) 
//IO口地址映射


/*GD32F407*/
//#define GPIOA_BASE            (AHB1_BUS_BASE + 0x0000)
//#define GPIOB_BASE            (AHB1_BUS_BASE + 0x0400)
//#define GPIOC_BASE            (AHB1_BUS_BASE + 0x0800)
//#define GPIOD_BASE            (AHB1_BUS_BASE + 0x0C00)
//#define GPIOE_BASE            (AHB1_BUS_BASE + 0x1000)
//#define GPIOF_BASE            (AHB1_BUS_BASE + 0x1400)
//#define GPIOG_BASE            (AHB1_BUS_BASE + 0x1800)
//#define GPIOH_BASE            (AHB1_BUS_BASE + 0x1C00)
//#define GPIOI_BASE            (AHB1_BUS_BASE + 0x2000)

//#define GPIOA_ODR_Addr    (GPIOA_BASE+20) //0x40020014 
//#define GPIOB_ODR_Addr    (GPIOB_BASE+20) //0x40020414 
//#define GPIOC_ODR_Addr    (GPIOC_BASE+20) //0x40020814 
//#define GPIOD_ODR_Addr    (GPIOD_BASE+20) //0x40020C14 
//#define GPIOE_ODR_Addr    (GPIOE_BASE+20) //0x40021014 
//#define GPIOF_ODR_Addr    (GPIOF_BASE+20) //0x40021414    
//#define GPIOG_ODR_Addr    (GPIOG_BASE+20) //0x40021814  
//#define GPIOH_ODR_Addr    (GPIOH_BASE+20) //0x40021C14
//#define GPIOI_ODR_Addr    (GPIOI_BASE+20) //0x40022014

//#define GPIOA_IDR_Addr    (GPIOA_BASE+16) //0x40020010 
//#define GPIOB_IDR_Addr    (GPIOB_BASE+16) //0x40020410 
//#define GPIOC_IDR_Addr    (GPIOC_BASE+16) //0x40020810 
//#define GPIOD_IDR_Addr    (GPIOD_BASE+16) //0x40020C10 
//#define GPIOE_IDR_Addr    (GPIOE_BASE+16) //0x40021010 
//#define GPIOF_IDR_Addr    (GPIOF_BASE+16) //0x40021410 
//#define GPIOG_IDR_Addr    (GPIOG_BASE+16) //0x40021810 
//#define GPIOH_IDR_Addr    (GPIOH_BASE+16) //0x40021C10 
//#define GPIOI_IDR_Addr    (GPIOI_BASE+16) //0x40022010 

/*GD32F103/105*/
#define GPIOA_BASE            (APB2_BUS_BASE + 0x0800)
#define GPIOB_BASE            (APB2_BUS_BASE + 0x0C00)
#define GPIOC_BASE            (APB2_BUS_BASE + 0x1000)
#define GPIOD_BASE            (APB2_BUS_BASE + 0x1400)
#define GPIOE_BASE            (APB2_BUS_BASE + 0x1800)
#define GPIOF_BASE            (APB2_BUS_BASE + 0x1C00)
#define GPIOG_BASE            (APB2_BUS_BASE + 0x2000)

#define GPIOA_ODR_Addr    (GPIOA_BASE+12) //0x4001080C 
#define GPIOB_ODR_Addr    (GPIOB_BASE+12) //0x40010C0C 
#define GPIOC_ODR_Addr    (GPIOC_BASE+12) //0x4001100C 
#define GPIOD_ODR_Addr    (GPIOD_BASE+12) //0x4001140C 
#define GPIOE_ODR_Addr    (GPIOE_BASE+12) //0x4001180C 
#define GPIOF_ODR_Addr    (GPIOF_BASE+12) //0x40011A0C    
#define GPIOG_ODR_Addr    (GPIOG_BASE+12) //0x40011E0C    

#define GPIOA_IDR_Addr    (GPIOA_BASE+8) //0x40010808 
#define GPIOB_IDR_Addr    (GPIOB_BASE+8) //0x40010C08 
#define GPIOC_IDR_Addr    (GPIOC_BASE+8) //0x40011008 
#define GPIOD_IDR_Addr    (GPIOD_BASE+8) //0x40011408 
#define GPIOE_IDR_Addr    (GPIOE_BASE+8) //0x40011808 
#define GPIOF_IDR_Addr    (GPIOF_BASE+8) //0x40011A08 
#define GPIOG_IDR_Addr    (GPIOG_BASE+8) //0x40011E08 
 
//IO口操作,只对单一的IO口!
//确保n的值小于16!
#define PAout(n)   BIT_ADDR(GPIOA_ODR_Addr,n)  //输出 
#define PAin(n)    BIT_ADDR(GPIOA_IDR_Addr,n)  //输入 

#define PBout(n)   BIT_ADDR(GPIOB_ODR_Addr,n)  //输出 
#define PBin(n)    BIT_ADDR(GPIOB_IDR_Addr,n)  //输入 

#define PCout(n)   BIT_ADDR(GPIOC_ODR_Addr,n)  //输出 
#define PCin(n)    BIT_ADDR(GPIOC_IDR_Addr,n)  //输入 

#define PDout(n)   BIT_ADDR(GPIOD_ODR_Addr,n)  //输出 
#define PDin(n)    BIT_ADDR(GPIOD_IDR_Addr,n)  //输入 

#define PEout(n)   BIT_ADDR(GPIOE_ODR_Addr,n)  //输出 
#define PEin(n)    BIT_ADDR(GPIOE_IDR_Addr,n)  //输入

#define PFout(n)   BIT_ADDR(GPIOF_ODR_Addr,n)  //输出 
#define PFin(n)    BIT_ADDR(GPIOF_IDR_Addr,n)  //输入

#define PGout(n)   BIT_ADDR(GPIOG_ODR_Addr,n)  //输出 
#define PGin(n)    BIT_ADDR(GPIOG_IDR_Addr,n)  //输入

#endif

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
GD32中读取IO的电压,可以通过ADC模块或者GPIO模块实现。 1. 通过ADC模块读取IO电压 首先需要配置ADC模块,包括通道、时钟、采样时间等。然后将需要读取电压的IO连接到ADC通道上,启动ADC转换,并使用`ADC_GetConversionValue()`函数获取ADC的转换结果。最后,根据ADC模块的参考电压和分辨率,将转换结果转换为对应的电压值。 以下是示例代码: ``` #include "gd32f30x.h" ADC_InitPara ADC_InitStructure; float ADC_ConvertedValue; void ADC_Configuration(void) { /* Enable ADC0 clock */ RCC_APB2PeriphClock_Enable(RCC_APB2PERIPH_ADC0, ENABLE); /* ADC Calibration and Enable */ ADC_Calibration(ADC0); ADC_Enable(ADC0, ENABLE); /* ADC0 regular channel11 configuration */ ADC_InitStructure.ADC_Mode_Scan = DISABLE; ADC_InitStructure.ADC_Mode_Continuous = DISABLE; ADC_InitStructure.ADC_Trig_External = ADC_EXTERNAL_TRIGGER_DISABLE; ADC_InitStructure.ADC_Data_Align = ADC_DATAALIGN_RIGHT; ADC_InitStructure.ADC_Channel_Number = 11; ADC_InitStructure.ADC_Sample_Time = ADC_SAMPLETIME_239POINT5; ADC_Init(ADC0, &ADC_InitStructure); /* Enable ADC0 */ ADC_Enable(ADC0, ENABLE); } float Read_IO_Voltage(void) { float Voltage = 0; /* Start ADC0 Software Conversion */ ADC_SoftwareStartConv_Enable(ADC0, ENABLE); /* Wait for ADC conversion */ while(ADC_GetFlagStatus(ADC0, ADC_FLAG_EOC) == RESET); /* Get ADC conversion value */ ADC_ConvertedValue = ADC_GetConversionValue(ADC0); /* Calculate voltage value */ Voltage = (float)ADC_ConvertedValue / 4096.0 * 3.3; return Voltage; } int main(void) { /* ADC configuration */ ADC_Configuration(); while (1) { /* Read IO voltage */ float voltage = Read_IO_Voltage(); } } ``` 2. 通过GPIO模块读取IO电压 可以通过读取IO的电平状态,判断IO的电压。如果IO为高电平,则电压为3.3V;如果IO为低电平,则电压为0V。 以下是示例代码: ``` #include "gd32f30x.h" #define IO_PORT GPIOA #define IO_PIN GPIO_PIN_0 int main(void) { /* Configure IO port as input */ gpio_init(IO_PORT, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, IO_PIN); while (1) { /* Read IO voltage */ if (gpio_input_bit_get(IO_PORT, IO_PIN) == SET) { /* IO voltage is 3.3V */ } else { /* IO voltage is 0V */ } } } ``` 请注意,以上代码仅供参考,具体实现可能需要根据不同的硬件连接和要求进行调整。同时也需要注意ADC的采样精度和速度等参数的合理设置。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值