单芯片解决方案,开启全新体验——W55MH32 高性能以太网单片机
W55MH32是WIZnet重磅推出的高性能以太网单片机,它为用户带来前所未有的集成化体验。这颗芯片将强大的组件集于一身,具体来说,一颗W55MH32内置高性能Arm® Cortex-M3核心,其主频最高可达216MHz;配备1024KB FLASH与96KB SRAM,满足存储与数据处理需求;集成TOE引擎,包含WIZnet全硬件TCP/IP协议栈、内置MAC以及PHY,拥有独立的32KB以太网收发缓存,可供8个独立硬件socket使用。如此配置,真正实现了All-in-One解决方案,为开发者提供极大便利。
在封装规格上,W55MH32 提供了两种选择:QFN68和QFN100。
W55MH32Q采用QFN68封装版本,尺寸为8x8mm,它拥有36个GPIO、3个ADC、12通道DMA、17个定时器、2个I2C、3个串口、2个SPI接口(其中1个带I2S接口复用)、1个CAN以及1个USB2.0。在保持与同系列其他版本一致的核心性能基础上,仅减少了部分GPIO以及SDIO接口,其他参数保持一致,性价比优势显著,尤其适合网关模组等对空间布局要求较高的场景。紧凑的尺寸和精简化外设配置,使其能够在有限空间内实现高效的网络连接与数据交互,成为物联网网关、边缘计算节点等紧凑型设备的理想选择。 同系列还有QFN100封装的W55MH32L版本,该版本拥有更丰富的外设资源,适用于需要多接口扩展的复杂工控场景,软件使用方法一致。更多信息和资料请进入http://www.w5500.com/网站或者私信获取。
此外,本W55MH32支持硬件加密算法单元,WIZnet还推出TOE+SSL应用,涵盖TCP SSL、HTTP SSL以及MQTT SSL等,为网络通信安全再添保障。
为助力开发者快速上手与深入开发,基于W55MH32Q这颗芯片,WIZnet精心打造了配套开发板。开发板集成WIZ-Link芯片,借助一根USB C口数据线,就能轻松实现调试、下载以及串口打印日志等功能。开发板将所有外设全部引出,拓展功能也大幅提升,便于开发者全面评估芯片性能。
若您想获取芯片和开发板的更多详细信息,包括产品特性、技术参数以及价格等,欢迎访问官方网页:http://www.w5500.com/,我们期待与您共同探索W55MH32的无限可能。

第五章 GPIO示例
功夫不负有心人,相信学习至此大家已经掌握了基础内容介绍的知识。我们希望通过前面的章节你已经掌握了W55MH32开发的工具和方法。下面我们将和大家一起来学习W55MH32 的一些基础外设,这些外设实际项目中经常会用到,希望大家认真学习和掌握,以便将来更好、更快的完成实际项目开发。
后面我们将采取一章一实例的方式,介绍 W55MH32 常用外设的使用,通过本篇的学习,我们将带领大家进入W55MH32 的精彩世界。
本章将通过一个经典的跑马灯程序,带大家开启 W55MH32之旅。通过本章的学习,我们将了解到 W55MH32的 IO 口作为输出使用的方法。
本章分为如下 4 个小节:
1 W55MH32 GPIO 简介
2 寄存器描述
3 程序设计
4 下载验证
1 W55MH32 GPIO 简介
每个 GPI/O 端口有两个 32 位配置寄存器(GPIOx_CRL,GPIOx_CRH),两个 32 位数据寄存器(GPIOx_IDR 和 GPIOx_ODR),一个 32 位置位/复位寄存(GPIOx_BSRR),一个 16 位复位寄存器GPIOx_BRR)和一个 32 位锁定寄存器(GPIOx_LCKR)。根据数据手册中列出的每个 I/O 端口的特定硬件特征,GPIO 端口的每个位可以由软件分别配置成多种模式。
-------- 输入浮空
-------- 输入上拉
-------- 输入下拉
-------- 模拟输入
-------- 开漏输出
-------- 推挽式输出
-------- 推挽式复用功能
-------- 开漏复用功能
每个 I/O 端口位可以自由编程,然而必须按照 32 位字访问 I/O 端口寄存器(不允许半字或字节访问)。GPIOx_BSRR 和 GPIOx_BRR 寄存器允许对任何 GPIO 寄存器进行读/更改的独立访问;这样,在读和更改访问之间产生 IRQ 时不会发生危险。
下图给出了一个 I/O 端口位的基本结构。

