打印
[方案相关]

华大M0 系列单片机的端口电路结构简析

[复制链接]
872|16
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
端口结构介绍
  无论使用MCU实现什么功能,只要是有意义的功能必然会涉及到IO口的操作。IO口的操作也是MCU的入门操作,按国际惯例一般上手MCU的第一个程序点灯程序就是通过IO口的输出来实现的。
华大M0+系列单片机的端口电路有两种结构,这两种电路结构大体相同,只是存在三个微小的差别。


HC32F(L)x3x、HC32F(L)x7x和HC32F(L)x9x系列芯片的端口电路是一种结构,为了便于说明我们称这种结构为结构一,


框图如下:


使用特权

评论回复
沙发
键盘手没手|  楼主 | 2022-4-30 16:33 | 只看该作者
 HC32F003、HC32F005和HC32L110芯片是一种结构,我们称这种结构为结构二,框图如下:

使用特权

评论回复
板凳
键盘手没手|  楼主 | 2022-4-30 16:33 | 只看该作者

使用特权

评论回复
地板
键盘手没手|  楼主 | 2022-4-30 16:34 | 只看该作者
由上面两个构图我们可以很清楚地知道两种结构的区别如下:
  1.结构一的PxOUT(寄存器中出现的x=A,B,C,D,E,F代表芯片含有的端口组,后面的亦是同样的意思)可以通过操作位寄存器(PxBSET、PxBCLR、PxBSETCLR)来直接控制某一位的输出,而不会影响这组寄存器中的其余的位,结构二没有相关的位操作。

使用特权

评论回复
5
键盘手没手|  楼主 | 2022-4-30 17:14 | 只看该作者
 2.结构一输出/输入数据寄存器(PxOUT/PxIN)支持AHB/FAST IO总线访问(通过寄存器 GPIO_CTRL2.ahb_sel 位控制),其他寄存器支持AHB总线访问。结构二端口输入值/输出值寄存器(PxIN/PxOUT)只支持 AHB 总线读写。

使用特权

评论回复
6
键盘手没手|  楼主 | 2022-4-30 17:15 | 只看该作者
对于这两种不同的总线,系统时钟(HCLK)对这两种总线的处理周期并不相同。下面两幅图为对于两种总线端口翻转的最快时序:

使用特权

评论回复
7
键盘手没手|  楼主 | 2022-4-30 17:16 | 只看该作者
 对于 AHB 总线,每两个 HCLK 周期,IO 翻转一次,而对于 FAST IO 总线,每个 HCLK周期,IO 翻转一次。

使用特权

