一、前言

本篇开始对STM32的GPIO在实际开发设计中的使用配置和技巧进行探讨,可以先去回顾下之前介绍的GPIO的相关理论基础知识包括基本结构,工作模式和寄存器原理。

了解过STM32的GPIO相关的理论知识,这样在应用GPIO开发过程中,能更好的理解GPIO的特点,应用起来会更加的得心应手。

后续将从以下图1中所示的几个方面对GPIO应用设计中的步骤展开介绍。本篇先介绍GPIO的基本API函数定义,配置初始化的流程,以及使用技巧;针对将GPIO的引脚用于外部中断的功能将作为单独的一篇进行详细的讨论介绍。​

图1 GPIO应用设计


二、API函数

STM32有多种类型的库,本节所介绍的STM32的GPIO函数接口是STM32标准库的函数接口,接口总共分为4种类型,如图2所示。​

图2 GPIO库函数接口分类

1、关键参数

在详细介绍各个API函数接口功能之前,我们需要对函数接口中使用到的关键的几个参数进行分析。

(1)、GPIO_TypeDef* GPIOx

这个参数是用于指定需要具体的GPIO端口号定义,参数的范围为GPIOA~GPIOK。

(2)、GPIO_InitTypeDef* GPIO_InitStruct

这个参数是GPIO端口需要初始化的功能参数的结构体指针,下面我们看看这个结构体的定义。

1 typedef struct
2 {
3 uint32_t GPIO_Pin; //GPIO端口的引脚
4 GPIOMode_TypeDef GPIO_Mode; //GPIO的端口模式
5 GPIOSpeed_TypeDef GPIO_Speed; //GPIO的输出速度频率
6 GPIOOType_TypeDef GPIO_OType; //GPIO输出时的类型
7 GPIOPuPd_TypeDef GPIO_PuPd; //GPIO上下拉电阻设置
8 }GPIO_InitTypeDef;

  (a)、GPIO端口的引脚:可选范围为GPIO_Pin_0~GPIO_Pin_15,也可以选所有引脚GPIO_Pin_All。

  (b)、GPIO的端口模式:用于设置GPIO的端口模式,可选的端口模式如下。

1 typedef enum
2 {
3 GPIO_Mode_IN = 0x00, //普通IO口输入
4 GPIO_Mode_OUT = 0x01, //普通IO口输出
5 GPIO_Mode_AF = 0x02, //管脚复用功能
6 GPIO_Mode_AN = 0x03 //模拟输入,用于ADC功能
7 }GPIOMode_TypeDef;

(c)、GPIO的输出速度频率:当GPIO引脚用于普通功能输出或复用功能输出时,GPIO的输出速度频率,可选的输出速率如下。

1 typedef enum
2 {
3 GPIO_Low_Speed = 0x00, //GPIO_Speed_2MHz
4 GPIO_Medium_Speed = 0x01, //GPIO_Speed_25MHz
5 GPIO_Fast_Speed = 0x02, //GPIO_Speed_50MHz
6 GPIO_High_Speed = 0x03 //GPIO_Speed_100MHz
7 }GPIOSpeed_TypeDef;

速度高的IO耗电大、噪声也大,速度低的IO耗电小、噪声也小。使用合适的速度可以降低功耗和噪声。高频的驱动电路,噪声也高,当不需要高的输出频率时,请选用低频驱动电路,这样非常有利于提高系统的EMI性能,也可以降低功耗。当然如果要输出较高频率的信号,但却选用了较低频率的速度,很可能会得到失真的输出信号。关键是GPIO的引脚速度跟应用匹配。

(d)、GPIO输出时的类型:当GPIO引脚用于普通功能输出或复用功能输出时,可选择设置的GPIO的输出结构类型有如下。

1 typedef enum
2 {
3 GPIO_OType_PP = 0x00, //推挽结构
4 GPIO_OType_OD = 0x01 //开漏结构
5 }GPIOOType_TypeDef;

