历史上的今天
返回首页

历史上的今天

今天是:2024年08月26日(星期一)

正在发生

2018年08月26日 | STM32 学习三 GPIO操作

2018-08-26 来源:eefocus

一、基础知识


GPIO寄存器

  • 32位配置寄存器:GPIOx_CRL

  • 32位配置寄存器:GPIOx_CRH

  • 32位数据寄存器:GPIOx_IDR

  • 32位数据寄存器:GPIOx_ODR

  • 32位置位/复位寄存器:GPIOx_BSRR

  • 16位复位寄存器:GPIOx_BRR

  • 32位锁定寄存器:GPIOx_LCKR

工作模式:

  • 输入浮空

  • 输入上拉

  • 输入下拉

  • 模拟输入

  • 开漏输出

  • 推挽式输出

  • 推挽式复用功能

  • 开漏复用功能

每个I/O端口位可以自由编程,而I/O端口寄存器必须按32位字被访问,不允许半字或字节访问。

GPIOx_BSRR和GPIOx_BRR寄存器允许对任何GPIO寄存器的读/更改的独立访问,这样,在读和更改访问之间产生IRQ时不会发生危险。

每个I/O端口位的基本结构:


端口位配置表:


输出模式位:


端口配置低寄存器CRL:


端口配置高寄存器CRH:


端口输入数据寄存器IDR:


端口输出数据寄存器:ODR


锁定寄存器:GPIOx_LCKR

锁定寄存器位置

端口位设置寄存器:GPIOx_BSRR
端口位复位寄存器:GPIOx_BRR

二、编程测试

在GPIOA.0 .1引脚输出高电平:

#include "stm32f10x_map.h"

 

int main()

{

//GPIOA->CRL   控制0-7引脚  工作模式

//GPIOA->CRH 控制8-15引脚 工作模式

//1.设置GPIOA引脚工作模式:

//GPIO共16个引脚,让

//GPIOA.0 GPIOA.1 

//用推挽式输出、速度50Mhz

GPIOA->CRL=0x33;

 

//2.在相应的引脚输出一个电平

GPIOA->ODR=0x00;   //清零

GPIOA->ODR=0x3;   //11

   return(1);

}


程序执行结果:



通过第8引脚输入,控制第0引脚输出


#include "stm32f10x_map.h"

 

int main()

{

     //配置 PA.0 推挽输出 50M

     // PA.8 输入

GPIOA->CRL = 0x03; //CNF0=00   MODE0=11

GPIOA->CRH = 0x04; //CNF0=01 MODE0=00 //模拟CNF0=00输入时,引脚变化不会引起IDR变化,浮空输入CNF0=01

   // PA.0=PA.8

   while(1){

if((GPIOA->IDR & 0x0100)==0x0100) //如果第8位为1

GPIOA->ODR = 0x01;  

else

GPIOA->ODR = 0x00;

    }

   return(1);

}

程序仿真结果:


点击8脚,发现0脚跟着改变。

通过高8位控制低8位引脚:方法1

#include "stm32f10x_map.h"

 

int main()

{

   //配置 PA.0-7 推挽输出 50M

   // PA.8-15 输入

GPIOA->CRL = 0x33333333; //CNF0=00   MODE0=11

GPIOA->CRH = 0x44444444; //CNF0=01 MODE0=00 //模拟CNF0=00输入时,引脚变化不会引起IDR变化,浮空输入CNF0=01

   // PA.0=PA.8...

   while(1){

if((GPIOA->IDR & 0x0100)==0x0100)  GPIOA->ODR = GPIOA->ODR | 0x01; else GPIOA->ODR = GPIOA->ODR & (~0x01);

if((GPIOA->IDR & 0x0200)==0x0200)  GPIOA->ODR = GPIOA->ODR | 0x02; else GPIOA->ODR = GPIOA->ODR & (~0x02);

if((GPIOA->IDR & 0x0400)==0x0400)  GPIOA->ODR = GPIOA->ODR | 0x04; else GPIOA->ODR = GPIOA->ODR & (~0x04);

if((GPIOA->IDR & 0x0800)==0x0800)  GPIOA->ODR = GPIOA->ODR | 0x08; else GPIOA->ODR = GPIOA->ODR & (~0x08);

if((GPIOA->IDR & 0x1000)==0x1000)  GPIOA->ODR = GPIOA->ODR | 0x10; else GPIOA->ODR = GPIOA->ODR & (~0x10);

if((GPIOA->IDR & 0x2000)==0x2000)  GPIOA->ODR = GPIOA->ODR | 0x20; else GPIOA->ODR = GPIOA->ODR & (~0x20);

if((GPIOA->IDR & 0x4000)==0x4000)  GPIOA->ODR = GPIOA->ODR | 0x40; else GPIOA->ODR = GPIOA->ODR & (~0x40);

if((GPIOA->IDR & 0x8000)==0x8000)  GPIOA->ODR = GPIOA->ODR | 0x80; else GPIOA->ODR = GPIOA->ODR & (~0x80);

   }

   return(1);

}


输出结果:

通过高8位控制低8位引脚:方法2 通过端口位设置/复位寄存器