评论回复
8
键盘手没手|  楼主 | 2022-4-30 17:17 | 只看该作者
3.结构二对应芯片的RST引脚可以复用成带有内部上拉电阻的数字输入引脚,结构一对应的芯片RST引脚不可以复用为IO引脚。
  重点来了,说完两种结构的差**进入正题,说下两种结构和共性。
  每个端口都可以配置成数字或模拟端口,并且可以实现内部上拉(pull up)/下拉(pull down)的输入,高阻输入(floating input),推挽输出(CMOS output),开漏输出(open drain output),两档驱动能力输出。
  数字端口被配置成模拟端口后,数字功能被隔离,不能输出数字“1”和“0”,CPU 读取端口输入值寄存器的结果为“0”。
  每个数字端口被配置为输入时,都可以提供外部中断,中断类型可以配置成高电平触发、低电平触发、上升沿触发、下降沿触发 4 种,查询 Px_STAT[n]的中断标志位即可知道相应的中断触发端口。另外,每个数字端口的中断都可以把芯片从睡眠模式/深度睡眠模式唤醒到工作模式。
  芯片复位后端口为高阻输入(floating input),目的是防止芯片被异常复位时,对外部器件产生异常动作。
  当端口配置为数字端口的时候可以通过设置Px_SEL寄存器接受各功能模块(如 SPI,UART,I2C,Timer 等)的输入输出信号,此内容放到相应外设模块内容来讲解。
  端口相关配置介绍
  端口相关配置如下:
  数字端口(PxADS对应位为0);
  模拟端口(PxADS对应位为1);
  端口引脚为输入(PxDIR对应位为1);
  端口引脚为输出(PxDIR对应位为0);
  输入电平状态(PxIN 对应引脚获得高电平对应位为1,获得低电平对应位为0);
  输出电平选择(PxOUT 对应位为1相应引脚输出高电平,为0相应引脚输出低电平);
  内部上拉(PxPU对应位为1);
  内部下拉(PxPD对应位为1);
  高阻(PxPU对应位为0且PxPD对应位为0);
  推挽输出(PxOD对应位为0);
  开漏输出(PxOD对应位为1);
  低驱动能力输出(PxDR对应位为1);
  高驱动能力输出(PxDR对应位为0);
  端口高电平中断使能(PxHIE对应位为1);
  端口低电平中断使能(PxLIE对应位为1);
  端口上升沿中断使能(PxRIE对应位为1);
  端口下降沿中断使能(PxFIE对应位为1);
  对于结构一的芯片特有寄存器
  端口置位(PxBSET对应位为1置位,为0保持);
  端口清零(PxBCLR对应位为1清零,为0保持);
  端口置位清零(PxBSETCLR (PxBSET对应位为1置位,为0保持;PxBCLR对应位为1清零,为0保持))。PxBSET 和 PxBCLR 相同位同时置 1 时,PxBCLR 具有高优先级。即该端口被清零。
  端口配置操作流程
  端口复用配置为模拟端口操作流程
  a)设置寄存器 PxADS[n]为 1
  端口复用配置为数字通用端口操作流程
  a) 设置寄存器 PxADS[n]为 0
  b) 设置寄存器 Px_SEL 为 0
  c) 设置寄存器 PxDIR[n]为 1:端口方向为输入,CPU 可以读取端口的状态 PxIN[n]。
  d) 设置寄存器 PxDIR[n]为 0:端口方向为输出
  e) 设置寄存器 PxOUT[n]为 1:端口输出高电平
  f) 设置寄存器 PxOUT[n]为 0:端口输出低电平
  端口上拉使能配置操作流程
  a)设置寄存器 PxPU[n]为 1
  端口下拉使能配置操作流程
  a) 设置寄存器 PxPU[n]为 0
  b) 设置寄存器 PxPD[n]为 1
  注:当 PxPU[n],PxPD[n]同时置 1 时,PxPU[n]优先级高,PxPD[n]无效。
  端口增强驱动配置操作流程
  a)设置寄存器 PxDR[n]为 0
  端口开漏输出配置操作流程
  a)设置寄存器 PxOD[n]为 1
  配置代码
  无上下拉输入配置
  stc_gpio_cfg_t stcGpioCfg;
  Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio, TRUE); //打开GPIO外设时钟
  stcGpioCfg.enDir = GpioDirIn; //端口方向配置-》输入
  stcGpioCfg.enDrv = GpioDrvL; //驱动能力配置-》高驱动能力
  stcGpioCfg.enPu = GpioPuDisable; //端口上下拉配置-》无
  stcGpioCfg.enPd = GpioPdDisable;
  stcGpioCfg.enOD = GpioOdDisable; //开漏输出配置-》开漏输出关闭
  stcGpioCfg.enCtrlMode = GpioAHB; //总线控制模式配置-》AHB
  Gpio_Init(STK_USER_PORT, STK_USER_PIN, &stcGpioCfg); // GPIO IO USER KEY初始化
  推挽输出配置
  stc_gpio_cfg_t stcGpioCfg;
  Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio, TRUE); //打开GPIO外设时钟
  stcGpioCfg.enDir = GpioDirOut; //端口方向配置-》输出
  stcGpioCfg.enDrv = GpioDrvL; //驱动能力配置-》高驱动能力
  stcGpioCfg.enPu = GpioPuDisable; //端口上下拉配置-》无
  stcGpioCfg.enPd = GpioPdDisable;
  stcGpioCfg.enOD = GpioOdDisable; //开漏输出配置-》开漏输出关闭
  stcGpioCfg.enCtrlMode = GpioAHB; //总线控制模式配置-》AHB
  Gpio_Init(STK_LED_PORT, STK_LED_PIN, &stcGpioCfg); // GPIO IO LED端口初始化
  Gpio_ClrIO(STK_LED_PORT, STK_LED_PIN); // LED关闭
  常用的端口操作库函数
  单端口操作
  单个IO口输出低电平
  原型 en_result_t Gpio_ClrIO(en_gpio_port_t enPort, en_gpio_pin_t enPin)
  举例 Gpio_ClrIO(GpioPortA ,GpioPin1 ); //PA01端口输出低电平
  单个IO口输出高电平
  原型 en_result_t Gpio_SetIO(en_gpio_port_t enPort, en_gpio_pin_t enPin)
  举例 Gpio_SetIO(GpioPortA ,GpioPin1 ); //PA01端口输出高电平
  获得IO口输入值
  原型 boolean_t Gpio_GetInputIO(en_gpio_port_t enPort, en_gpio_pin_t enPin)
  举例 u8PA1Stat = Gpio_GetInputIO(GpioPortA ,GpioPin1); //u8PA1Stat 为PA1端口输入电平状态
  获得IO口输出值
  原型 boolean_t Gpio_ReadOutputIO(en_gpio_port_t enPort, en_gpio_pin_t enPin)
  举例 u8PA1Stat = Gpio_ReadOutputIO(GpioPortA ,GpioPin1); //u8PA1Stat 为PA1端口输出电平状态
  多端口操作
  同时让一组端口中的多个引脚输出低电平
  原型 en_result_t Gpio_ClrPort(en_gpio_port_t enPort, uint16_t u16ValMsk)
  举例 Gpio_ClrPort(GpioPortA , 0x000F); //PA0~PA3输出低电平,其余保持
  同时让一组端口中的多个引脚输出高电平
  原型 en_result_t Gpio_SetPort(en_gpio_port_t enPort, uint16_t u16ValMsk)
  举例 Gpio_SetPort(GpioPortA , 0x000F); //PA0~PA3输出高电平,其余保持
  获取一组IO口的输入数据
  原型 uint16_t Gpio_GetInputData(en_gpio_port_t enPort)
  举例 u16PAInputData = Gpio_GetInputData(GpioPortA ); //u16PAInputData的值为PA组输入数据
  同时让一组端口输出多个高低电平
  原型 en_result_t Gpio_SetClrPort(en_gpio_port_t enPort, uint32_t u32ValMsk)
  举例 Gpio_SetClrPort(GpioPortA , 0x00f0000f); //PA4 ~ PA7输出高电平PA0 ~ PA3输出低电平
  端口结构介绍
  无论使用MCU实现什么功能,只要是有意义的功能必然会涉及到IO口的操作。IO口的操作也是MCU的入门操作,按国际惯例一般上手MCU的第一个程序点灯程序就是通过IO口的输出来实现的。