GPIO 的基本结构图
如上图所示,可以看到右边只有 I/O 引脚,这个 I/O 引脚就是我们可以看到的芯片实物的引脚,其他部分都是 GPIO 的内部结构。
① 保护二极管
保护二极管共有两个,用于保护引脚外部过高或过低的电压输入。当引脚输入电压高于VDD 时,上面的二极管导通,当引脚输入电压低于 VSS 时,下面的二极管导通,从而使输入芯片内部的电压处于比较稳定的值。虽然有二极管的保护,但这样的保护却很有限,大电压大电流的接入很容易烧坏芯片。所以在实际的设计中我们要考虑设计引脚的保护电路。
② 上拉、下拉电阻
它们阻值大概在 30~50K 欧之间,可以通过上、下两个对应的开关控制,这两个开关由寄存器控制。当引脚外部的器件没有干扰引脚的电压时,即没有外部的上、下拉电压,引脚的电平由引脚内部上、下拉决定,开启内部上拉电阻工作,引脚电平为高,开启内部下拉电阻工作,则引脚电平为低。同样,如果内部上、下拉电阻都不开启,这种情况就是我们所说的浮空模式。浮空模式下,引脚的电平是不可确定的。引脚的电平可以由外部的上、下拉电平决定。需要注意的是,W55MH32 的内部上拉是一种“弱上拉”,这样的上拉电流很弱,如果有要求大电流还是得外部上拉。
③ 施密特触发器
对于标准施密特触发器,当输入电压高于正向阈值电压,输出为高;当输入电压低于负向阈值电压,输出为低;当输入在正负向阈值电压之间,输出不改变,也就是说输出由高电准位翻转为低电准位,或是由低电准位翻转为高电准位,对应的阈值电压是不同的。只有当输入电压发生足够的变化时,输出才会变化,因此将这种元件命名为触发器。这种双阈值动作被称为迟滞现象,表明施密特触发器有记忆性。从本质上来说,施密特触发器是一种双稳态多谐振荡器。施密特触发器可作为波形整形电路,能将模拟信号波形整形为数字电路能够处理的方波波形,而且由于施密特触发器具有滞回特性,所以可用于抗干扰,以及在闭回路正回授/负回授配置中用于实现多谐振荡器。下面看看比较器跟施密特触发器的作用的比较,就清楚的知道施密特触发器对外部输入信号具有一定抗干扰能力,如图所示。

比较器的(A)和施密特触发器(B)作用比较
④ P-MOS 管和 N-MOS 管
这个结构控制 GPIO 的开漏输出和推挽输出两种模式。开漏输出:输出端相当于三极管的集电极,要得到高电平状态需要上拉电阻才行。推挽输出:这两只对称的 MOS 管每次只有一只导通,所以导通损耗小、效率高。输出既可以向负载灌电流,也可以从负载拉电流。推拉式输出既能提高电路的负载能力,又能提高开关速度。上面我们对 GPIO 的基本结构图中的关键器件做了介绍,下面分别介绍 GPIO 八种工作模式对应结构图的工作情况。
1、输入浮空
输入浮空模式:上拉/下拉电阻为断开状态,施密特触发器打开,输出被禁止。输入浮空模式下,IO 口的电平完全是由外部电路决定。如果 IO 引脚没有连接其他的设备,那么检测其输入电平是不确定的。该模式可以用于按键检测等情景。

输入浮空模式
2、输入上拉
输入上拉模式:上拉电阻导通,施密特触发器打开,输出被禁止。在需要外部上拉电阻的时候,可以使用内部上拉电阻,这样可以节省一个外部电阻,但是内部上拉电阻的阻值较大,所以只是“弱上拉”,不适合做电流型驱动。

输入上拉模式
3、输入下拉
输入下拉模式:下拉电阻导通,施密特触发器打开,输出被禁止。在需要外部下拉电阻的时候,可以使用内部下拉电阻,这样可以节省一个外部电阻,但是内部下拉电阻的阻值较大,所以不适合做电流型驱动。

