历史上的今天
返回首页

历史上的今天

今天是:2024年10月19日(星期六)

正在发生

2021年10月19日 | stm32专题三:位带操作—GPIO输出和输入

2021-10-19 来源:eefocus

位带操作其实很简单,就是把位带区某寄存器的特定位,用公式给映射到位带别名区的32位地址上,该地址在编译器看来是个立即数,因此需要强制类型转换成32位地址指针,最后对指针取值操作。


特别值得注意的是,在强制类型转换成地址时,一定要加volatile关键词,不然一定会被编译器level-3优化掉,导致程序出错。博主一开始是直接使用(unsigned int *),然后在这里调试了很久,一直没发现问题所在,突然想到三级优化,加上volatile后程序正常执行。


以下是位带宏定义和输入—输出测试代码,


#include "stm32f10x.h"

#include "bsp_led.h"

#include "bsp_key.h"

 

/** 

  * @brief 位带操作

  * @cal   ((addr & 0xF0000000) + 0X02000000 + ((addr & 0x00FFFFFF) << 5) + ((bitnum) << 2))

  * @note  上述公式将位带区的寄存器addr第bitnum位,转化为位带别名区的一个32位地址

  * @attention 强制类型时一定要加volatile,不然会被level-3优化掉(ODR正常,IDR错误)

  */

 

// 位带输出

#define GPIOA_ODR_Addr (GPIOA_BASE + 0X0C)

#define GPIOB_ODR_Addr (GPIOB_BASE + 0X0C)

#define GPIOC_ODR_Addr (GPIOC_BASE + 0X0C)

#define GPIOD_ODR_Addr (GPIOD_BASE + 0X0C)

#define GPIOE_ODR_Addr (GPIOE_BASE + 0X0C)

#define GPIOF_ODR_Addr (GPIOF_BASE + 0X0C)

#define GPIOG_ODR_Addr (GPIOG_BASE + 0X0C)

 

#define PAout(n) *(volatile unsigned int *)((GPIOA_ODR_Addr & 0xF0000000) + 0X02000000 + ((GPIOA_ODR_Addr & 0x00FFFFFF) << 5) + ((n) << 2))

#define PBout(n) *(volatile unsigned int *)((GPIOB_ODR_Addr & 0xF0000000) + 0X02000000 + ((GPIOB_ODR_Addr & 0x00FFFFFF) << 5) + ((n) << 2))

#define PCout(n) *(volatile unsigned int *)((GPIOC_ODR_Addr & 0xF0000000) + 0X02000000 + ((GPIOC_ODR_Addr & 0x00FFFFFF) << 5) + ((n) << 2)) 

#define PDout(n) *(volatile unsigned int *)((GPIOD_ODR_Addr & 0xF0000000) + 0X02000000 + ((GPIOD_ODR_Addr & 0x00FFFFFF) << 5) + ((n) << 2))

#define PEout(n) *(volatile unsigned int *)((GPIOE_ODR_Addr & 0xF0000000) + 0X02000000 + ((GPIOE_ODR_Addr & 0x00FFFFFF) << 5) + ((n) << 2))

#define PFout(n) *(volatile unsigned int *)((GPIOF_ODR_Addr & 0xF0000000) + 0X02000000 + ((GPIOF_ODR_Addr & 0x00FFFFFF) << 5) + ((n) << 2))

#define PGout(n) *(volatile unsigned int *)((GPIOG_ODR_Addr & 0xF0000000) + 0X02000000 + ((GPIOG_ODR_Addr & 0x00FFFFFF) << 5) + ((n) << 2))

 

// 位带输入

#define GPIOA_IDR_Addr (GPIOA_BASE + 0X08)

#define GPIOB_IDR_Addr (GPIOB_BASE + 0X08)

#define GPIOC_IDR_Addr (GPIOC_BASE + 0X08)

#define GPIOD_IDR_Addr (GPIOD_BASE + 0X08)

#define GPIOE_IDR_Addr (GPIOE_BASE + 0X08)

#define GPIOF_IDR_Addr (GPIOF_BASE + 0X08)

#define GPIOG_IDR_Addr (GPIOG_BASE + 0X08)

 

#define PAin(n) *(volatile unsigned int *)((GPIOA_IDR_Addr & 0xF0000000) + 0X02000000 + ((GPIOA_IDR_Addr & 0x00FFFFFF) << 5) + ((n) << 2))

