尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

沁恒微 RISC-V 蓝牙 CH5xx GPIO使用说明

沁恒微 RISC-V 蓝牙 CH5xx GPIO使用说明 CH5xx 芯片的 GPIO 使用说明以及注意事项 ...... 矜辰所致 ...... 增加晶振引脚的说明 2025/12/5 ...... 增加中断标志寄存器的读取说明 2026/3/2 ...... 增加GPIO上电默认状态说明 2026/9/30前言官方并没有单独为 GPIO 写一个示例主要是太简单了 但依然有些小伙伴一个简单的 GPIO 中断使用起来都出现问题。另外对于新学习一款芯片需要知道有没有哪些 “ 特殊 ” 的 GPIO 引脚这种往往是使用者最关心也最容易踩坑的地方。所以本文我们内容就是说明一下 CH5xx 芯片 GPIO 如何使用中断以及芯片在 GPIO 口使用注意事项。我是矜辰所致全网同名尽量用心写好每一系列文章不浮夸不将就认真对待学知识的我们矜辰所致金石为开目录前言一、 基础介绍1.1 模式设置1.2 电平输出读取1.3 重映射1.4 中断设置1.5 复位默认状态二、 GPIO 中断示例2.1 中断使用注意点2.2 关于中断标志寄存器的读取三、GPIO 引脚说明3.1 特殊引脚3.2 晶振引脚结语一、 基础介绍本文以 CH585 为例介绍其他芯片使用方式类似。GPIO 基础功能实在是太简单了随便打开一个工程都会有串口初始化随便一跳转 GPIO 操作函数都出来了。 比如GPIOA_SetBits(GPIO_Pin_14);跳转到定义CH58x_gpio.h文件里面里面包括使用者需要了解的 GPIO 操作的所有函数都有注释。1.1 模式设置模式设置voidGPIOB_ModeCfg(uint32_tpin,GPIOModeTypeDef mode);...typedefenum{GPIO_ModeIN_Floating,//浮空输入GPIO_ModeIN_PU,//上拉输入GPIO_ModeIN_PD,//下拉输入GPIO_ModeOut_PP_5mA,//推挽输出最大5mAGPIO_ModeOut_PP_20mA,//推挽输出最大20mA}GPIOModeTypeDef;示例GPIOA_ModeCfg(GPIO_Pin_14,GPIO_ModeOut_PP_5mA);//推挽输出1.2 电平输出读取电平设置针对输出而言:#defineGPIOA_ResetBits(pin)(R32_PA_CLR|pin)//输出低电平#defineGPIOA_SetBits(pin)(R32_PA_OUT|pin)//输出高电平#defineGPIOA_InverseBits(pin)(R32_PA_OUT^pin)//翻转IO电平读取针对输入而言#defineGPIOA_ReadPort()(R32_PA_PIN)//读取PA口所有IO状态#defineGPIOA_ReadPortPin(pin)(R32_PA_PIN(pin))//读取PA口指定IO状态示例GPIOA_SetBits(GPIO_Pin_14);GPIOA_ReadPortPin(GPIO_Pin_14);1.3 重映射重映射使用GPIOPinRemap官方代码直接有对应说明重映射部分为了兼容系列不同型号的芯片有部分没有写比如 I2C UART3 具体查看自己使用芯片的使用手册**********************************************************************fn GPIOPinRemap**brief 外设功能引脚映射**param s-是否使能映射*param perph-RB_RF_ANT_SW_EN-RF antennaswitchcontrol output on PA4/PA5/PA12/PA13/PA14/PA15*RB_PIN_U0_INV-RXD0/RXD0_/TXD0/TXD0_ invert input/output*RB_PIN_INTX-INTX:INT24/INT25 PB8/PB9-INT24_/INT25_ PB22/PB23*RB_PIN_MODEM-MODEM:PA6/PA7-PB12/PB13*RB_PIN_I2C-I2C:PB14/PB15-PB14/PB15*RB_PIN_PWMX-PWMX:PA12/PA13/PB7/PB6/PB4-PA6/PA7/PB3/PB2/PB1*RB_PIN_SPI0-SPI0:PA12/PA13/PA14/PA15-PB12/PB13/PB14/PB15*RB_PIN_UART3-UART3:PA4/PA5-PA4/PA5*RB_PIN_UART2-UART2:PB22/PB23-PA6/PA7*RB_PIN_UART1-UART1:PA8/PA9-PB12/PB13*RB_PIN_UART0-UART0:PB4/PB7-PA15/PA14*RB_PIN_TMR3-TMR2:PB22-PB22*RB_PIN_TMR2-TMR2:PA11-PB11*RB_PIN_TMR1-TMR1:PA10-PB10*RB_PIN_TMR0-TMR0:PA9-PB23**returnnone*/voidGPIOPinRemap(FunctionalState s,uint16_tperph)示例//串口GPIOA_SetBits(GPIO_Pin_14);GPIOPinRemap(ENABLE,RB_PIN_UART0);GPIOA_ModeCfg(GPIO_Pin_15,GPIO_ModeIN_PU);GPIOA_ModeCfg(GPIO_Pin_14,GPIO_ModeOut_PP_5mA);UART0_DefInit();//I2CGPIOPinRemap(ENABLE,RB_PIN_I2C);GPIOB_ModeCfg(GPIO_Pin_21|GPIO_Pin_20,GPIO_ModeIN_PU);1.4 中断设置CH585 支持中断的引脚有 PA0-PA15PB0-PB15PB22PB23所以PB17不支持GPIO中断PB22 和PB23 与 PB8 和 PB9 属于映射关系使用 PB22 中断功能需要调用映射函数。中断配置voidGPIOA_ITModeCfg(uint32_tpin,GPIOITModeTpDef mode);typedefenum{GPIO_ITMode_LowLevel,//低电平触发GPIO_ITMode_HighLevel,//高电平触发GPIO_ITMode_FallEdge,//下降沿触发GPIO_ITMode_RiseEdge,//上升沿触发}GPIOITModeTpDef;中断标志状态读取#defineGPIOA_ReadITFlagPort()(R16_PA_INT_IF)//读取PA口所有IO中断标志状态#defineGPIOA_ReadITFlagBit(pin)(R16_PA_INT_IF(pin))//读取PA口指定IO中断标志状态清楚中断标志位#defineGPIOA_ClearITFlagBit(pin)(R16_PA_INT_IFpin)中断示例/* 配置唤醒源为 GPIO - PA5 */GPIOA_ModeCfg(GPIO_Pin_5,GPIO_ModeIN_PU);GPIOA_ITModeCfg(GPIO_Pin_5,GPIO_ITMode_FallEdge);// 下降沿唤醒PFIC_EnableIRQ(GPIO_A_IRQn);__INTERRUPT __HIGH_CODEvoidGPIOA_IRQHandler(void){GPIOA_ClearITFlagBit(GPIO_Pin_5);}1.5 复位默认状态芯片引脚的复位默认状态都是 浮空输入。通过手册 GPIO 相关寄存器列表可知二、 GPIO 中断示例在文章上面我们已经介绍过中断设置函数以及使用示例虽然官方没有单独的 GPIO 中断示例但是在 PM 例程里面用到了 GPIO 中断这里我们自己写一个简单的程序大家可以先看一下按照我们一般的理解下面的程序应该是没问题的如果上面的程序大家能发现问题基本上就掌握了 CH5xx 芯片 GPIO 的用法了。2.1 中断使用注意点上面的程序只能运行一次就 跑飞 了有几个问题。中断必须在前面加__INTERRUPT。告诉编译器软件自动压栈要不然程序进去一次就跑飞。但是在前面的代码即便我们把__INTERRUPT加上还是会有问题会发现 while 里面的if(test_flag)永远为假 但是我们中断中PRINT(!!!!!!\r\n);是执行到了的说明在中断中test_flag 1是有的这就是上面程序的第二个问题。在中断中改变的变量必须在前面加volatile修饰 。修改完毕我们测试才能正常但是对于我们使用 CH5xx 芯片来说我们除了在中断前面加__INTERRUPT还会加上__HIGH_CODE把代码搬运到 RAM 中运行提高响应速度。不加__HIGH_CODE编译后的 .map 文件中中断响应函数存放地址为 Flash 区域.text.GPIOA_IRQHandler0x0000000000000cea0x2c./src/Main.o0x0000000000000ceaGPIOA_IRQHandler加了__HIGH_CODE编译后的 .map 文件中中断响应函数存放地址为 RAM 区域*(.highcode)*(.highcode.*).highcode.GPIOA_IRQHandler0x00000000200001f80x30./src/Main.o0x00000000200001f8GPIOA_IRQHandler对于这个简单的代码我测试了加不加都可以但是强烈建议大家加上只要是中断__INTERRUPT __HIGH_CODE都加上。最后这个 GPIO 中断测试代码如下#includeCH58x_common.hvoidDebugInit(void){GPIOA_SetBits(GPIO_Pin_14);GPIOPinRemap(ENABLE,RB_PIN_UART0);GPIOA_ModeCfg(GPIO_Pin_14,GPIO_ModeOut_PP_5mA);UART0_DefInit();}volatileuint8_ttest_flag0;intmain(){HSECFG_Capacitance(HSECap_18p);SetSysClock(SYSCLK_FREQ);DebugInit();GPIOA_ModeCfg(GPIO_Pin_5,GPIO_ModeIN_PU);//上拉输入GPIOA_ITModeCfg(GPIO_Pin_5,GPIO_ITMode_FallEdge);//下降沿双向触发PFIC_EnableIRQ(GPIO_A_IRQn);//中断使能PRINT(GPIO TEST begin...\r\n);while(1){if(test_flag){// PFIC_DisableIRQ(GPIO_A_IRQn);PRINT(IRQ ON..\r\n);test_flag0;// PFIC_EnableIRQ( GPIO_A_IRQn );}}}__INTERRUPT __HIGH_CODEvoidGPIOA_IRQHandler(void){if(R16_PA_INT_IFGPIO_Pin_5)// check enable gpio it flag{DelayMs(10);//简单测试使用if(!GPIOA_ReadPortPin(GPIO_Pin_5)){R16_PA_INT_IFGPIO_Pin_5;//clear it flagPRINT(!!!!!!\r\n);test_flag1;}}}2.2 关于中断标志寄存器的读取GPIOA 和 GPIOB 分别有一个中断标志寄存器官方给好了宏定义可以直接读取但是实际上直接读取这两个寄存器是不准确无意义的如下图有时候因为中断问题想把寄存器的值打印出来差错不能这样直接读取。需要与上中断使能寄存器如下方式方可读到正常值uint16_tttR16_PB_INT_IFR16_PB_INT_EN;uint16_ttt2R16_PA_INT_IFR16_PA_INT_EN;PRINT(PB_INT_IF 0x%04X\n,tt);PRINT(PA_INT_IF 0x%04X\n,tt2);在中断中也可以验证一下具体效果如下图 :三、GPIO 引脚说明3.1 特殊引脚PA12引脚在上电/上电复位时会产生一个15ms左右的高电平。这是芯片原厂产测用的信号无法规避。谨慎使用此 IO 作为输出。PA9引脚CH585/4M 型号其他型号串口免按键引脚查看下一点的推荐博文在上电时会产生一个40~50ms的高电平。这是由于启用了串口免按键下载原厂 boot 中配置了 UART 功能TX 脚空闲状态上拉了。可以在烧录前配置关闭串口免按键下载。PB22为默认的 BOOT 引脚CH585/CH592 部分/CH579低电平触发几个特殊的型号的默认 BOOT 引脚CH592DPB15低电平触发CH591DPB7低电平触发CH572RPA4低电平CH572D/572Q/570D/570QPA1高电平且PA0是低电平关于下载引脚大家请参考博文www.cnblogs.com/risc5-ble/p/18868018PB22只有上电时会检测低电平进boot进APP后就是普通引脚PB22一直接地会导致上电后过60秒BOOT 超时才能运行用户代码。PB23为复位引脚若做输入输出使用时在使用 ISP 下载时需关闭 RST 的使能否则可能导致下次无法正常下载或代码一直复位。GPIO 中断标志寄存器只有16位也就是说只有 PA0 ~ PA15、PB0~ PB15 是可以被用作GPIO中断的。PB22和PB23与PB8和PB9属于映射关系使用 PB22 中断功能需要调用映射函数。在 IO 比较少的封装中比如说 CH592FMCU上只有PB22\PB23而没有PB8\PB9此时PB22\PB23两脚本身就是支持 GPIO 中断的无需额外配置GPIO 的灌入电流和输出电流最大值均为100mA。上面提到的PA9和PB23的配置在 ISP 下载工具中对应的位置如下3.2 晶振引脚对于高频晶振CH5xx 系列芯片必须要接而且引脚也不能用于其他用途这个型号对应大家自行查看手册32MHz 用于芯片的基本外设整个射频 PLL 的参考时钟 ISP 下载需要高精度。对于低频晶振CH572/ CH570 是没有外接低频晶振引脚的。对于 CH585/CH584/CH592 来说他们的引脚都是PA11和PA10有些芯片也没有这个自己查看手册或者说有些芯片有这个引脚但是自己不接外接晶振也可以作为普通的 GPIO 引脚。但是要注意如果需要使用蓝牙主机功能是一定需要外接 32.768Khz 晶振的。蓝牙主机功能对蓝牙数据传输收发包的时间要求较高。如果后期有一些特殊的芯片需要说明再来更新。结语本文主要介绍了一下 蓝牙芯片 CH5xx 系列 GPIO 使用给出了一个中断使用的示例以及芯片一些特殊 GPIO 口的说明希望对大家使用芯片的时候有帮助。好了本文就到这里。谢谢大家
返回列表