推挽输出时,可以输出高或者低电平;开漏输出时,如果要输出高电平,则需要在芯片内部配置上拉电阻(弱上拉)或者在芯片IO外部连接上拉电阻。

(e)、GPIO上下拉电阻设置:可以为GPIO端口的引脚选择设置是否具备带上拉或下拉电阻功能。

1 typedef enum
2 {
3 GPIO_PuPd_NOPULL = 0x00, //无上拉或者下拉
4 GPIO_PuPd_UP = 0x01, //带上拉电阻
5 GPIO_PuPd_DOWN = 0x02 //带下拉电阻
6 }GPIOPuPd_TypeDef;

STM32芯片GPIO的上拉电阻和下拉电阻最小值,典型值和最大值如下:

(3)、uint16_t GPIO_PinSource和uint8_t GPIO_AF

这两个参数都是GPIO端口引脚需要配置成复用功能引脚用到的参数。

GPIO_PinSource:指需配置的复用功能引脚源,可选范围GPIO_PinSource0~GPIO_PinSource15。

GPIO_AF:指该引脚具体需要配置的功能,具体配置功能要看实际应用需求,例如需要配置成SPI1功能的引脚,那么就选GPIO_AF_SPI1。

2、函数接口

下面就对具体的函数接口进行逐个的介绍。由于使用的是STM32的标准库,GPIO 相关的函数及配置定义和可以调用的接口放置在官方提供的标准库文件 stm32fxx_gpio.c和头文件 stm32fxx_gpio.h 文件中。

(1)、void GPIO_DeInit(GPIO_TypeDef* GPIOx);

作用:将GPIO端口设置成初始的默认状态,相当于复位GPIO端口,默认的状态为输入浮空的状态。

举例:GPIO_DeInit(GPIOA),将GPIOA端口所有引脚复位到默认状态。

(2)、void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);

作用:将GPIO端口引脚进行功能状态初始化。

举例:将GPIOA的pin1引脚设为普通输出功能,IO驱动速率可达50MHz,推挽模式,带上拉电阻。

1 gpio_InitStruct.GPIO_Pin = GPIO_Pin_1;
2 gpio_InitStruct. GPIO_Mode = GPIO_Mode_OUT;
3 gpio_InitStruct.GPIO_Speed = GPIO_Fast_Speed;
4 gpio_InitStruct. GPIO_OType = GPIO_OType_PP;
5 gpio_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
6 GPIO_Init(GPIOA, &gpio_InitStruct);

(3)、void GPIO_StructInit(GPIO_InitTypeDef* GPIO_InitStruct);

作用:获取GPIO端口的所有引脚的一个默认状态,可应用于某个GPIO端口上。该函数内部默认的引脚默认状态如下。

1 GPIO_InitStruct->GPIO_Pin  = GPIO_Pin_All;
2 GPIO_InitStruct->GPIO_Mode = GPIO_Mode_IN;
3 GPIO_InitStruct->GPIO_Speed = GPIO_Speed_2MHz;
4 GPIO_InitStruct->GPIO_OType = GPIO_OType_PP;
5 GPIO_InitStruct->GPIO_PuPd = GPIO_PuPd_NOPULL;

举例:使用gpio_InitStruct快速获取到了引脚的默认状态值。

1 GPIO_StructInit(&gpio_InitStruct);

(4)、void GPIO_PinLockConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);

作用:将指定GPIO端口引脚当前的配置进行锁定,锁定后该引脚配置不能被修改,只有等下次MCU复位锁定才能释放。

举例:锁定GPIOA的管脚pin1配置不被修改。

1 GPIO_PinLockConfig(GPIOA, GPIO_Pin_1);

(5)、uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);

作用:为当GPIO的相应管脚配置成输入时,读取该GPIO端口下的相应引脚输入电平值。

举例:读取GPIOA的pin1引脚输入电平值。

1 status = GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_1);

(6)、uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx);

作用:为当GPIO配置成输入时,读取该GPIO端口下的所有引脚输入电平值。

