STM32 学习10 位绑定

一、概念

位绑定通俗地说,就把对寄存器某一位的操作,映射到某个内存地址(只有最低位有效)。

M3都是按32位整体处理的,并没有单独对一个位进行操作,通过位绑定就可以实现CPU对单独一个位进行操作,只需要一个指令周期,代码效率高、速度快,更改的时候不需要多读一次寄存器。

M3内核并没有全部允许位绑定,只有两个区有,分别为:

SARM区:0x2000_0000‐0x200F_FFFF  这个SRAM绑定的地址就是从0x2200 0000开始,共1M。   

片上外设区:0x4000_0000‐0x400F_FFFF  这个区绑定的地址就是从0x4200 0000开始的,共1M。

二、计算公式

SRAM区映射的地址

AliasADDr = 0x22000000 + ((A - 0x20000000) * 8 + n) * 4 = 0x22000000 + ((A - 0x20000000) * 32 + n * 4   ,  n=0~7

片上外设区映射的地址

AliasADDr = 0x42000000 + ((A - 0x20000000) * 8 + n) * 4= 0x42000000 + ((A - 0x20000000) * 32 + n * 4

三、示例:

基本计算示例:

#include "stm32f10x_map.h"
#define PA0  GPIOA->BRR 
#define PA1	 GPIOA->BSRR 
int main()
{
	u32 *PAO3 = (u32 *)(0x42000000 + (0x4001080c-0x40000000)*32 + 3*4);	   //内存地址定义一个指针,PA端口输出 第3位
	u32 *PAI11 = (u32 *)(0x42000000 + (0x40010808-0x40000000)*32 + 11*4);	   //绑定PA输入 第11个端口</span>

   //配置 	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(*PAI11==1)  *PAO3 = 1; else *PAO3 = 0;
		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);
}

定义宏示例:

 
#include "stm32f10x_map.h"
#define PA0  GPIOA->BRR 
#define PA1	 GPIOA->BSRR 

#define GPIOA_ODR_A  (GPIOA_BASE+0x0c)
#define GPIOA_IDR_A  (GPIOA_BASE+0x08)
#define GPIOB_ODR_A  (GPIOB_BASE+0x0c)
#define GPIOB_IDR_A  (GPIOB_BASE+0x08)
#define GPIOC_ODR_A  (GPIOC_BASE+0x0c)
#define GPIOC_IDR_A  (GPIOC_BASE+0x08)
#define GPIOD_ODR_A  (GPIOD_BASE+0x0c)
#define GPIOD_IDR_A  (GPIOD_BASE+0x08)
#define GPIOE_ODR_A  (GPIOE_BASE+0x0c)
#define GPIOE_IDR_A  (GPIOE_BASE+0x08)

#define BitBind(Addr,BitNum)    *((volatile unsigned long *)((Addr&0xF0000000)+0x2000000+((Addr&0xfffff)<<5)+(BitNum<<2)))

#define PAout(n)  BitBind(GPIOA_ODR_A,n) //某位输出
#define PAin(n)   BitBind(GPIOA_IDR_A,n)  //某位输入
#define PBout(n)  BitBind(GPIOB_ODR_A,n) 
#define PBin(n)   BitBind(GPIOB_IDR_A,n) 
#define PCout(n)  BitBind(GPIOC_ODR_A,n) 
#define PCin(n)   BitBind(GPIOC_IDR_A,n)  
#define PDout(n)  BitBind(GPIOD_ODR_A,n) 
#define PDin(n)   BitBind(GPIOD_IDR_A,n)
#define PEout(n)  BitBind(GPIOE_ODR_A,n) 
#define PEin(n)   BitBind(GPIOE_IDR_A,n) 
int main()
{
	u32 *PAO3 = (u32 *)(0x42000000 + (0x4001080c-0x40000000)*32 + 3*4);	   		//内存地址定义一个指针,PA端口输出 第3位
	u32 *PAI11 = (u32 *)(0x42000000 + (0x40010808-0x40000000)*32 + 11*4);		//绑定PA输入 第11个端口

   //配置 	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;  //简单宏方式
		if((GPIOA->IDR & 0x0200)==0x0200)  PA1 = 0x02; else PA0 = 0x02;
		if((GPIOA->IDR & 0x0400)==0x0400)  PA1 = 0x04; else PA0 = 0x04;
		if(*PAI11==1)  *PAO3 = 1; else *PAO3 = 0;  //指针方式
		if(PAin(12)==1)  PAout(4)=1; else PAout(4)=0;   //宏 位绑定
		if(PAin(13)==1)  PAout(5)=1; else PAout(5)=0;
		if(PAin(14)==1)  PAout(6)=1; else PAout(6)=0;
		if(PAin(15)==1)  PAout(7)=1; else PAout(7)=0;
  }
   return(1);
}

 
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
# 毕业设计——基于STM32的室内空气监控系统设计与实现 ### 摘要 基于STM32的室内空气监控系统是由STM32F103C8T6单片机,多种传感器组成的智能监控系统。通过嵌入式相关技术、WiFi通信、MQTT协议开发设备端,以OneNET云平台作为服务器,基于微信小程序开发用户端,实现本智能监控系统。本系统可持续监测室内的温湿度、可燃气体、PM2.5等空气参数,并将采集数据通过OLED显示屏展示。同时,所采集数据通过MQTT协议上传OneNET云平台下的MQTT服务器。用户可通过微信小程序查看设备端空气参数数据和设备状态,以及远程控制设备端的警报器和通风机,方便用户及时获得室内空气质量状况并进行干预以解决潜在危险。本系统设计通过运行和调试,可以稳定地进行室内空气监控,并实现数据可视化,具有一定的应用价值和市场前景。 ### 关键词:STM32F103C8T6;室内空气监控系统;室内空气监测系统 ### 具体功能 (1)设备端通过传感器采集室内空气参数数据,包括温湿度、可燃气体浓度、PM2.5浓度。当任一种采集到的空气参数数据超过设置的安全值时,系统将进行报警通知用户,同时打开通风机进行通风。设备端默认为自动报警模式,用户可在设备端按下按键切换为手动报警模式,经过10秒后会再次切换为自动报警模式。 (2)传感器采集的空气参数数据实时更新并显示在OLED显示屏上。 (3)设备端具有三个控制按键,按键一为警报器开关,按键二为通风机开关,按键三可以切换通风机的模式,即控制向外排风模式和向内送风模式的切换。 (4)设备端通过WIFI通信模块接入网络,利用MQTT协议将数据上传至OneNET云平台多协议接入服务下的MQTT服务器,OneNET云平台的服务器的数据存储有效期为一个月。用户端微信小程序可通过API接口从该服务器中获取数据,获取得到的JSON格式数据经过解析处理后渲染到小程序页面,实时显示室内空气参数数据和硬件设备状态。 (5)用户可以通过微信小程序的开关组件,下发控制命令至OneNET云平台的MQTT服务器,经过该服务器发布订阅,设备端接收到订阅后,经解析得到控制信息,并执行相应的操作,包括警报器的开启关闭和通风机的开启关闭、正转反转。 (6)在微信小程序的服务页面中,用户可以根据个人生活习惯在系统提供的安全值范围中选择合适的值,并下发给设备端作为报警阈值。可使用系统默认的安全值设置。 (7)用户注册微信小程序账号时,需要填写用户名、手机号码和密码,同时可以绑定设备端的唯一设备号。,绑定设备号为非强制动作,用户可以在登录后,再进行绑定设备号或者修改设备号以绑定新设备。绑定了同一设备号的微信小程序用户会被视为设备共享人。 (8)用户端微信小程序会获取用户所在地理信息,通过API接口获取和风天气的城市天气服务,显示包括今日天气、气温、相对湿度、风向、风力、风速、当前小时降水量、大气压强、能见度的天气信息。 (9)用户端微信小程序的每一个空气参数的功能页面中,会默认显示当日数据折线图,折线图绘制信息为当日的最大值和平均值。用户可以在日历组件选择日期查看指定历史数据,同样会绘制数据折线图。同时在该页面中,会默认显示当日和当前小时的空气参数数据最大值和平均值,点击折线图可以查询得到某一小时的最大值和平均值。 (10)用户可以在微信小程序的消息通知页面查看最近十条间隔一分钟以上的报警信息,信息包括报警日期时间,空气参数数据和设备状态。 ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

编程圈子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值