输入下拉模式
4、模拟功能
模拟功能:上下拉电阻断开,施密特触发器关闭,双 MOS 管也关闭。其他外设可以通过模拟通道输入输出。该模式下需要用到芯片内部的模拟电路单元单元,用于 ADC、DAC、MCO 这类操作模拟信号的外设。

模拟功能
5、开漏输出
开漏输出模式:W55MH32 的开漏输出模式是数字电路输出的一种,从结果上看它只能输出低电平 Vss 或者高阻态,常用于 IIC 通讯(IIC_SDA)或其它需要进行电平转换的场景。

开漏输出模式
6、推挽输出
推挽输出模式:W55MH32的推挽输出模式,从结果上看它会输出低电平 VSS或者高电平VDD推挽输出跟开漏输出不同的是,推挽输出模式 P-MOS 管和 N-MOS 管都用上。
如果输出数据寄存器①的值为 0,经过“输出控制”取反操作后,输出逻辑 1 到 P-MOS 管的栅极,这时 P-MOS 管就会截止,同时也会输出逻辑 1 到 N-MOS 管的栅极,这时 N-MOS 管就会导通,使得 IO 引脚接到 VSS,即输出低电平。如果输出数据寄存器的值为 1 ,经过“输出控制”取反操作后,输出逻辑 0 到 N-MOS 管的栅极,这时 N-MOS 管就会截止,同时也会输出逻辑 0 到 P-MOS 管的栅极,这时 P-MOS 管就会导通,使得 IO 引脚接到 VDD,即输出高电平。
由上述可知,推挽输出模式下,P-MOS 管和 N-MOS 管同一时间只能有一个管是导通的。当 IO 引脚在做高低电平切换时,两个管子轮流导通,一个负责灌电流,一个负责拉电流,使其负载能力和开关速度都有较大的提高。
另外在推挽输出模式下,施密特触发器也是打开的,我们可以读取 IO 口的电平状态。由于推挽输出模式下输出高电平时,是直接连接VDD,所以驱动能力较强,可以做电流型驱动,驱动电流最大可达 25mA,但是芯片的总电流有限,所以并不建议这样用,最好还是使用芯片外部的电源。

推挽输出模式
7、开漏式复用功能
开漏式复用功能:一个 IO 口可以是通用的 IO 口功能,还可以是其它外设的特殊功能引脚,这就是 IO 口的复用功能,如图所示。一个 IO 口可以是多个外设的功能引脚,我们需要选择其中一个外设的功能引脚。当选择复用功能时,引脚的状态是由对应的外设控制,而不是输出数据寄存器。除了复用功能外,其它的结构分析请参考开漏输出模式。
另外在开漏式复用功能模式下,施密特触发器也是打开的,我们可以通过输入数据寄存器读取 IO 口的电平状态,同时外设也可以读取 IO 口的信息。

开漏式复用功能
8、推挽式复用功能
推挽式复用功能:复用功能介绍请查看开漏式复用功能,结构分析请参考推挽输出模式,这里不再赘述。

推挽式复用功能
2 GPIO 寄存器描述
2.1 端口配置低寄存器(GPIOx_CRL)(x=A..G)

2.2 端口配置高寄存器(GPIOx_CRH)(x=A..G)

2.3 端口输入数据寄存器(GPIOx_IDR)(x=A..G)

2.4 端口输出数据寄存器(GPIOx_ODR)(x=A..G)


2.5 端口位设置/清除寄存器(GPIOx_BSRR)(x=A..G)

2.6 端口位清除寄存器(GPIOx_BRR)(x=A..G)

2.7 端口配置锁定寄存器(GPIOx_LCKR)(x=A..G)
当执行正确的写序列设置了位 16(LCKK)时,该寄存器用来锁定端口位的配置。位[15:0]用于锁定GPIO 端口的配置。在规定的写入操作期间,不能改变 LCKP[15:0]。当对相应的端口位执行了LOCK 序列后,在下次系统复位之前将不能再更改端口位的配置。
每个锁定位锁定控制寄存器(CRL,CRH)中相应的 4 个位。