使用特权

评论回复
9
键盘手没手|  楼主 | 2022-4-30 17:18 | 只看该作者
华大M0+系列单片机的端口电路有两种结构,这两种电路结构大体相同,只是存在三个微小的差别。HC32F(L)x3x、HC32F(L)x7x和HC32F(L)x9x系列芯片的端口电路是一种结构,为了便于说明我们称这种结构为结构一,框图如下:

使用特权

评论回复
10
键盘手没手|  楼主 | 2022-4-30 17:21 | 只看该作者
HC32F003、HC32F005和HC32L110芯片是一种结构,我们称这种结构为结构二,框图如下:

使用特权

评论回复
11
键盘手没手|  楼主 | 2022-4-30 17:22 | 只看该作者
由上面两个构图我们可以很清楚地知道两种结构的区别如下:
  1.结构一的PxOUT(寄存器中出现的x=A,B,C,D,E,F代表芯片含有的端口组,后面的亦是同样的意思)可以通过操作位寄存器(PxBSET、PxBCLR、PxBSETCLR)来直接控制某一位的输出,而不会影响这组寄存器中的其余的位,结构二没有相关的位操作。

使用特权

评论回复
12
键盘手没手|  楼主 | 2022-4-30 17:22 | 只看该作者
2.结构一输出/输入数据寄存器(PxOUT/PxIN)支持AHB/FAST IO总线访问(通过寄存器 GPIO_CTRL2.ahb_sel 位控制),其他寄存器支持AHB总线访问。结构二端口输入值/输出值寄存器(PxIN/PxOUT)只支持 AHB 总线读写。对于这两种不同的总线,系统时钟(HCLK)对这两种总线的处理周期并不相同。下面两幅图为对于两种总线端口翻转的最快时序:

使用特权