举例:读取GPIOA端口所有引脚的输入电平值。

1 status = GPIO_ReadInputData(GPIOA);

(7)、uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);

作用:为当GPIO的相应管脚配置成输出时,读取该GPIO端口下的相应引脚输出电平值。

举例:读取GPIOA的pin1引脚输出电平值。

1 status = GPIO_ReadOutputDataBit(GPIOA, GPIO_Pin_1);

(8)、uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx);

作用:为当GPIO配置成输出时,读取该GPIO端口下的所有引脚输出电平值。

举例:读取GPIOA端口所有引脚的输出电平值。

1 status = GPIO_ReadOutputData(GPIOA);

(9)、void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);

作用:置位相应GPIO端口引脚的电平值。

举例:将GPIOA的pin1管脚电平置为1。

1 GPIO_SetBits(GPIOA, GPIO_Pin_1);

也可以用于多个引脚电平的置位。

1 GPIO_SetBits(GPIOA, GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3);

(10)、void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);

作用:清零相应GPIO端口引脚的电平值。

举例:将GPIOA的pin1管脚电平置为0。

1 GPIO_ResetBits(GPIOA, GPIO_Pin_1);

也可以用于多个引脚电平的清零。

1 GPIO_ResetBits(GPIOA, GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3);

(11)、void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal);

作用:将GPIO端口的指定管脚电平置1或置0。

举例:将GPIOA的pin1管脚电平置为1。

1 GPIO_WriteBit(GPIOA, GPIO_Pin_1, 1);

也可以用于多个引脚电平操作。

1 GPIO_WriteBit(GPIOA, GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3, 1);

(12)、void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal);

作用:将GPIO端口的所有管脚电平置1或置0。

举例:将GPIOA端口的所有管脚电平置为1。

1 GPIO_Write(GPIOA, 1);

(13)、void GPIO_ToggleBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);

作用:翻转指定GPIO引脚的输出电平,即0变为1,1变为0。

举例:翻转GPIOA的pin1管脚电平值。

1 GPIO_ToggleBits(GPIOA , GPIO_Pin_1);

(14)、void GPIO_PinAFConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_PinSource, uint8_t GPIO_AF);

作用:将GPIO的指定管脚配置成复用功能管脚。

举例:将GPIOA的pin9管脚配置成串口USART1的功能管脚。

1 GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1);

三、配置流程

配置流程主要在实际的驱动配置中对GPIO进行初始化的操作,根据实际项目应用开发中的芯片GPIO引脚的定义,进行合理的配置。图3所示为GPIO的基本配置操作流程。​

图3 GPIO配置流程

(1)、使能对应GPIO的时钟

在配置GPIO的开始,首先需要将对应的GPIO模块的时钟打开,这样才能为GPIO工作提供动力源,因此只有先将GPIO的时钟打开才能使GPIO正常的工作。

关于STM32芯片内部整体的时钟系统,可以回顾之前明解STM32时钟系统的文章介绍。STM32的GPIO模块是挂载在芯片内部AHB1总线(AHB:高级高性能总线)上的外设,因此就需要打开GPIO在AHB1总线上对应的时钟。AHB1总线上的外设时钟开关在STM32提供的标准库函数中通过函数 RCC_AHB1PeriphClockCmd ()来实现的。例如调用:

1 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);

这样就将GPIOA的时钟打开,也可以同时打开多个GPIO端口的时钟:

1 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA|RCC_AHB1Periph_GPIOB, ENABLE);

(2)、引脚功能配置

接下来对GPIO引脚的配置是需要根据实际的项目应用要求,根据各个芯片管脚的定义来对引脚的功能进行合理的配置,主要是根据引脚是使用成普通IO输出还是输入,复用功能还是模拟管脚来调用GPIO_Init()函数进行配置。举例说明:

用于普通IO输出时:

1 GPIO_WriteBit(GPIOA, GPIO_Pin_1, 1);//向引脚输出0或1电平,在GPIO_Init前调用
2 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;//设置使用引脚
3 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通IO输出
4 GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//根据实际应用配置输出结构类型
5 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//根据实际应用配置输出速度
6 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//根据实际应用配置上拉或下拉电阻
7 GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化PA1引脚

需要注意的是,初始化输出电平时,需要先调用写引脚电平接口,再做初始化操作,这是因为GPIO_WriteBit是将输出的值写入寄存器输出置位/复位寄存器BSRR,BSRR寄存器复位值是0,GPIO_Init相当于将GPIO引脚初始化完打开输出开关。如果需要输出的是高电平,GPIO_WriteBit在前,GPIO_Init在后相当于在没打开开关之前就将1在BSRR中放置好,GPIO_Init将开关一打开就可以输出高电平;如果GPIO_Init在前,GPIO_WriteBit在后,GPIO_Init完会将BSRR中的0先输出,过了一个函数指令周期后调用GPIO_WriteBit才输出高电平,因此若驱动时序对函数指令周期敏感的外围器件时,可能带来驱动时序问题!

用于普通IO输入时:

1 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;//设置使用引脚
2 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;//普通IO输入
3 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//根据实际应用配置输出速度
4 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//根据实际应用配置上拉或下拉电阻
5 GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化PA1引脚

用于复用功能时:

在管脚应用于复用功能时,需要调用GPIO_PinAFConfig()接口来将管脚配置成具体的外设管脚。

1 GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1); //PA9 复用为 USART1
2 GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_USART1); //PA10复用为USART1
3 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10; //设置使用引脚
4 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能
5 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //根据实际应用配置输出速度
6 GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //根据实际应用配置输出结构类型
7 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //根据实际应用配置上拉或下拉电阻
8 GPIO_Init(GPIOA,&GPIO_InitStructure); //初始化PA9和PA10引脚

用于模拟管脚时:

1 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;//PA5 通道 5
2 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;//模拟输入
3 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;//不带上下拉
4 GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化PA5引脚

当STM32需要进行 AD( 模数 ) 转换采样时,需要把引脚设置为模拟输入模式,模拟输入模式下,不需要连接上拉和下拉电阻,因为GPIO用于模拟功能时,引脚的上、下拉电阻是不起作用的。这个时候即使在配置了上拉或下拉电阻,也不会影响到模拟信号的输入。

(3)、对GPIO引脚进行操作

在初始化完GPIO引脚的具体配置后,就可以对GPIO引脚进行具体的操作使用了。

用于普通IO输出时:

  可以调用相关GPIO相关写操作接口对引脚进行输出0或者1的操作:GPIO_SetBits、GPIO_ResetBits、GPIO_WriteBit、GPIO_ToggleBits。

  也可以调用相关GPIO读接口对输出类型的GPIO进行读取引脚电平的操作GPIO_ReadOutputDataBit。

用于普通IO输入时:

可以调用相关GPIO读接口对输入类型的GPIO进行读取引脚电平的操作:GPIO_ReadInputDataBit。

用于复用功能时:

需要根据实际使用时的具体外设配置,接着初始化相应的片上外设后,调用具体的外设信号读或者写接口进行信号的读写操作。

用于模拟管脚时:

由于模拟管脚功能是用芯片上的ADC对芯片外部的模拟信号进行采样,因此还需要初始化完ADC外设后,调用ADC外设采样的接口进行信号读取。


四、使用技巧

在日常程序开发调试的过程中,可以简单有效的利用GPIO驱动输出高低电平来进行辅助的测试及验证工作。下面介绍几个较为常用的使用场景,如果有其它可以利用GPIO的方法和技巧,也请大家积极留言,我们一起探讨。

(1)、在boot程序阶段使用IO翻转输出信号的频率可以和APP程序阶段使用IO翻转输出信号的频率相异,通过使用示波器测量波形,用于区分程序是运行在boot程序阶段还是APP程序阶段,即不同程序阶段。