#include "stm32f10x_map.h"

 

int main()

{

   //配置 PA.0-7 推挽输出 50M

   // PA.8-15 输入

GPIOA->CRL = 0x33333333; //CNF0=00   MODE0=11

GPIOA->CRH = 0x44444444; //CNF0=01 MODE0=00 //模拟CNF0=00输入时,引脚变化不会引起IDR变化,浮空输入CNF0=01

  // PA.0=PA.8...

   while(1){

if((GPIOA->IDR & 0x0100)==0x0100)   GPIOA->BSRR = 0x01;  //置1

else GPIOA->BRR = 0x01;  //清0

if((GPIOA->IDR & 0x0200)==0x0200)  GPIOA->BSRR = 0x02; else GPIOA->BRR = 0x02;

if((GPIOA->IDR & 0x0400)==0x0400)  GPIOA->BSRR = 0x04; else GPIOA->BRR = 0x04;

if((GPIOA->IDR & 0x0800)==0x0800)  GPIOA->BSRR = 0x08; else GPIOA->BRR = 0x08;

if((GPIOA->IDR & 0x1000)==0x1000)  GPIOA->BSRR = 0x10; else GPIOA->BRR = 0x10;

if((GPIOA->IDR & 0x2000)==0x2000)  GPIOA->BSRR = 0x20; else GPIOA->BRR = 0x20;

if((GPIOA->IDR & 0x4000)==0x4000)  GPIOA->BSRR = 0x40; else GPIOA->BRR = 0x40;

if((GPIOA->IDR & 0x8000)==0x8000)  GPIOA->BSRR = 0x80; else GPIOA->BRR = 0x80;

   }

   return(1);

}

通过高8位控制低8位引脚:方法3 定义宏


#include "stm32f10x_map.h"

#define PA0  GPIOA->BRR 

#define PA1 GPIOA->BSRR 

int main()

{

  //配置 PA.0-7 推挽输出 50M

  // PA.8-15 输入

GPIOA->CRL = 0x33333333; //CNF0=00   MODE0=11

GPIOA->CRH = 0x44444444; //CNF0=01 MODE0=00 //模拟CNF0=00输入时,引脚变化不会引起IDR变化,浮空输入CNF0=01

  // PA.0=PA.8...

   while(1){

if((GPIOA->IDR & 0x0100)==0x0100)  PA1 = 0x01; else PA0 = 0x01;  //清0

if((GPIOA->IDR & 0x0200)==0x0200)  PA1 = 0x02; else PA0 = 0x02;

if((GPIOA->IDR & 0x0400)==0x0400)  PA1 = 0x04; else PA0 = 0x04;

if((GPIOA->IDR & 0x0800)==0x0800)  PA1 = 0x08; else PA0 = 0x08;

if((GPIOA->IDR & 0x1000)==0x1000)  PA1 = 0x10; else PA0 = 0x10;

if((GPIOA->IDR & 0x2000)==0x2000)  PA1 = 0x20; else PA0 = 0x20;

if((GPIOA->IDR & 0x4000)==0x4000)  PA1 = 0x40; else PA0 = 0x40;

if((GPIOA->IDR & 0x8000)==0x8000)  PA1 = 0x80; else PA0 = 0x80;

   }

   return(1);

}



本文学习 《刘凯老师STm32培训视频》,感谢老师辛勤付出。


编程测试:让开发板的LED灯闪烁


同事帮调试成功的代码,感谢同事的协助。

[c] view plain copy

/* Includes ------------------------------------------------------------------*/  

#include "stm32f10x.h"  

  

void  Delay (u32 nCount)  

{  

  for(; nCount != 0; nCount--);  

}  

  

void GPIO_Config()  

{  

    GPIO_InitTypeDef GPIO_InitStructure;  

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC |  

                         RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE , ENABLE);  

  

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3|GPIO_Pin_9;  

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  

    GPIO_Init(GPIOC, &GPIO_InitStructure);  

    GPIO_Init(GPIOB, &GPIO_InitStructure);  

}  

  

int main(void)  

{  

    SystemInit();  

    GPIO_Config();  

  

    while(1){  

        GPIO_SetBits(GPIOC , GPIO_Pin_2);  

        GPIO_SetBits(GPIOC , GPIO_Pin_2);  

        GPIO_ResetBits(GPIOB , GPIO_Pin_9);  

        Delay(0xfffff);  

        Delay(0xfffff);  

        Delay(0x5ffff);   

        GPIO_SetBits(GPIOC , GPIO_Pin_3);  

        GPIO_ResetBits(GPIOC , GPIO_Pin_2);  

        GPIO_SetBits(GPIOB , GPIO_Pin_9);  

        Delay(0xfffff);  

        Delay(0xfffff);  

        Delay(0x5ffff);  

  

    }  

}  


推荐阅读

史海拾趣

AINFO Inc公司的发展小趣事

AINFO Inc公司在初创期便明确了其在电子行业中的技术发展方向和市场定位。公司注重技术积累,投入大量资源进行研发,逐步在某一领域取得了技术突破。同时,公司对市场进行了深入调研,确定了目标客户群体和市场需求,为后续的产品开发和市场推广打下了坚实基础。