3 程序设计
3.1 GPIO_IOInput例程
此代码为一个基于W55MH32的嵌入式程序,主要功能是对 GPIO 输入进行测试,同时配置 UART 串口通信用于输出系统时钟信息和按键按下的提示信息。
主函数main()
int main(void)
{
RCC_ClocksTypeDef clocks;
delay_init();
UART_Configuration(115200);
RCC_GetClocksFreq(&clocks);
printf("n");
printf("SYSCLK: %3.1fMhz, HCLK: %3.1fMhz, PCLK1: %3.1fMhz, PCLK2: %3.1fMhz, ADCCLK: %3.1fMhzn",
(float)clocks.SYSCLK_Frequency / 1000000, (float)clocks.HCLK_Frequency / 1000000,
(float)clocks.PCLK1_Frequency / 1000000, (float)clocks.PCLK2_Frequency / 1000000, (float)clocks.ADCCLK_Frequency / 1000000);
printf("GPIO IO Input Tset.n");
GPIO_Configuration();
while (1)
{
}
}
对延时函数进行初始化。
把串口波特率配置为 115200。
获取系统时钟频率并输出。
配置 GPIO。
进入无限循环。
GPIO 配置函数GPIO_Configuration()
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_PIN1_TEST;
GPIO_InitStructure.GPIO_Speed = GPIO_SPEED_TEST;
GPIO_InitStructure.GPIO_Mode = GPIO_MODE_TEST;
GPIO_Init(GPIO_GROUP_TEST, &GPIO_InitStructure);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource1);
NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
EXTI_InitStructure.EXTI_Line = EXTI_Line1;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
}
开启 GPIOA 和 AFIO 的时钟。
对 GPIO 引脚进行初始化。
把 GPIO 引脚配置为外部中断线。
对 NVIC(嵌套向量中断控制器)进行配置。
对外部中断进行配置,触发方式为下降沿触发。
UART 配置函数UART_Configuration()
void UART_Configuration(uint32_t bound)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
USART_InitStructure.USART_BaudRate = bound;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART_TEST, &USART_InitStructure);
USART_Cmd(USART_TEST, ENABLE);
}
开启 USART1 和 GPIOA 的时钟。
对 USART1 的发送和接收引脚进行初始化。
对 USART1 进行初始化,设置波特率、数据位、停止位等参数。
使能 USART1。
外部中断处理函数EXTI1_IRQHandler()
void EXTI1_IRQHandler(void)
{
if (EXTI_GetITStatus(EXTI_Line1) == SET)
{
delay_ms(10);
if (GPIO_ReadOutputDataBit(GPIOA, GPIO_Pin_1) == Bit_SET)
{
printf("The key is pressedn");
}
}
EXTI_ClearITPendingBit(EXTI_Line1);
}
当检测到外部中断触发时,进行消抖处理。
若按键确实被按下,则通过串口输出提示信息。
清除中断标志位。
3.2 GPIO_IOOut例程
初始化部分:delay_init():初始化延时函数。
UART_Configuration(115200):配置串口,波特率为 115200。
RCC_GetClocksFreq(&clocks):获取系统时钟频率信息,并通过串口打印出来。
GPIO_Configuration():配置 GPIOB 的 PB0、PB2、PB3 为推挽输出模式。
主循环部分:
以 200ms 为间隔依次将 PB0、PB2、PB3 置高电平,再依次将它们置低电平,循环执行。
while (1)
{
GPIO_SetBits(GPIO_GROUP_TEST, GPIO_PIN1_TEST);
printf("LED1 ONn");
delay_ms(200);
GPIO_SetBits(GPIO_GROUP_TEST, GPIO_PIN2_TEST);
printf("LED2 ONn");
delay_ms(200);
GPIO_SetBits(GPIO_GROUP_TEST, GPIO_PIN3_TEST);
printf("LED3 ONn");
delay_ms(200);
GPIO_ResetBits(GPIO_GROUP_TEST, GPIO_PIN1_TEST);
printf("LED1 OFFn");
delay_ms(200);
GPIO_ResetBits(GPIO_GROUP_TEST, GPIO_PIN2_TEST);
printf("LED2 OFFn");
delay_ms(200);
GPIO_ResetBits(GPIO_GROUP_TEST, GPIO_PIN3_TEST);
printf("LED3 OFFn");
delay_ms(200);
}
}
4 下载验证
4.1 GPIO_IOInput例程

4.2 GPIO_IOOut例程

审核编辑 黄宇
-
寄存器
+关注
关注
31文章
5589浏览量
129064 -
GPIO
+关注
关注
16文章
1313浏览量
55727
发布评论请先 登录

第五章 GPIO示例
评论