(2)、在使用定时器中断的时候,为了确保定时器时基设置的正确性,测试是可以定时器中断中增加IO口信号翻转逻辑,通过使用示波器测量翻转的频率来测试验证定时器中断的周期。

1 void TIM1_IRQHandler(void) //定时器 1 中断服务函数
2 {
3 if(TIM_GetITStatus(TIM1,TIM_IT_Update)==SET) //溢出中断
4 {
5 GPIO_ToggleBits(); //IO口信号翻转操作逻辑,用于验证定时器中断频率
6 }
7 TIM_ClearITPendingBit(TIM1,TIM_IT_Update); //清除中断标志位
8 }

(3)、在不同的程序段中使用多个IO,输出高电平,通过示波器测量IO口之间输出高电平的间隔,可以确定两个程序段之间运行的准确时间。

(4)、在板卡上没有LED进行闪烁指示的情况或没有使用外部看门狗芯片的情况下,为了确认程序是否仍然在正常运行,需要留出一个IO口,用于翻转高低电平输出,后续就可以用示波器测量该信号的有无来判断程序是否死机。

(5)、在没有调试打印程序信息的串口时,查找死机问题的时候,放置不同的IO输出高电平的在不同的程序段,这样类似的进行插桩驱动测试,通过示波器测量信号,可以大体的定位在程序运行的哪一块发生了死机的问题。

(6)、在测试验证阶段,可以将某个IO引脚配置成输入模式,利用外部给的激励信号,在程序中判断读到的信号电平的高低状态,去作为逻辑判断条件进行一些代码段的验证测试。


五、总结

本篇主要主要是对STM32的GPIO在日常基本应用开发中的具体的操作配置和使用方法进行了说明,包括API功能函数的定义,驱动初始化的配置流程以及一些利用GPIO操作的相关技巧,后续将对GPIO使用成外部中断时进行详细的介绍。


更多技术内容和书籍资料获取,入群技术交流敬请关注“明解嵌入式”

明解STM32—GPIO应用设计篇之API函数及配置使用技巧的更多相关文章

  1. 明解STM32—GPIO理论基础知识篇之基本结构

    ​ 一.前言 万物皆有源头,大家学习单片机的源头操作就是通过GPIO口点灯,GPIO作为STM32最基础的外设,也是大家最先接触的外设.当然,看似基础的GPIO,不仅仅是简单的设置好IO口,让灯亮起就 ...

  2. 队列链式存储 - 设计与实现 - API函数

    队列相关基础内容参我的博文:队列顺序存储 - 设计与实现 - API函数 队列也是一种特殊的线性表:可以用线性表链式存储来模拟队列的链式存储. 主要代码: // linkqueue.h // 队列链式 ...

  3. 队列顺序存储 - 设计与实现 - API函数

    队列是一种特殊的线性表 队列仅在线性表的两端进行操作 队头(Front):取出数据元素的一端 队尾(Rear):插入数据元素的一端 队列不允许在中间部位进行操作! queue常用操作 销毁队列 清空队 ...

  4. 线性表的顺序存储设计和实现 - API函数实现

    基本概念 设计与实现 插入元素算法 判断线性表是否合法 判断插入位置是否合法 把最后一个元素到插入位置的元素后移一个位置 将新元素插入 线性表长度加1 获取元素操作 判断线性表是否合法 判断位置是否合 ...

  5. STM32 GPIO 配置之ODR, BSRR, BRR 详解

    STM32 GPIO 配置之ODR, BSRR, BRR 详解 用stm32 的配置GPIO 来控制LED 显示状态,可用ODR,BSRR,BRR 直接来控制引脚输出状态. ODR寄存器可读可写:既能 ...

  6. 《手把手教你》系列基础篇(九十六)-java+ selenium自动化测试-框架之设计篇-跨浏览器(详解教程)

    1.简介 从这一篇开始介绍和分享Java+Selenium+POM的简单自动化测试框架设计.第一个设计点,就是支持跨浏览器测试. 宏哥自己认为的支持跨浏览器测试就是:同一个测试用例,支持用不同浏览器去 ...

  7. 《手把手教你》系列基础篇(九十七)-java+ selenium自动化测试-框架设计篇-Selenium方法的二次封装和页面基类(详解教程)

    1.简介 上一篇宏哥介绍了如何设计支持不同浏览器测试,宏哥的方法就是通过来切换配置文件设置的浏览器名称的值,来确定启动什么浏览器进行脚本测试.宏哥将这个叫做浏览器引擎类.这个类负责获取浏览器类型和启动 ...

  8. (转)Android Binder设计与实现 – 设计篇

    原文地址(貌似已打不开):Android Binder设计与实现 – 设计篇 ------------------------------------------------------------- ...

  9. 明解C语言

    本文为阅读书籍<明解C语言-中级篇>所积累的知识点及编译书本代码时遇到的问题.部分对应代码在\Code_2018\BK_明解C语言目录下.每个代码内都含有程序功能.思路.疑惑点等内容,如有 ...

  10. C语言学习书籍推荐《明解C语言》下载

    柴田望洋 (作者), 管杰 (译者), 罗勇 (译者) <明解C语言>是日本的C语言经典教材,自出版以来不断重印.修订,被誉为“C语言圣经”.作者在日本IT界家喻户晓,出版过一系列极富影响 ...

