STM32_IO口操作
- 格式:doc
- 大小:160.50 KB
- 文档页数:7
STM32端⼝输⼊输出模式配置STM32的IO⼝模式配置根据数据⼿册提供的信息,stm32的io⼝⼀共有⼋种模式,他们分别是:四种输⼊模式上拉输⼊:通过内部的上拉电阻将⼀个不确定的信号通过⼀个电阻拉到⾼电平。
下拉输⼊:把电压拉到GND。
与上拉原理相似。
浮空输⼊:引脚内部什么都不接,处于浮空模式下,电平状态是不确定的。
外部信号输⼊什么,IO⼝就是什么状态。
模拟输⼊:接收到的是连续的模拟信号,⼀般⽤于AD转换。
四种输出模式推挽输出:可以输出⾼低电平,连接数字器件。
在stm32中推挽电路由两个MOS管组成:输出⾼电平时P-MOS管导通,引脚联通VDD(3.3v)。
输出低电平时N-MOS导通,引脚联通GND。
**该⽅式既提⾼电路的负载能⼒,⼜提⾼开关速度。
**开漏输出:⽆法直接输出⾼电平,要在外部连接上拉电阻才⾏,输出的电压由上拉电阻连接的电源决定。
适合做电流型的驱动,其吸收电流的能⼒相对强(⼀般20ma以内)。
开漏输出还有⼀个特性:线与。
即很多开漏模式引脚连接在⼀起,只有当所有引脚都输出1时,才能够被上拉电阻拉到⾼电平。
若有⼀个引脚为低电平,则所有引脚相当于接地。
复⽤推挽输出:简单来说就是给内部外设使⽤的推挽输出模式,复⽤开漏输出:简单来说就是给内部外设使⽤的开漏输出模式在STM32中,根据不同的使⽤场景,选⽤不同的IO模式:GPIO_Mode_AIN:模拟输⼊,⼀般⽤作模数转换GPIO_Mode_IN_FLOATING:浮空输⼊,常⽤在key识别上**GPIO_Mode_IPD: **下拉输⼊--- IO内部下拉电阻输⼊GPIO_Mode_IPU:上拉输⼊--- IO内部上拉电阻输⼊GPIO_Mode_Out_OD:开漏输出---可以外接上拉电阻输出较⾼的电平,也能够通过读取IO的电平变化实现C51的IO双向功能。
**GPIO_Mode_Out_PP: **推挽输出---IO输出0-接GND,IO输出1 -接VCC,读输⼊值是未知的。
1、不使用库函数的IO口操作Systick 部分内容属于NVIC控制部分,一共有4个寄存器SysTick_CTRL, 0xE000E010 -- 控制寄存器默认值:0x0000 0004SysTick_LOAD, 0xE000E014 -- 重载寄存器默认值:0x0000 0000SysTick_VAL, 0xE000E018 -- 当前值寄存器默认值:0x0000 0000SysTick_CALIB, 0xE000E01C -- 校准值寄存器默认值:0x0002328SysTick_CTRL 寄存器内有4个bit具有意义第0位:ENABLE,Systick 使能位(0:关闭Systick功能;1:开启Systick功能)第1位:TICKINT,Systick 中断使能位(0:关闭Systick中断;1:开启Systick中断)第2位:CLKSOURCE,Systick时钟源选择(0:使用HCLK/8 作为Systick时钟;1:使用HCLK作为系统时钟)第16位:COUNTFLAG,Systick计数比较标志IO口的位操作实现该部分代码实现对STM32各个IO口的位操作,包括读入和输出。
当然在这些函数调用之前,必须先进行IO口时钟的使能和IO口功能定义。
此部分仅仅对IO口进行输入输出读取和控制。
代码如下:#define BITBAND(addr,bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2))#define MEM_ADDR(addr) *((volatile unsigned long *)(addr))#define BIT_ADDR(addr,bitnum) MEM_ADDR(BITBAND(addr,bitnum)) //IO口地址映射#define GPIOA_ODR_Addr (GPIOA_BASE+12) //0x4001080C#define GPIOB_ODR_Addr (GPIOB_BASE+12) //0x40010C0C#define GPIOC_ODR_Addr (GPIOC_BASE+12) //0x4001100C#define GPIOD_ODR_Addr (GPIOD_BASE+12) //0x4001140C#define GPIOE_ODR_Addr (GPIOE_BASE+12) //0x4001180C#define GPIOF_ODR_Addr (GPIOF_BASE+12) //0x40011A0C#define GPIOA_IDR_Addr (GPIOA_BASE+8) //0x40010808 #define GPIOB_IDR_Addr (GPIOB_BASE+8) //0x40010C08 #define GPIOC_IDR_Addr (GPIOC_BASE+8) //0x40011008 #define GPIOD_IDR_Addr (GPIOD_BASE+8) //0x40011408 #define GPIOE_IDR_Addr (GPIOE_BASE+8) //0x40011808 #define GPIOF_IDR_Addr (GPIOF_BASE+8) //0x40011A08 55//IO口操作,只对单一的IO口!//确保n的值小于16!#define PAout(n) BIT_ADDR(GPIOA_ODR_Addr,n) //输出#define PAin(n) BIT_ADDR(GPIOA_IDR_Addr,n) //输入#define PBout(n) BIT_ADDR(GPIOB_ODR_Addr,n) //输出#define PBin(n) BIT_ADDR(GPIOB_IDR_Addr,n) //输入#define PCout(n) BIT_ADDR(GPIOC_ODR_Addr,n) //输出#define PCin(n) BIT_ADDR(GPIOC_IDR_Addr,n) //输入#define PDout(n) BIT_ADDR(GPIOD_ODR_Addr,n) //输出#define PDin(n) BIT_ADDR(GPIOD_IDR_Addr,n) //输入#define PEout(n) BIT_ADDR(GPIOE_ODR_Addr,n) //输出#define PEin(n) BIT_ADDR(GPIOE_IDR_Addr,n) //输入#define PFout(n) BIT_ADDR(GPIOF_ODR_Addr,n) //输出#define PFin(n) BIT_ADDR(GPIOF_IDR_Addr,n) //输入#define PGout(n) BIT_ADDR(GPIOG_ODR_Addr,n) //输出#define PGin(n) BIT_ADDR(GPIOG_IDR_Addr,n) //输入以上代码的实现得益于CM3的位带操作,具体的实现比较复杂,请参考<<CM3权威指南>>第五章(87页~92页)。
主题:STM32读取IO口高电平范围分析内容:1. STM32简介1.1 STM32是由意法半导体公司推出的一款32位嵌入式微控制器产品线。
1.2 STM32具有高性能、低功耗、丰富的外设接口和丰富的开发工具支持等特点。
2. IO口的定义2.1 IO口是微控制器上的通用输入输出引脚,可以通过程序控制其电平状态。
2.2 在一般情况下,IO口可以设置为输入模式或输出模式。
3. STM32读取IO口高电平的方法3.1 使用GPIO读取寄存器3.1.1 GPIO读取寄存器是用来读取IO口的高电平状态的寄存器。
3.1.2 该寄存器可以通过位操作来读取每个IO口的状态,可以获取其高电平状态。
3.2 使用外部中断3.2.1 在需要及时响应IO口状态变化的情况下,可以使用外部中断来读取IO口的高电平状态。
3.2.2 外部中断可以在IO口状态发生变化时立即响应,提高了系统的实时性。
3.3 使用定时器3.3.1 定时器可以周期性地读取IO口的状态,对于需要进行定时采集的场景较为适用。
3.3.2 通过定时器可以定时读取IO口的高电平状态,并进行相应的处理和分析。
4. STM32读取IO口高电平的限制4.1 IO口的速度限制4.1.1 由于IO口的速度限制,读取高电平的频率受到一定的限制。
4.1.2 针对高速信号的IO口读取,需要根据具体情况选择合适的读取方法。
4.2 IO口的电压范围限制4.2.1 STM32的IO口在读取高电平时,需要注意其电压范围的限制。
4.2.2 超过了IO口能够承受的电压范围,可能会损坏IO口或引发其他问题。
5. 结论5.1 通过GPIO读取寄存器、外部中断、定时器等方法,可以实现STM32读取IO口高电平的功能。
5.2 在使用这些方法时,需要注意IO口的速度限制和电压范围限制,以确保系统的稳定性和安全性。
结尾:以上就是对STM32读取IO口高电平范围的分析,希望对您有所帮助。
如有任何问题,欢迎交流讨论。
STM32的IO⼝设置⽅法实例STM32的IO⼝设置⽅法实例!通过本节的学习,你将了解到STM32的IO⼝作为输出使⽤的⽅法。
本节分为如下⼏个⼩节:3.1.1 STM32 IO⼝简介3.1.2 硬件设计3.1.3 软件设计3.1.4 仿真与下载3.1.1 STM32 IO简介作为所有开发板的经典⼊门实验,莫过于跑马灯了。
ALIENTEK MiniSTM32开发板板载了2个LED,DS0和DS1,本实验将通过教你如何控制这两个灯实现交替闪烁的类跑马灯效果。
该实验的关键在于如何控制STM32的IO⼝输出。
了解了STM32的IO⼝如何输出的,就可以实现跑马灯了。
通过这⼀节的学习,你将初步掌握STM32基本IO⼝的使⽤,⽽这是迈向STM32的第⼀步。
STM32的IO⼝可以由软件配置成8种模式:1、输⼊浮空2、输⼊上拉3、输⼊下拉4、模拟输⼊5、开漏输出6、推挽输出7、推挽式复⽤功能8、开漏复⽤功能每个IO⼝可以⾃由编程,单IO⼝寄存器必须要按32位字被访问。
STM32的很多IO⼝都是5V兼容的,这些IO⼝在与5V电平的外设连接的时候很有优势,具体哪些IO⼝是5V兼容的,可以从该芯⽚的数据⼿册管脚描述章节查到(I/O Level标FT的就是5V电平兼容的)。
STM32的每个IO端⼝都有7个寄存器来控制。
他们分别是:配置模式的2个32位的端⼝配置寄存器CRL和CRH;2个32位的数据寄存器IDR和ODR;1个32位的置位/复位寄存器BSRR;⼀个16位的复位寄存器BRR;1个32位的锁存寄存器LCKR;这⾥我们仅介绍常⽤的⼏个寄存器,我们常⽤的IO端⼝寄存器只有4个:CRL、CRH、IDR、ODR。
CRL和CRH控制着每个IO⼝的模式及输出速率。
STM32的IO⼝位配置表如表3.1.1.1所⽰:表3.1.1.1 STM32的IO⼝位配置表STM32输出模式配置如表3.1.1.2所⽰:表3.1.1.2 STM32输出模式配置表接下来我们看看端⼝低配置寄存器CRL的描述,如下图所⽰:图3.1.1.1端⼝低配置寄存器CRL各位描述该寄存器的复位值为0X4444 4444,从上图可以看到,复位值其实就是配置端⼝为浮空输⼊模式。
一、概述在嵌入式系统开发中,常常需要对STM32单片机的IO口进行操作。
其中,IO口对地电阻的问题是一个重要的话题。
本文将详细介绍STM32单片机IO口对地电阻的相关知识,包括其原理、计算方法和在实际开发中的应用。
二、STM32单片机IO口对地电阻的原理1. STM32单片机IO口STM32单片机拥有丰富的外设资源,其中IO口是其中最基本的一个。
IO口可以设置为输入或者输出模式,用于连接外部设备或者作为数据输入输出的通道。
2. IO口对地电阻的概念在使用IO口时,会涉及到与地之间的电阻。
当IO口处于输出模式时,如果外部设备与IO口相连,就会形成一个电路。
而在该电路中,IO口与地之间的电阻就称为IO口对地电阻。
IO口对地电阻的大小会影响IO口的输出电平和稳定性,因此需要合理设置。
三、STM32单片机IO口对地电阻的计算方法1. IO口对地电阻的计算公式IO口对地电阻的大小可以通过计算得出。
假设STM32单片机输出高电平时的输出电流为I,输出低电平时的输出电流为I_L,从而可以得到IO口对地电阻的计算公式如下:R = V / I其中R为IO口对地电阻,V为IO口输出高电平时的电压。
2. 实际计算方法在实际计算中,需要先确定IO口的输出电压和输出电流大小,然后通过上述公式即可计算得出IO口对地电阻的大小。
在计算时需要考虑实际电路中的影响因素,如外部电阻等。
四、STM32单片机IO口对地电阻的应用1. IO口对地电阻的影响IO口对地电阻的大小直接影响了IO口输出电平的稳定性和可靠性。
较大的IO口对地电阻会导致输出电平波动较大,甚至无法正常输出高电平。
合理设置IO口对地电阻对于保证IO口正常工作至关重要。
2. 设置IO口对地电阻的方法在实际开发中,可以采取一定的措施来设置IO口对地电阻。
可以通过外部电路方式对IO口进行负载补偿,从而降低IO口对地电阻的大小,提高输出稳定性。
五、结论本文从STM32单片机IO口对地电阻的原理、计算方法和应用进行了详细介绍。
STM32单片机的八种IO口模式解析
STM32八种IO口模式区别
(1)GPIO_Mode_AIN模拟输入
(2)GPIO_Mode_IN_FLOATING浮空输入
(3)GPIO_Mode_IPD下拉输入
(4)GPIO_Mode_IPU上拉输入
(5)GPIO_Mode_Out_OD开漏输出
(6)GPIO_Mode_Out_PP推挽输出
(7)GPIO_Mode_AF_OD复用开漏输出
(8)GPIO_Mode_AF_PP复用推挽输出
以下是详细讲解
(1)GPIO_Mode_AIN模拟输入
即关闭施密特触发器,将电压信号传送到片上外设模块(不接上、下拉电阻)
(2)GPIO_Mode_IN_FLOATING浮空输入
浮空输入状态下,IO的电平状态是不确定的,完全由外部输入决定,如果在该引脚悬空的情况下,读取该端口的电平是不确定的
(3)GPIO_Mode_IPD下拉输入GPIO_Mode_IPU上拉输入
一般来讲,上拉电阻为1K-10K,电阻越小,驱动能力越强
电阻的作用:防止输入端悬空,减少外部电流对芯片的干扰,限流;,增加高电平输出时的驱动能力。
上拉输入:在默认状态下(GPIO引脚无输入)为高电平
下拉输入:在默认状态下(GPIO引脚无输入)为低电平
(4)GPIO_Mode_Out_OD开漏输出
开漏输出:输出端相当于三极管的集电极。
要得到高电平状态需要上拉电阻才行。
适合于做电流型的驱动,。
stm32位操作详解stm32位操作详解STM32位操作原理思想:把⼀个⽐特分成32位,每位都分配⼀个地址,这样就有32个地址,通过地址直接访问。
位操作基础位运算位运算的运算分量只能是整型或字符型数据,位运算把运算对象看作是由⼆进位组成的位串信息,按位完成指定的运算,得到位串信息的结果。
位运算&(按位与)、|(按位或)、^(按位异或)、~ (按位取反)。
其中,按位取反运算符是单⽬运算符,其余均为双⽬运算符。
位运算符的优先级从⾼到低,依次为~、&、^、|,其中~的结合⽅向⾃右⾄左,且优先级⾼于算术运算符,其余运算符的结合⽅向都是⾃左⾄右,且优先级低于关系运算符。
(1)按位与运算符(&)按位与运算将两个运算分量的对应位按位遵照以下规则进⾏计算:0 & 0 = 0, 0 & 1 = 0, 1 & 0 = 0, 1 & 1 = 1。
即同为1的位,结果为1,否则结果为0。
例如,设3的内部表⽰为000000115的内部表⽰为00000101则3&5的结果为00000001按位与运算有两种典型⽤法,⼀是取⼀个位串信息的某⼏位,如以下代码截取x的最低7位:x & 0177。
⼆是让某变量保留某⼏位,其余位置0,如以下代码让x只保留最低6位:x = x & 077。
以上⽤法都先要设计好⼀个常数,该常数只有需要的位是 (2)按位或运算符(|)按位或运算将两个运算分量的对应位按位遵照以下规则进⾏计算:0 | 0 = 0, 0 | 1 = 1, 1 | 0 = 1, 1 | 1 = 1即只要有1个是1的位,结果为1,否则为0。
例如,023 | 035结果为037。
按位或运算的典型⽤法是将⼀个位串信息的某⼏位置成1。
如将要获得最右4为1,其他位与变量j的其他位相同,可⽤逻辑或运算017|j。
若要把这结果赋给变量j,可写成:j = 017|j(3)按位异或运算符(^)按位异或运算将两个运算分量的对应位按位遵照以下规则进⾏计算:0 ^ 0 = 0, 0 ^ 1 = 1, 1 ^ 0 = 1, 1 ^ 1 = 0即相应位的值相同的,结果为0,不相同的结果为1。
以及上拉输入、下拉输入、浮空输入、模拟输入的区别最近在看数据手册的时候,发现在Cortex-M3里,对于GPIO的配置种类有8种之多:(1)GPIO_Mode_AIN 模拟输入(2)GPIO_Mode_IN_FLOATING 浮空输入(3)GPIO_Mode_IPD 下拉输入(4)GPIO_Mode_IPU 上拉输入(5)GPIO_Mode_Out_OD 开漏输出(6)GPIO_Mode_Out_PP 推挽输出(7)GPIO_Mode_AF_OD 复用开漏输出(8)GPIO_Mode_AF_PP 复用推挽输出对于刚入门的新手,我想这几个概念是必须得搞清楚的,平时接触的最多的也就是推挽输出、开漏输出、上拉输入这三种,但一直未曾对这些做过归纳。
因此,在这里做一个总结:推挽输出:可以输出高,低电平,连接数字器件; 推挽结构一般是指两个三极管分别受两互补信号的控制,总是在一个三极管导通的时候另一个截止。
高低电平由IC的电源低定。
推挽电路是两个参数相同的三极管或MOSFET,以推挽方式存在于电路中,各负责正负半周的波形放大任务,电路工作时,两只对称的功率开关管每次只有一个导通,所以导通损耗小、效率高。
输出既可以向负载灌电流,也可以从负载抽取电流。
推拉式输出级既提高电路的负载能力,又提高开关速度。
详细理解:如图所示,推挽放大器的输出级有两个“臂”(两组放大元件),一个“臂”的电流增加时,另一个“臂”的电流则减小,二者的状态轮流转换。
对负载而言,好像是一个“臂”在推,一个“臂”在拉,共同完成电流输出任务。
当输出高电平时,也就是下级负载门输入高电平时,输出端的电流将是下级门从本级电源经VT3拉出。
这样一来,输出高低电平时,VT3 一路和VT5 一路将交替工作,从而减低了功耗,提高了每个管的承受能力。
又由于不论走哪一路,管子导通电阻都很小,使RC常数很小,转变速度很快。
因此,推拉式输出级既提高电路的负载能力,又提高开关速度。
STM32⼀些特殊引脚做IO使⽤的注意事项1 PC13、PC14、PC15的使⽤这三个引脚与RTC复⽤,《STM32参考⼿册》中这样描述:PC13 PC14 PC15需要将VBAT与VDD连接,实测采⽤以下程序驱动4个74HC165可以不⽤上拉电阻,输出速度配置为2MHz(实测50MHz也能输出正常),但是还是建议加上拉电阻⽐较好。
最新⽂档中已经删除“在同⼀时间只有⼀个引脚能作为输出”也就是三个引脚可以同时作为输出引脚,其他条件未变库函数版本程序如下:1. RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOC|RCC_APB2Periph_AFIO, ENABLE );2.3. PWR_BackupAccessCmd( ENABLE );/* 允许修改RTC和后备寄存器,取消备份区写保护*/4. RCC_LSEConfig( RCC_LSE_OFF ); /* 关闭外部低速时钟OSC32,PC14+PC15可以⽤作普通IO*/5. BKP_TamperPinCmd(DISABLE); /* 关闭TAMPER⼊侵检测功能,PC13可以⽤作普通IO*/6. PWR_BackupAccessCmd(DISABLE); /* 禁⽌修改RTC和后备寄存器,备份区写保护*/7.8. /*注意PC13 PC14 PC15通过电源开关进⾏供电,只能吸收3mA电流,输出只能⼯作在2MHz,最⼤驱动30pF,不能驱动LED*/9. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 |GPIO_Pin_14 | GPIO_Pin_15; //PC13=SH/LD,PC14=SCLK,PC15空10. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;11. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//GPIO_Mode_Out_PP;12. GPIO_Init(GPIOC, &GPIO_InitStructure);寄存器版本程序初始化如下:1. RCC->APB2ENR|=1<<4; //使能PORTC时钟2. RCC->APB2ENR|=1<<0; //使能AFIO时钟3. GPIOC->CRH&=0X000FFFFF; //PC13,14,15设置成输出 2MHz 推挽输出4. GPIOC->CRH|=0X22200000;5. PWR->CR|=1<<8; //取消备份区写保护6. RCC->BDCR&=0xFFFFFFFE; //外部低俗振荡器关闭 C14,PC15成为普通IO7. BKP->CR&=0xFFFFFFFE; //侵⼊检测TAMPER引脚作为通⽤IO⼝使⽤8. PWR->CR&=0xFFFFFEFF; //备份区写保护其他链接:2 PB3、PB4、PA15引脚做GPIO使⽤(SWD下载程序)PB3、PB4、PA15分别与JTDO、JNTRST和JTDI复⽤,做普通⼝需要禁⽤JTAG,使⽤SWD下载程序。
STM32的IO口读写#define LCD_DATA_IN(((GPIOC->IDR & PINS_DATA) >> 0) & 0xFF) //端口输入寄存器/* Writing value to DA TA pins */ #define LCD_DATA_OUT(x) GPIOC->ODR = (GPIOC->ODR & ~PINS_DA TA) | (x << 0); //端口输出寄存器/* Setting all pins to output mode */#define LCD_ALL_DIR_OUTGPIOC->CRL = (GPIOC->CRL & 0x00000000) | 0x33333333; //配置寄存器低8位GPIOC->CRH = (GPIOC->CRH & 0xFFF00000) | 0x00033333; //配置寄存器高8位uchar value ;tValue = ~value;GPIOB->BSRR = (uint) value; //高16复位/低16置位寄存器GPIOB->BRR = (uint) tV alue; //低16复位寄存器GPIO_WriteBit(GPIOB, GPIO_Pin_2,Bit_RESET); //重置单个或多个位IO为0状态GPIO_WriteBit(GPIOB, GPIO_Pin_2,Bit_SET); //重置单个或多个位IO为1状态GPIO_WriteBit(GPIOB, GPIO_Pin_2,(BitAction)0x01); //写入单个或多个位IO为1状态GPIO_WriteBit(GPIOB, GPIO_Pin_2,(BitAction)0x00); //写入单个或多个位IO为0状态GPIO_Write(GPIOC,0xaa55); //写入整个PORT 口的状态GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_6);//读入单个或多个输入寄存器的位IO状态//必须在输入模式GPIO_ReadInputData(GPIOA);//读入整个输入口寄存器的IO状态//必须在输入模式GPIO_ReadOutputDataBit(GPIOA,GPIO_Pin_6);//读入单个或多个输出寄存器的位IO状态//必须在输出模式GPIO_ReadOutputData(GPIOA);//读入整个输出口寄存器的IO状态//必须在输出模式GPIO_SetBits(GPIOD,GPIO_Pin_2); //置1GPIO_SetBits(GPIOD,GPIO_Pin_3|GPIO_Pin_4); //置1 GPIO_ResetBits(GPIOD,GPIO_Pin_2); //清0GPIO_ResetBits(GPIOD,GPIO_Pin_4|GPIO_Pin_3); //清0。
STM32运用总结主要分为IO口,定时器的PWM和QEI,中断,ADC,DAC和DMA介绍。
在STM32的运用中第一步一般是使能相应模块的时钟,然后配置IO口,最后配置相应的寄存器。
1.IO口STM32的IO口非常多,而且与其它外设模块通常是复用的。
在不同的外设中IO口的设置是不一样的。
这一部分介绍普通的数值IO口。
IO口有A-G共7组,每组16口。
1.IO口在时钟总线AHB1上,使能对应端口的时钟。
在寄存器RCC->AHB1ENR中。
2.配置IO口的模式,普通的IO口配置为普通的输入输出模式。
配置IO口是悬空还是上拉或者下拉。
以上两步分别在寄存器GPIOx->MODER和GPIOx->PUPDR(x=A,B,C,D,E,F,G)3.其中配置为输出模式时还要设置速度和相应的输出方式,开漏或者推挽,以上两步分别在寄存器GPIOx-> OSPEEDR和GPIOx->OTYPER(x=A,B,C,D,E,F,G)。
4.设置IO口的高低电平。
在寄存器GPIOx->BSRRH中置相应的位为1就是将相应的位置0,在寄存器GPIOx->BSRRL中置相应的位为1就是将相应的位置1.另外还可以设置GPIOx_ODR寄存器来设置输出电平以及读取GPIOx_IDR寄存器来获取输入电平。
2.PWMSTM32的定时器也非常之多,用到的主要是两个部分:用定时器产生PWM和定时触发ADC,这里一部分介绍PWM。
(高级定时器的配置和这差不多,由于在STM32F103里面已经尝试过在STM32F407里面就没有再写)1.配置IO口。
我们说过STM32的外设模块主要是和IO口复用的,因此在使用外设模块时首先配置好相应的IO口。
比如使用A口的PA1作为定时器Timer2的PWM输出。
则应按照如下的步骤来配置PA1。
1)使能A口的时钟。
在寄存器RCC->AHB1ENR中。
2)配置PA1为复用功能。
STM32IO口函数GPIO使用说明STM32是一款广泛使用的32位单片机,具有丰富的外设资源,其中之一就是IO(Input/Output)口。
IO口是STM32与外部世界进行通信的接口,本文将对如何使用STM32IO口函数GPIO进行详细说明。
GPIO是通用输入输出口,可以配置为输入或输出,可以连接到各种外部设备如按钮、开关、LED等。
STM32提供了一系列GPIO口,如GPIOA、GPIOB等。
每个GPIO口有多个引脚可供选择,如GPIOA口有GPIO_Pin_0到GPIO_Pin_15共16个引脚。
在使用IO口之前,需要初始化IO口的设置,包括如下步骤:1.选择GPIO口:选择需要操作的GPIO口,如GPIOA或GPIOB。
2.配置引脚模式:确定所需的引脚模式,如输入、输出或复用模式。
3.配置引脚输出类型:如果选择输出模式,需要确定输出类型,如推挽输出或开漏输出。
4.配置引脚速度:确定引脚的传输速度。
5.配置引脚上拉/下拉:确定引脚是否需要上拉或下拉电阻。
6.配置引脚复用功能:如果选择复用模式,配置引脚使用的功能。
以下为具体的GPIO函数说明:1. GPIO_InitTypeDef:GPIO初始化结构体,包含需要配置的GPIO口、引脚模式、输出类型、速度、上拉/下拉等信息。
- 参数:GPIO_TypeDef* GPIOx:需要初始化的GPIO口;uint16_t GPIO_Pin: 需要初始化的引脚。
2. GPIO_Pin_0到GPIO_Pin_15:宏定义,用于选择要配置的引脚。
3. GPIO_Mode:引脚模式枚举类型,包括输入模式(GPIO_Mode_IN)、输出模式(GPIO_Mode_OUT)和复用功能模式(GPIO_Mode_AF)。
4. GPIO_Speed:引脚速度枚举类型,包括低速(GPIO_Speed_2MHz)、中速(GPIO_Speed_10MHz)和高速(GPIO_Speed_50MHz)。
最全的STM32八种IO口模式讲解STM32是一种基于ARM Cortex-M处理器的微控制器系列,具有强大的性能和广泛的应用领域。
而IO口是STM32微控制器中常见的功能之一,它允许我们与外部设备进行通信和数据交换。
在STM32中,IO口有八种不同的模式,本文将逐一进行讲解。
1. 输入浮空模式(Floating Input)输入浮空模式是IO口的默认模式。
在这种模式下,IO口既不输出也不输入电平信号,它的电平状态由外部电路决定。
这种模式非常适用于连接外部传感器或其他输入设备。
2. 模拟输入模式(Analog Input)模拟输入模式是用于连接模拟传感器的模式。
在这种模式下,IO口被配置为模拟输入引脚,可以读取来自传感器的模拟电压值。
3. 输出推挽模式(Push-pull Output)输出推挽模式是最常用的IO口模式之一、在这种模式下,IO口既能输出高电平,也能输出低电平。
它能够驱动较大负载,并且在输出状态下具有较低的电平谐波失真。
推挽输出模式常用于控制LED灯、继电器和其他外部设备。
4. 输出开漏模式(Open-drain Output)输出开漏模式也被称为开漏输出模式。
在这种模式下,IO口只能输出低电平,而不能输出高电平。
当IO口输出低电平时,它会与外部上拉电阻连接,使得整个电路可以实现低电平输出。
开漏输出模式常用于I2C总线和其他需要共享信号线的应用。
5. 复用推挽模式(Push-pull Alternate Function)复用推挽模式是IO口的特殊模式之一、在这种模式下,IO口既可以用于通用IO功能,也可以用作一些外设的引脚。
复用推挽模式常用于USART、SPI和I2C等串行通信接口。
6. 复用开漏模式(Open-drain Alternate Function)复用开漏模式也是IO口的特殊模式之一、在这种模式下,IO口可以用作一些外设的引脚,并且只能输出低电平。
复用开漏模式常用于I2C总线和其他需要共享信号线的应用。
Stm32 用IO口驱动8位液晶程序#include "stm32f10x.h"#include "ILI9320.h"int main(void){SystemInit();GPIO_Config();ILI9325_Initial(); //初始化LCD//delayms(100);//绘制矩形平面// Show_RGB(0,120,0,64,Blue2);// Show_RGB(120,240,0,64,Black);// Show_RGB(0,120,64,128,White);// Show_RGB(120,240,64,128,Blue);// Show_RGB(0,120,128,192,Red);// Show_RGB(120,240,128,192,Magenta);// Show_RGB(0,120,192,256,Green);// Show_RGB(120,240,192,256,Cyan);// Show_RGB(0,120,256,320,Yellow);// Show_RGB(120,240,256,320,Red);//// LCD_PutString(0,0,"专业电子论坛",White,Blue2); // LCD_PutString(0,16,"",White,Blue2); // LCD_PutString(0,32,"专业开发板",White,Blue2);// LCD_PutString(0,48,"浩豚电子科技",White,Blue2);while(1){CLR_Screen(Red); //用背景色清屏CLR_Screen(Yellow);CLR_Screen(Green);}}/*----------------------------------------------------------------320x240彩屏液晶驱动程序----------------------------------------------------------------*/#include"ILI9320.h"#include"stm32f10x.h"void GPIO_Config(){GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(LCD_GPIO_DATA_CLK|RCC_APB2Periph_GPIOA,ENABLE); GPIO_InitStructure.GPIO_Pin=LCD_GPIO_DATA_PIN;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(LCD_GPIO_DATA_PORT ,&GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4 ;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStructure);}/*----------------------------------------------------------------清屏函数输入参数:bColor 清屏所使用的背景色----------------------------------------------------------------*/void CLR_Screen(unsigned int bColor){unsigned int i,j;LCD_SetPos(0,239,0,319);//320x240for (i=0;i<320;i++){for (j=0;j<240;j++)Write_Data_U16(bColor);}}/*----------------------------------------------------------------显示英文字符输入参数:x 横坐标y 纵坐标c 需要显示的字符fColor 字符颜色bColor 字符背景颜色----------------------------------------------------------------*//*#include "8X16.h"void LCD_PutChar8x16(unsigned short x, unsigned short y, char c, unsigned int fColor, unsigned int bColor){unsigned int i,j;LCD_SetPos(x,x+8-1,y,y+16-1);for(i=0; i<16;i++) {unsigned char m=Font8x16[c*16+i];for(j=0;j<8;j++) {if((m&0x80)==0x80) {Write_Data_U16(fColor);}else {Write_Data_U16(bColor);}m<<=1;}}}*//*----------------------------------------------------------------显示英文字符输入参数:x 横坐标y 纵坐标c 需要显示的字符fColor 字符颜色bColor 字符背景颜色----------------------------------------------------------------*//*void LCD_PutChar(unsigned short x, unsigned short y, char c, unsigned int fColor, unsigned int bColor) {LCD_PutChar8x16( x, y, c, fColor, bColor );} *//*----------------------------------------------------------------显示汉字输入参数:x 横坐标y 纵坐标c 需要显示的汉字码fColor 字符颜色bColor 字符背景颜色----------------------------------------------------------------*//*#include "GB1616.h" //16*16汉字字模void PutGB1616(unsigned short x, unsigned short y, unsigned char c[2], unsigned int fColor,unsigned int bColor){unsigned int i,j,k;LCD_SetPos(x, x+16-1,y, y+16-1);for (k=0;k<64;k++) { //64标示自建汉字库中的个数,循环查询内码if ((codeGB_16[k].Index[0]==c[0])&&(codeGB_16[k].Index[1]==c[1])){for(i=0;i<32;i++) {unsigned short m=codeGB_16[k].Msk[i];for(j=0;j<8;j++) {if((m&0x80)==0x80) {Write_Data_U16(fColor);}else {Write_Data_U16(bColor);}m<<=1;}}}}} *//*----------------------------------------------------------------显示字符串可以中英文同时显示输入参数:x 横坐标y 纵坐标*s 需要显示的字符串fColor 字符颜色bColor 字符背景颜色----------------------------------------------------------------*//*void LCD_PutString(unsigned short x, unsigned short y, char *s, unsigned int fColor, unsigned int bColor){unsigned char l=0;while(*s) {if( *s < 0x80){LCD_PutChar(x+l*8,y,*s,fColor,bColor);s++;l++;}else{PutGB1616(x+l*8,y,(unsigned char*)s,fColor,bColor);s+=2;l+=2;}}}*//*----------------------------------------------------------------显示RGB颜色输入参数:x0,y0 起始坐标x1,y1 结束坐标Color 背景颜色----------------------------------------------------------------*//*void Show_RGB (unsigned int x0,unsigned int x1,unsigned int y0,unsigned int y1,unsigned int Color){unsigned int i,j;LCD_SetPos(x0,x1,y0,y1);//坐标for (i=y0;i<=y1;i++) //有两个for{for (j=x0;j<=x1;j++)Write_Data_U16(Color);//写颜色}}*//*----------------------------------------------------------------显示图片图片必须是320x240,否则不能正确识别----------------------------------------------------------------*//*void show_photo(void){unsigned char j;unsigned int i;unsigned long s=0;LCD_SetPos(0,240,0,320);//320x240for (i=0;i<75;i++){for (j=0;j<240;j++)Write_Data(0xff,0xff);}for (i=0;i<170;i++){for (j=0;j<55;j++)Write_Data(0xff,0xff);for (j=0;j<130;j++)Write_Data(pic[s++],pic[s++]);for (j=0;j<55;j++)Write_Data(0xff,0xff);}for (i=0;i<75;i++){for (j=0;j<240;j++)Write_Data(0xff,0xff);}}*//*----------------------------------------------------------------写命令、写数据输入参数:x 需要输入的命令16位y 需要输入的数据16位----------------------------------------------------------------*/ void Write_Cmd_Data (unsigned char x,unsigned int y) {Write_Cmd(x);//八位的命令Write_Data_U16(y);}/*----------------------------------------------------------------写16位数据----------------------------------------------------------------*/void Write_Data_U16(unsigned int y){unsigned char m,n;m=y>>8;n=y;Write_Data(m,n);}/*------------------------------------------------------------------------------ 写16位命令---------------------------------------------------------------------------------*/ void Write_Cmd(unsigned int y){unsigned char m,n;m=y>>8;n=y;Write_Cmd1(m,n);}/*----------------------------------------------------------------写命令(双八位)----------------------------------------------------------------*/void Write_Cmd1(unsigned char DH,unsigned char DL){LCD_CS_CLR;LCD_RS_CLR;LCD_RD_SET;LCD_RW_CLR;WriteData(DH);LCD_RW_SET;LCD_CS_SET;LCD_CS_CLR;LCD_RS_CLR;LCD_RD_SET;LCD_RW_CLR;WriteData(DL);LCD_RW_SET;LCD_CS_SET;}/*----------------------------------------------------------------写数据双8位----------------------------------------------------------------*/void Write_Data(unsigned char DH,unsigned char DL){LCD_CS_CLR;LCD_RS_SET;LCD_RW_CLR;LCD_RD_SET;WriteData(DH);LCD_CS_CLR;LCD_RW_SET;LCD_CS_CLR;LCD_RS_SET;LCD_RW_CLR;LCD_RD_SET;WriteData(DL);LCD_RW_SET;LCD_CS_SET;}/*----------------------------------------------------------------延时函数----------------------------------------------------------------*/void delay_us(int time) //延时微秒级函数{do{time--;}while(time>1);}void delayms(uint time) //延时毫秒级函数{while(time!=0){delay_us(1000); time--;}}/*----------------------------------------------------------------液晶初始化----------------------------------------------------------------*/void ILI9325_Initial(void){LCD_RS_SET;LCD_RW_SET;LCD_CS_SET;LCD_RES_SET;delayms(1);LCD_RES_CLR;delayms(10);LCD_RES_SET;delayms(50);Write_Cmd_Data(0x00E5, 0x8000); // Set internal timingWrite_Cmd_Data(0x0000, 0x0001); // 启动振荡Write_Cmd_Data(0x002b, 0x0010); // Set internal timingWrite_Cmd_Data(0x0001,0x0100);Write_Cmd_Data(0x0002,0x0700);Write_Cmd_Data(0x0003,0x1030);Write_Cmd_Data(0x0004,0x0000);Write_Cmd_Data(0x0008,0x0207);Write_Cmd_Data(0x0009,0x0000);Write_Cmd_Data(0x000A,0x0000);Write_Cmd_Data(0x000C,0x0000);Write_Cmd_Data(0x000D,0x0000);Write_Cmd_Data(0x000F,0x0000);//power on sequence VGHVGLWrite_Cmd_Data(0x0010,0x0000);Write_Cmd_Data(0x0011,0x0007);Write_Cmd_Data(0x0012,0x0000);Write_Cmd_Data(0x0013,0x0000);//vghWrite_Cmd_Data(0x0010,0x1290);Write_Cmd_Data(0x0011,0x0227);delayms(100);//vregioutWrite_Cmd_Data(0x0012,0x001d); //0x001b delayms(100);//vom amplitudeWrite_Cmd_Data(0x0013,0x1500); delayms(100);//vom HWrite_Cmd_Data(0x0029,0x0018);Write_Cmd_Data(0x002B,0x000D);//gammaWrite_Cmd_Data(0x0030,0x0004);Write_Cmd_Data(0x0031,0x0307);Write_Cmd_Data(0x0032,0x0002);// 0006 Write_Cmd_Data(0x0035,0x0206);Write_Cmd_Data(0x0036,0x0408);Write_Cmd_Data(0x0037,0x0507);Write_Cmd_Data(0x0038,0x0204);//0200 Write_Cmd_Data(0x0039,0x0707);Write_Cmd_Data(0x003C,0x0405);// 0504 Write_Cmd_Data(0x003D,0x0F02);//ramWrite_Cmd_Data(0x0050,0x0000);Write_Cmd_Data(0x0051,0x00EF);Write_Cmd_Data(0x0052,0x0000);Write_Cmd_Data(0x0053,0x013F);Write_Cmd_Data(0x0060,0xA700);Write_Cmd_Data(0x0061,0x0001);Write_Cmd_Data(0x006A,0x0000);//Write_Cmd_Data(0x0080,0x0000);Write_Cmd_Data(0x0081,0x0000);Write_Cmd_Data(0x0082,0x0000);Write_Cmd_Data(0x0083,0x0000);Write_Cmd_Data(0x0084,0x0000);Write_Cmd_Data(0x0085,0x0000);//Write_Cmd_Data(0x0090,0x0010);Write_Cmd_Data(0x0092,0x0600);Write_Cmd_Data(0x0093,0x0003);Write_Cmd_Data(0x0095,0x0110);Write_Cmd_Data(0x0097,0x0000);Write_Cmd_Data(0x0098,0x0000);Write_Cmd_Data(0x0007,0x0133);Write_Cmd_Data(0x0000,0x0022);//}/*----------------------------------------------------------------画点输入参数:x,y 需要画点坐标color 点的颜色----------------------------------------------------------------*//*void Put_pixel(uchar x,uchar y,unsigned int color){LCD_SetPos(x,x,y,y);Write_Data_U16(color);}*//*----------------------------------------------------------------设置坐标----------------------------------------------------------------*/static void LCD_SetPos(unsigned int x0,unsigned int x1,unsigned int y0,unsigned int y1) {Write_Cmd_Data(WINDOW_XADDR_START,x0);Write_Cmd_Data(WINDOW_XADDR_END,x1);Write_Cmd_Data(WINDOW_Y ADDR_START,y0);Write_Cmd_Data(WINDOW_Y ADDR_END,y1);Write_Cmd_Data(GRAM_XADDR,x0);Write_Cmd_Data(GRAM_Y ADDR,y0);Write_Cmd (0x0022);//LCD_WriteCMD(GRAMWR);}/*----------------------------------------------------------------在屏幕上画线输入参数:起始坐标X0,Y0,终止坐标X1,Y1color 线颜色----------------------------------------------------------------*//*void Line( uchar X0,uchar Y0,uchar X1,uchar Y1,unsigned int color){int dx = X1 - X0;int dy = Y1 - Y0;int P = 2 * dy - dx;int dobDy = 2 * dy;int dobD = 2 * (dy - dx);int PointX = 0,PointY = 0;int incx = 0,incy = 0;int distance = 0,xerr = 0,yerr = 0;unsigned int i = 0;if(dx == 0) //k=1斜率为1{PointX = X0;if(Y0 < Y1){PointY = Y0;}else{PointY = Y1;}for(i = 0;i <= ((Y0<Y1) ? (Y1-Y0) : (Y0-Y1));i++) {Put_pixel(PointX,PointY,color);PointY++;}return;}if(dy == 0) //k=0斜率为0{PointY = Y0;if(X0 < X1){PointX = X0;}else{PointX = X1;}for(i = 0;i <= ((X0<X1) ? (X1-X0) : (X0-X1));i++) {Put_pixel(PointX,PointY,color);PointX++;}return;}if(dx > 0)incx = 1;else if(dx == 0)incx = 0;elseincx = -1;if(dy > 0)incy = 1;else if(dy == 0)incy = 0;elseincy = -1;dx = ((X0>X1) ? (X0-X1) : (X1-X0));dy = ((Y0>Y1) ? (Y0-Y1) : (Y1-Y0));if(dx>dy) distance=dx;else distance=dy;PointX = X0;PointY = Y0;for(i=0;i<=distance+1;i++){Put_pixel(PointX,PointY,color);xerr+=dx;yerr+=dy;if(xerr>distance){xerr-=distance;PointX+=incx;}if(yerr>distance){yerr-=distance;PointY+=incy;}}}*//*---------------------------------------------------------------------------绘制矩形框输入参数:矩形的起始位置left,top矩形的结束位置right,bottom矩形框的颜色color-----------------------------------------------------------------------------*/ /*void Rectangle( uchar left,uchar top,uchar right,uchar bottom,unsigned int color){Line(left,top,right,top,color);Line(left,top,left,bottom,color);Line(right,top,right,bottom,color);Line(left,bottom,right,bottom,color);}*//*---------------------------------------------------------------------------绘制平面矩形输入参数:矩形的起始位置left,top矩形的结束位置right,bottom矩形框的颜色color-----------------------------------------------------------------------------*/ /*void Bar( uchar left,uchar top,uchar right,uchar bottom,unsigned int color){uchar i = 0,k = 0;for(k = top;k < bottom;k++){for(i = left+1;i <= right;i++){LCD_SetPos(i,i,k,k);Write_Data_U16(color);}}}*//*---------------------------------------------------------------------------向LCD发送一个0--255的数值-----------------------------------------------------------------------------*/ /*void LCDShow_uCharNumber( uchar x,uchar y,uchar uCharNumber,unsigned int forecolor,unsigned int bkcolor){LCD_PutChar(x,y,uCharNumber/100+'0',forecolor,bkcolor);LCD_PutChar(x+8,y,uCharNumber/10%10+'0',forecolor,bkcolor);LCD_PutChar(x+16,y,uCharNumber%10+'0',forecolor,bkcolor); }*/。
1、不使用库函数的IO口操作Systick 部分内容属于NVIC控制部分,一共有4个寄存器SysTick_CTRL, 0xE000E010 -- 控制寄存器默认值:0x0000 0004SysTick_LOAD, 0xE000E014 -- 重载寄存器默认值:0x0000 0000SysTick_VAL, 0xE000E018 -- 当前值寄存器默认值:0x0000 0000SysTick_CALIB, 0xE000E01C -- 校准值寄存器默认值:0x0002328SysTick_CTRL 寄存器内有4个bit具有意义第0位:ENABLE,Systick 使能位(0:关闭Systick功能;1:开启Systick功能)第1位:TICKINT,Systick 中断使能位(0:关闭Systick中断;1:开启Systick中断)第2位:CLKSOURCE,Systick时钟源选择(0:使用HCLK/8 作为Systick时钟;1:使用HCLK 作为系统时钟)第16位:COUNTFLAG,Systick计数比较标志IO口的位操作实现该部分代码实现对STM32各个IO口的位操作,包括读入和输出。
当然在这些函数调用之前,必须先进行IO口时钟的使能和IO口功能定义。
此部分仅仅对IO口进行输入输出读取和控制。
代码如下:#define BITBAND(addr,bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2))#define MEM_ADDR(addr) *((volatile unsigned long *)(addr))#define BIT_ADDR(addr,bitnum) MEM_ADDR(BITBAND(addr,bitnum))//IO口地址映射#define GPIOA_ODR_Addr (GPIOA_BASE+12) //0x4001080C#define GPIOB_ODR_Addr (GPIOB_BASE+12) //0x40010C0C#define GPIOC_ODR_Addr (GPIOC_BASE+12) //0x4001100C#define GPIOD_ODR_Addr (GPIOD_BASE+12) //0x4001140C#define GPIOE_ODR_Addr (GPIOE_BASE+12) //0x4001180C#define GPIOF_ODR_Addr (GPIOF_BASE+12) //0x40011A0C#define GPIOG_ODR_Addr (GPIOG_BASE+12) //0x40011E0C#define GPIOA_IDR_Addr (GPIOA_BASE+8) //0x40010808#define GPIOB_IDR_Addr (GPIOB_BASE+8) //0x40010C08#define GPIOC_IDR_Addr (GPIOC_BASE+8) //0x40011008#define GPIOD_IDR_Addr (GPIOD_BASE+8) //0x40011408#define GPIOE_IDR_Addr (GPIOE_BASE+8) //0x40011808#define GPIOF_IDR_Addr (GPIOF_BASE+8) //0x40011A08 55#define GPIOG_IDR_Addr (GPIOG_BASE+8) //0x40011E08//IO口操作,只对单一的IO口!//确保n的值小于16!#define PAout(n) BIT_ADDR(GPIOA_ODR_Addr,n) //输出#define PAin(n) BIT_ADDR(GPIOA_IDR_Addr,n) //输入#define PBout(n) BIT_ADDR(GPIOB_ODR_Addr,n) //输出#define PBin(n) BIT_ADDR(GPIOB_IDR_Addr,n) //输入#define PCout(n) BIT_ADDR(GPIOC_ODR_Addr,n) //输出#define PCin(n) BIT_ADDR(GPIOC_IDR_Addr,n) //输入#define PDout(n) BIT_ADDR(GPIOD_ODR_Addr,n) //输出#define PDin(n) BIT_ADDR(GPIOD_IDR_Addr,n) //输入#define PEout(n) BIT_ADDR(GPIOE_ODR_Addr,n) //输出#define PEin(n) BIT_ADDR(GPIOE_IDR_Addr,n) //输入#define PFout(n) BIT_ADDR(GPIOF_ODR_Addr,n) //输出#define PFin(n) BIT_ADDR(GPIOF_IDR_Addr,n) //输入#define PGout(n) BIT_ADDR(GPIOG_ODR_Addr,n) //输出#define PGin(n) BIT_ADDR(GPIOG_IDR_Addr,n) //输入以上代码的实现得益于CM3的位带操作,具体的实现比较复杂,请参考<<CM3权威指南>>第五章(87页~92页)。
有了上面的代码,我们就可以像51/A VR一样操作STM32的IO口了。
比如,我要PORTA的第七个IO口输出1,则可以使用PAout(6)=1;既可以实现。
我要判断PORTA的第15个位是否等于1,则可以使用if(PAin(14)==1)…;就可以了。
另种方式:(基本上做出来了)我的STM32板子PA0和PA1接的LED灯,所以先映射这两位。
查看手册中的寄存器组起始地址(原文件名:地址.jpg)引用图片GPIOA是 0x4001 0800GPIOD是0x4001 1400端口输出数据寄存器(GPIOx_ODR) 的偏移地址是 0x0c根据公式:别名区 = ADDRESS=0x4200 0000 + (0x0001 080C*0x20) + (bitx* 4) ;bitx:第x位得到PA.0和PA.1的别名区地址#define PA_Bit0 ((volatile unsigned long *) (0x42210180))#define PA_Bit1 ((volatile unsigned long *) (0x42210184))//42228180#define PD_Bit7 ((volatile unsigned long *) (0x4222819C))#define PD_Bit13 ((volatile unsigned long *) (0x422281CC))#define PD_Bit3 ((volatile unsigned long *) (0x4222818C))#define PD_Bit4 ((volatile unsigned long *) (0x42228190))接下来就可以对PA.0和PA.1进行位操作了*PA_Bit0 = 1; //PA.0 置1*PA_Bit1 = 0; //PA.1 置0还可以读出这一位的值:while(1){*PA_Bit1 =(~*PA_Bit1);Delay(1000); //延时1秒}PA.1接的LED会闪烁。
由于对STM32的存储结构不了解,0x4200 0000不知道是从哪里来的。
后来看到了一个PDF文档(原文件名:存储.jpg)引用图片原来0x4200 0000是外设别名区域的地址。
我也是刚刚学习STM32,有错误的地方请大家指点。
3、使用库函数,如下部分程序对IO的操作。
while(1){/* Turn on LD1 */GPIO_SetBits(GPIOD, GPIO_Pin_8);/* Insert delay */Delay(0xAFFFF);/* Turn on LD2 and LD3 */GPIO_SetBits(GPIOD, GPIO_Pin_9 | GPIO_Pin_10);/* Turn off LD1 */GPIO_ResetBits(GPIOD, GPIO_Pin_8);/* Insert delay */Delay(0xAFFFF);/* Turn on LD4 */GPIO_SetBits(GPIOD, GPIO_Pin_11);/* Turn off LD2 and LD3 */GPIO_ResetBits(GPIOD, GPIO_Pin_10 | GPIO_Pin_9);/* Insert delay */Delay(0xAFFFF);/* Turn off LD4 */GPIO_ResetBits(GPIOD, GPIO_Pin_11);}4、IO1PIN=(IO1PIN&0xff00ffff)|((Reg_Code&0xff)<<16);//将要写的数据先赋给单片机的16~23脚5、最小系统板上可以使用的普通IO口:A 0-150-10、12、13可作为一般的IO口使用,由于有第二功能,11、14、15管脚在普通IO口时会有不正常现象(比如设置成高电平输出时14电压几乎为0;设置成带上拉输入时11电压也很小(0.9左右),14电压几乎为0),在使用时应避免使用这些口B 0-15C 0-15D 0 1 2EFG6、IO口模式①模拟输入模式(GPIO_Mode_AIN)PA0,PA1,PA2,PA3,PA4,PA5,PA6,PA7,PB0,PB1,PC0, PC1, PC2,PC3,PC4,PC5可以设置成该模式,即这16个口可以用作AD输入②输入浮空模式(GPIO_Mode_IN_FLOATING)UART的输入引脚设置成该模式③带下拉输入(GPIO_Mode_IPD)④带上拉输入(GPIO_Mode_IPU)⑤开漏输出(GPIO_Mode_Out_OD)输出端相当于三极管的集电极. 要得到高电平状态需要上拉电阻才行. 适合于做电流型的驱动,其吸收电流的能力相对强(一般20ma以内).要实现线与需要用OC(open collector)门电路.是两个参数相同的三极管或MOSFET,以推挽方式存在于电路中,各负责正负半周的波形放大任务,电路工作时,两只对称的功率开关管每次只有一个导通,所以导通损耗小,效率高。
输出既可以向负载灌电流,也可以从负载抽取电流。