#define PBin(n) *(volatile unsigned int *)((GPIOB_IDR_Addr & 0xF0000000) + 0X02000000 + ((GPIOB_IDR_Addr & 0x00FFFFFF) << 5) + ((n) << 2))

#define PCin(n) *(volatile unsigned int *)((GPIOC_IDR_Addr & 0xF0000000) + 0X02000000 + ((GPIOC_IDR_Addr & 0x00FFFFFF) << 5) + ((n) << 2))

#define PDin(n) *(volatile unsigned int *)((GPIOD_IDR_Addr & 0xF0000000) + 0X02000000 + ((GPIOD_IDR_Addr & 0x00FFFFFF) << 5) + ((n) << 2))

#define PEin(n) *(volatile unsigned int *)((GPIOE_IDR_Addr & 0xF0000000) + 0X02000000 + ((GPIOE_IDR_Addr & 0x00FFFFFF) << 5) + ((n) << 2))

#define PFin(n) *(volatile unsigned int *)((GPIOF_IDR_Addr & 0xF0000000) + 0X02000000 + ((GPIOF_IDR_Addr & 0x00FFFFFF) << 5) + ((n) << 2))

#define PGin(n) *(volatile unsigned int *)((GPIOG_IDR_Addr & 0xF0000000) + 0X02000000 + ((GPIOG_IDR_Addr & 0x00FFFFFF) << 5) + ((n) << 2))

 

 

void delay(uint32_t count);

 

int main(void)

{

LED_GPIO_Config();

KEY_GPIO_Config();

 

#if 0

while (1)

{

// 位带输出测试

PBout(1) = 1;

delay(0XFFFFF);

PBout(1) = 0;

delay(0XFFFFF);

}

#else

while (1)

{

// 位带输入测试

if (PAin(0) == KEY_ON)

{

while (PAin(0) == KEY_ON);

LED_B_OFF;

LED_R_TOGGLE;

}

if (PCin(13) == KEY_ON)

{

while (PCin(13) == KEY_ON);

LED_R_OFF;

LED_B_TOGGLE;

}

}

#endif

}

 

void delay(uint32_t count)

{

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

}


推荐阅读

史海拾趣

ANADIGICS公司的发展小趣事

ANADIGICS是一家曾经存在的半导体公司,总部位于美国新泽西州的华兹堡市。以下是ANADIGICS公司发展的相关故事:

  1. 创立与初期发展:ANADIGICS公司成立于1985年,最初专注于开发射频(RF)集成电路和功率放大器。公司在其创始人的领导下迅速崛起,以其创新的技术和产品在无线通信领域赢得了声誉。

  2. 产品创新与市场占有率提升:ANADIGICS公司在其创立初期就致力于开发高性能的射频和功率放大器产品。随着移动通信技术的迅速发展,ANADIGICS的产品得到了广泛应用,其在市场上的份额逐渐增加。

  3. 全球扩张与市场渗透:ANADIGICS公司通过建立全球性的销售渠道和生产基地,扩大了其产品的市场覆盖范围。公司在美国、欧洲和亚洲等地设立了销售办事处和生产工厂,加强了与客户的联系,并提高了产品的交付效率。

  4. 技术领先地位与合作伙伴关系:ANADIGICS公司不断投入研发,保持技术领先地位。公司与各大手机制造商和无线通信设备供应商建立了合作伙伴关系,共同推动技术创新和产品发展。

  5. 挑战与破产:然而,随着市场竞争的加剧和技术变革的不断推进,ANADIGICS公司在市场上的地位逐渐受到挑战。公司陷入了财务困境,于2016年申请破产保护,并逐步停止了业务。最终,ANADIGICS公司在同年被日本半导体公司II-VI收购,结束了其独立运营的历史。

以上是ANADIGICS公司发展的一些主要故事,展示了该公司从创立到破产的发展历程。

Apex [Apex Microtechnology]公司的发展小趣事

2007年,Apex Microtechnology迎来了一个重要的发展机遇,被音频和能源市场上领先的混合信号处理元件供应商Cirrus Logic收购。此后,Apex Microtechnology作为Cirrus Logic在德克萨斯州奥斯汀的一个分公司,继续从事复杂芯片设计与开发。这次收购为Apex Microtechnology带来了更多的资源和支持,推动了其在电子行业的进一步发展。