随机推荐

  1. ctype.h系列的字符函数

    C有一系列专门处理字符的函数,ctype.h头文件包含了这些函数的原型.这些函数接受一个字符作为参数,如果该字符属于某特殊的类别,就返回一个非零值(真):否则返回0(假).这个头文件在判断特定字符类型 ...

  2. PHP判断0和空的方法

    可以兼容,传参数,或者不参数与0的判断   if ( isset($data['other_id']) && (!empty($data['other_id']) || is_nume ...

  3. 解决定时任务crontab运行待top的脚本

    脚本编写如: #!/bin/bash /usr/bin/top -n -1 -u mysql > /root/script/log/$(date +"%Y%m%d_%H%M%S&quo ...

  4. ESP32 优化 IRAM 内存方法整理 ---ESP32

    有以下三种方便的方法来优化 IRAM 内存: 启用 menuconfig -> Compiler option -> Optimization Level -> Optimize f ...

  5. 一文快速回顾 Java 操作数据库的方式-JDBC

    前言 数据库的重要性不言而喻,不管是什么系统,什么应用软件,也不管它们是 Windows 上的应用程序,还是 Web 应用程序,存储(持久化)和查询(检索)数据都是核心的功能. 大家学习数据库时,比如 ...

  6. Javaweb问题解决--在.java文件里面写sql语句模糊查询不成功的原因

    问题描述 在上学期,我就遇到了这个问题(别骂别骂),然后当时卡住之后,Mybatis闯入了我的视线,然后直接换用了较为方便的Mybatis框架结构,这个问题也就被搁置了,今天重新提起,优势慢慢地查阅了 ...

  7. Spring--事务案例的实现

    案例实现(主要是想用Spring实现一下MyBatis的相关内容) JDBCConfig.java MyBatisConfig.java SpringConfig.java accountDao.ja ...

  8. 在 Maui 中自绘组件1:绘制

    在 Maui 中自绘组件 系列文章已完结,共六篇,此为第一篇. 在 Maui 中自绘组件1:绘制 在 Maui 中自绘组件2:可绑定属性 在 Maui 中自绘组件3:事件与命令 在 Maui 中自绘组 ...

  9. 干货 | BitSail Connector 开发详解系列一:Source

    更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群 BitSail 是字节跳动自研的数据集成产品,支持多种异构数据源间的数据同步,并提供离线.实时.全量.增量场景下全 ...

  10. 90 条简单实用的 Python 编程技巧,建议收藏

    编码原则 建议 1:理解 Pythonic 概念 -- 详见 Python 中的<Python 之禅> 建议 2:编写 Pythonic 代码 避免不规范代码,比如只用大小写区分变量.使用 ...