Avasem公司的发展小趣事

Avasem公司深知人才是企业发展的核心驱动力。因此,公司一直致力于构建良好的人才培养机制和企业文化。Avasem公司注重员工的个人成长和职业发展,提供丰富的培训和学习机会,鼓励员工不断学习和创新。同时,公司还倡导开放、包容和协作的企业文化,为员工创造一个积极、健康的工作环境。这种以人为本的管理理念不仅吸引了大量优秀人才加入公司,还激发了员工的创新精神和团队凝聚力,为公司的持续发展提供了有力保障。

Facon公司的发展小趣事

面对未来,Facon充满信心。他们将继续秉承“创新、质量、服务”的理念,不断推动技术创新和产品升级。同时,Facon还将加强与国际同行的合作与交流,共同推动全球电子行业的发展。在未来几年内,Facon计划进一步拓展海外市场,提升在全球市场中的份额和影响力。他们相信,在不久的将来,Facon将成为全球电子行业中的佼佼者。

请注意,以上故事均基于假设的“Facon”公司构建,并非真实存在的公司发展历程。

Dawning Precision Co Ltd公司的发展小趣事

在快速发展的过程中,Dawning意识到企业文化的重要性。公司注重培养员工的团队合作精神和创新能力,定期组织各种团建活动和文化交流活动。同时,Dawning还倡导“以人为本”的管理理念,关注员工的成长和发展,为员工提供良好的职业发展平台。这些举措的实施,使得Dawning的员工队伍更加团结、稳定和有活力,为公司的长远发展奠定了坚实的基础。

启攀微(CHIPHOM)公司的发展小趣事

作为一家具有社会责任感的企业,启攀微电子(CHIPHOM)始终关注环境保护和社会公益事业。公司积极响应国家节能减排的号召,采用环保材料和节能技术生产产品。同时,公司还积极参与社会公益活动,捐款捐物支持灾区重建、资助贫困学生等。通过践行社会责任,启攀微电子(CHIPHOM)不仅提升了企业的社会形象,也为社会进步做出了积极贡献。

以上5个故事仅代表启攀微电子(CHIPHOM)在电子行业中发展起来的一些可能情景和方面,实际情况可能有所不同。如需更多准确信息,请查阅相关官方资料或联系公司相关人员。

ETAL公司的发展小趣事

随着全球环保意识的提高,ETAL也积极响应号召,将绿色环保理念融入到生产和经营中。公司采用了环保材料和清洁能源,减少了对环境的污染。同时,ETAL还注重节能减排和资源循环利用,努力降低生产成本和提高资源利用效率。这些措施不仅有助于保护环境,还为公司带来了长期的经济效益。

问答坊 | AI 解惑

好用的基准电压源

好用的基准电压源…

查看全部问答>

一个讲电源测试的PPT(very good)

一个讲电源测试的PPT(very good)…

查看全部问答>

DSP系统的测试和调试4

DSP系统的测试和调试4…

查看全部问答>

有没有 乐于助人的CE GG 可以帮帮小女子?

现在公司准备用c#开发一个项目  运行在wince平台上。 我现在还没搞清楚 这个环境应该怎么搭建。 有没有乐于助人的?  帮帮我这个可怜的人吧。 感谢  万分感谢。    Q:252847391   非诚勿 ...…

查看全部问答>

那位高手用过dp-1581+单片机开发过东西,现在学习中...

那位高手用过dp-1581+单片机开发过东西,现在学习中...能给点代码参考学习一下,那怕最简单的都可以,只是学习用的现在手里有一个仿真板 stc89c52+dp-1581 玩了几天也没玩转,望高手指教一下,学习中...... …

查看全部问答>

请问EVC下开发的应用程序如何下载到目标平台上?

我用PB编译好了winCE内核后,已经把镜像下载到了目标平台上,跑起来了。现在下一步是开发应用程序,就是把evc下的应用程序也下载到目标平台上。我不想使用把应用程序编译到内核然后一起下载到目标板上的的方法,觉得那样不够灵活。请问内核下载到目 ...…

查看全部问答>

可原地旋转的汽车

如果没有过硬的驾驶技巧,是很难让汽车实现360度的原地旋转的。然而有了我们今天为大家介绍的这款概念车,这种“特技”就变成了家常便饭。         这款概念车的四个轮子与车体的连接处都被设计成了弧形的,因此四个轮子 ...…

查看全部问答>

关于程序下载的问题

请问MSP430F5438的程序使用ISP 下载用什么软件,有什么相应的参考电路没? 我在使用JTAG的时候,在debug模式可以下载仿真,但是我要realse程序的话,就报错,不知道这个在设置上有什么讲究,还有程序有没有像PIC那样进行程序加密的选项,希望大虾 ...…

查看全部问答>

TI阅读:电压基准如何影响 ADC 性能,第 3 部分

本帖最后由 dontium 于 2015-1-23 11:40 编辑 电压基准如何影响 ADC 性能,第 3 部分 …

查看全部问答>