Gems Sensors & Controls公司的发展小趣事

随着技术的不断积累和市场的不断拓展,Gems Sensors & Controls公司成功加盟了全球知名的世界500强企业丹纳赫集团。这一举措不仅为公司带来了更多的资源和支持,也加速了Gems的全球化布局。如今,Gems的生产基地遍布北美、欧洲和亚洲,并在全球范围内设立了销售、设计和服务办事处,能够为客户提供更加全面和便捷的服务。

Grande Electronics Ltd公司的发展小趣事
定期清洁遥控器表面的灰尘和污垢,避免按键接触不良等问题。
DRS Technologies公司的发展小趣事

DRS Technologies公司成立于1968年,由Leonard Newman和David Gross两位工程师共同创立。当时,他们正在Loral Corporation研究反潜战的信号处理技术。然而,当Loral决定转向其他技术方向时,Newman和Gross决定继续他们的研究,并创立了DRS。他们的努力最终导致了AN/SQR-17无源潜艇探测系统的开发,这一系统至今仍在广泛使用。

CR Magnetics公司的发展小趣事

为了更好地服务全球客户,CR Magnetics积极在全球范围内拓展业务。公司在东亚、欧洲和美洲等地设立了制造和销售办事处,以便更快速地响应市场需求和提供更好的服务。同时,公司还与国际知名厂商建立了合作关系,共同推动电子行业的发展。

问答坊 | AI 解惑

新手遇到的问题

这几天我有重新再论坛里瞎转悠了,发现以前很好很老的帖子有浮出水面了,但是当我看到下面好几十楼的回复我蒙了,我不知道里面是否有别人回复的资料,所以我就一口气翻了几十楼。这一点感觉很不方便,希望管理员可以吧那些精华和置顶的帖子里的较好 ...…

查看全部问答>

RFIC和RFID 完全不同吧?

百度的答案,还请大家深入说说: RFIC是RF System 里的Block做成IC ,,基本上成品就是IC ; 而RFID是Radio-frequency identification 是一个系统,有特定的规范。 二者是否有确定的包含与被包含的关系呢?…

查看全部问答>

欢迎s3c6410爱好者加入超级群67958848

欢迎s3c6410爱好者加入超级群67958848…

查看全部问答>

I2C_IOControl 传一个数组出来,老不成功,郁闷死了

BOOL I2C_IOControl(         DWORD context, DWORD code, BYTE *pInBuffer, DWORD inSize, BYTE *pOutBuffer,         DWORD outSize, DWORD *pOutSize ) 里面定义了一个BYTE *str;然后给他空间,也 ...…

查看全部问答>

CE5.0支持MIDI吗?

CE5.0支持MIDI吗?。。。。。…

查看全部问答>

访问允许异常(section permission fault)

Hi,Dear all, 我在使用Hms30c7202过程中遇到一个难题,我使用的内核是2.6.13.4,大多数能够正常启动运行,个别出现不能启动情况。打印DEBUG信息,非正常设备启动失败,打印: Kernel panic - not syncing: No init found.  Try passi ...…

查看全部问答>

安装CE6的SP1出错toolMsmCA(Error):Setup package issue or CoreCon。。。

安装CE6的SP1是出错 “ToolMsmCA(Error):Setup package issue or CoreCon DataStore corrupted:CDeviceSDKInstallShin Add/Remove failed.HR=0x80004005. 我之前装了VS2005。 这几天才装这个,不知怎么出错,安装进度停在Installing the Gene ...…

查看全部问答>

DDK下重载new/delete的问题

各位,最近在开发一个驱动的时候需要检测内存泄漏,于是自己重载了new/delete,在win32下测了一下没问题,于是决定将其加入到当前的驱动下。可是,问题来了,总是出现LNK2005的错误,我查了一下这个错,应该是连接顺序的问题,出错信息显示在DDK中 ...…

查看全部问答>

STM32F207的固件库有没有出来?

                                 在ST网站上资料很少, 找不到固件库…

查看全部问答>

ASM eagle60 W/B BSOB

近来老板搞了点垃圾产品,在生产时用的是BSOB,但第二点不是翘线就是打不上,很多参数都用过了,不知还有哪里没想到的。求教怎样可以使ASM eagle60 W/B 的BSOB达到最佳。…

查看全部问答>