评论回复
13
键盘手没手|  楼主 | 2022-4-30 17:23 | 只看该作者
对于 AHB 总线,每两个 HCLK 周期,IO 翻转一次,而对于 FAST IO 总线,每个 HCLK周期,IO 翻转一次。
  3.结构二对应芯片的RST引脚可以复用成带有内部上拉电阻的数字输入引脚,结构一对应的芯片RST引脚不可以复用为IO引脚。
  重点来了,说完两种结构的差**进入正题,说下两种结构和共性。
  每个端口都可以配置成数字或模拟端口,并且可以实现内部上拉(pull up)/下拉(pull down)的输入,高阻输入(floating input),推挽输出(CMOS output),开漏输出(open drain output),两档驱动能力输出。
  数字端口被配置成模拟端口后,数字功能被隔离,不能输出数字“1”和“0”,CPU 读取端口输入值寄存器的结果为“0”。
  每个数字端口被配置为输入时,都可以提供外部中断,中断类型可以配置成高电平触发、低电平触发、上升沿触发、下降沿触发 4 种,查询 Px_STAT[n]的中断标志位即可知道相应的中断触发端口。另外,每个数字端口的中断都可以把芯片从睡眠模式/深度睡眠模式唤醒到工作模式。
  芯片复位后端口为高阻输入(floating input),目的是防止芯片被异常复位时,对外部器件产生异常动作。

使用特权

评论回复
14
键盘手没手|  楼主 | 2022-4-30 17:24 | 只看该作者
当端口配置为数字端口的时候可以通过设置Px_SEL寄存器接受各功能模块(如 SPI,UART,I2C,Timer 等)的输入输出信号,此内容放到相应外设模块内容来讲解。
  端口相关配置介绍
  端口相关配置如下:
  数字端口(PxADS对应位为0);
  模拟端口(PxADS对应位为1);
  端口引脚为输入(PxDIR对应位为1);
  端口引脚为输出(PxDIR对应位为0);
  输入电平状态(PxIN 对应引脚获得高电平对应位为1,获得低电平对应位为0);
  输出电平选择(PxOUT 对应位为1相应引脚输出高电平,为0相应引脚输出低电平);
  内部上拉(PxPU对应位为1);
  内部下拉(PxPD对应位为1);
  高阻(PxPU对应位为0且PxPD对应位为0);
  推挽输出(PxOD对应位为0);
  开漏输出(PxOD对应位为1);
  低驱动能力输出(PxDR对应位为1);
  高驱动能力输出(PxDR对应位为0);
  端口高电平中断使能(PxHIE对应位为1);
  端口低电平中断使能(PxLIE对应位为1);
  端口上升沿中断使能(PxRIE对应位为1);
  端口下降沿中断使能(PxFIE对应位为1);
  对于结构一的芯片特有寄存器
  端口置位(PxBSET对应位为1置位,为0保持);
  端口清零(PxBCLR对应位为1清零,为0保持);
  端口置位清零(PxBSETCLR (PxBSET对应位为1置位,为0保持;PxBCLR对应位为1清零,为0保持))。PxBSET 和 PxBCLR 相同位同时置 1 时,PxBCLR 具有高优先级。即该端口被清零。

使用特权

评论回复
15
键盘手没手|  楼主 | 2022-4-30 17:25 | 只看该作者
端口配置操作流程
  端口复用配置为模拟端口操作流程
  a)设置寄存器 PxADS[n]为 1
  端口复用配置为数字通用端口操作流程
  a) 设置寄存器 PxADS[n]为 0
  b) 设置寄存器 Px_SEL 为 0
  c) 设置寄存器 PxDIR[n]为 1:端口方向为输入,CPU 可以读取端口的状态 PxIN[n]。
  d) 设置寄存器 PxDIR[n]为 0:端口方向为输出
  e) 设置寄存器 PxOUT[n]为 1:端口输出高电平
  f) 设置寄存器 PxOUT[n]为 0:端口输出低电平
  端口上拉使能配置操作流程
  a)设置寄存器 PxPU[n]为 1
  端口下拉使能配置操作流程
  a) 设置寄存器 PxPU[n]为 0
  b) 设置寄存器 PxPD[n]为 1
  注:当 PxPU[n],PxPD[n]同时置 1 时,PxPU[n]优先级高,PxPD[n]无效。
  端口增强驱动配置操作流程
  a)设置寄存器 PxDR[n]为 0
  端口开漏输出配置操作流程
  a)设置寄存器 PxOD[n]为 1

使用特权

评论回复
16
键盘手没手|  楼主 | 2022-4-30 17:39 | 只看该作者
配置代码
  无上下拉输入配置
  stc_gpio_cfg_t stcGpioCfg;
  Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio, TRUE); //打开GPIO外设时钟
  stcGpioCfg.enDir = GpioDirIn; //端口方向配置-》输入
  stcGpioCfg.enDrv = GpioDrvL; //驱动能力配置-》高驱动能力
  stcGpioCfg.enPu = GpioPuDisable; //端口上下拉配置-》无
  stcGpioCfg.enPd = GpioPdDisable;
  stcGpioCfg.enOD = GpioOdDisable; //开漏输出配置-》开漏输出关闭
  stcGpioCfg.enCtrlMode = GpioAHB; //总线控制模式配置-》AHB
  Gpio_Init(STK_USER_PORT, STK_USER_PIN, &stcGpioCfg); // GPIO IO USER KEY初始化

使用特权

评论回复
17
键盘手没手|  楼主 | 2022-4-30 17:40 | 只看该作者
推挽输出配置
  stc_gpio_cfg_t stcGpioCfg;
  Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio, TRUE); //打开GPIO外设时钟
  stcGpioCfg.enDir = GpioDirOut; //端口方向配置-》输出
  stcGpioCfg.enDrv = GpioDrvL; //驱动能力配置-》高驱动能力
  stcGpioCfg.enPu = GpioPuDisable; //端口上下拉配置-》无
  stcGpioCfg.enPd = GpioPdDisable;
  stcGpioCfg.enOD = GpioOdDisable; //开漏输出配置-》开漏输出关闭
  stcGpioCfg.enCtrlMode = GpioAHB; //总线控制模式配置-》AHB
  Gpio_Init(STK_LED_PORT, STK_LED_PIN, &stcGpioCfg); // GPIO IO LED端口初始化
  Gpio_ClrIO(STK_LED_PORT, STK_LED_PIN); // LED关闭
  常用的端口操作库函数
  单端口操作
  单个IO口输出低电平
  原型 en_result_t Gpio_ClrIO(en_gpio_port_t enPort, en_gpio_pin_t enPin)
  举例 Gpio_ClrIO(GpioPortA ,GpioPin1 ); //PA01端口输出低电平
  单个IO口输出高电平
  原型 en_result_t Gpio_SetIO(en_gpio_port_t enPort, en_gpio_pin_t enPin)
  举例 Gpio_SetIO(GpioPortA ,GpioPin1 ); //PA01端口输出高电平
  获得IO口输入值
  原型 boolean_t Gpio_GetInputIO(en_gpio_port_t enPort, en_gpio_pin_t enPin)
  举例 u8PA1Stat = Gpio_GetInputIO(GpioPortA ,GpioPin1); //u8PA1Stat 为PA1端口输入电平状态
  获得IO口输出值
  原型 boolean_t Gpio_ReadOutputIO(en_gpio_port_t enPort, en_gpio_pin_t enPin)
  举例 u8PA1Stat = Gpio_ReadOutputIO(GpioPortA ,GpioPin1); //u8PA1Stat 为PA1端口输出电平状态
  多端口操作
  同时让一组端口中的多个引脚输出低电平
  原型 en_result_t Gpio_ClrPort(en_gpio_port_t enPort, uint16_t u16ValMsk)
  举例 Gpio_ClrPort(GpioPortA , 0x000F); //PA0~PA3输出低电平,其余保持
  同时让一组端口中的多个引脚输出高电平
  原型 en_result_t Gpio_SetPort(en_gpio_port_t enPort, uint16_t u16ValMsk)
  举例 Gpio_SetPort(GpioPortA , 0x000F); //PA0~PA3输出高电平,其余保持
  获取一组IO口的输入数据
  原型 uint16_t Gpio_GetInputData(en_gpio_port_t enPort)
  举例 u16PAInputData = Gpio_GetInputData(GpioPortA ); //u16PAInputData的值为PA组输入数据
  同时让一组端口输出多个高低电平
  原型 en_result_t Gpio_SetClrPort(en_gpio_port_t enPort, uint32_t u32ValMsk)
  举例 Gpio_SetClrPort(GpioPortA , 0x00f0000f); //PA4 ~ PA7输出高电平PA0 ~ PA3输出低电平

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

104

主题

1180

帖子

0

粉丝