自己写库--构建库函数编程

1、GPIO寄存器映射代码的优化

这是GPIO寄存器的映射,看起来不多,但是如果你遇到的寄存器很多的情况下,你就需要写多行的这样的代码,那么有没有什么办法可以对这段代码进行优化呢? 

#define GPIOE_CRL	   *(unsigned int *)(GPIOE_BASE+0x00)
#define GPIOE_CRH      *(unsigned int *)(GPIOE_BASE+0x04)
#define GPIOE_IDR      *(unsigned int *)(GPIOE_BASE+0x08)
#define GPIOE_ODR      *(unsigned int *)(GPIOE_BASE+0x0C)
#define GPIOE_BSRR     *(unsigned int *)(GPIOE_BASE+0x10)
#define GPIOE_BRR      *(unsigned int *)(GPIOE_BASE+0x14)
#define GPIOE_LCKR     *(unsigned int *)(GPIOE_BASE+0x18)

 优化思路:采用结构体的方式。因为每个寄存器之间间隔了4个字节是有规律可寻的。通过指针来访问。相当于只需要知道这个寄存器的基地址就行。最后再通过强制类型转换成指针类型,通过操作指针来完成功能。

typedef unsigned int u32;
typedef unsigned short u16;
//代码优化
typedef struct
{
	u32 CRL;
	u32 CRH;
	u32 IDR;
	u32 ODR;
	u32 BSRR;
	u32 BRR;
	u32 LCKR;
}GPIO_TypeDef;

#define GPIOE ((GPIO_TypeDef*)GPIOE_BASE)
//库函数雏形
	RCC_APB2ENR |= (1<<6);
	GPIOE->CRL &=~(0x0F<<(4*5));
	GPIOE->CRL |= (3<<(5*4));
	GPIOE->ODR |= (1<<5);
	while(1)
	{
		GPIOE->ODR |= (1<<5);
		delay(0xFFFFF);
		GPIOE->ODR &= ~(1<<5);
		delay(0xFFFFF);
		
		
	}

 

2、RCC结构体 

//RCC
typedef struct
{
	u32 CR;
	u32 CFGR;
	u32 CIR;
	u32 APB2RSTR;
	u32 APB1RSTR;
	u32 AHBENR;
	u32 APB2ENR;
	u32 APB1ENR;
	u32 BDCR;
	u32 CSR;
}RCC_TypeDef;
#define RCC   ((RCC_TypeDef*)RCC_BASE)

3、端口置位和复位函数 

引脚定义 

#ifndef __STM32F10X_GPIO_H
#define __STM32F10X_GPIO_H

#include "stm32f10x.h"

//引脚宏定义
#define GPIO_Pin_0   ((u16)0x0001)
#define GPIO_Pin_1   ((u16)0x0002)
#define GPIO_Pin_2   ((u16)0x0004)
#define GPIO_Pin_3   ((u16)0x0008)
#define GPIO_Pin_4   ((u16)0x0010)
#define GPIO_Pin_5   ((u16)0x0020)
#define GPIO_Pin_6   ((u16)0x0040)
#define GPIO_Pin_7   ((u16)0x0080)

#define GPIO_Pin_8   ((u16)0x0100)
#define GPIO_Pin_9   ((u16)0x0200)
#define GPIO_Pin_10  ((u16)0x0400)
#define GPIO_Pin_11  ((u16)0x0800)
#define GPIO_Pin_12  ((u16)0x1000)
#define GPIO_Pin_13  ((u16)0x2000)
#define GPIO_Pin_14  ((u16)0x4000)
#define GPIO_Pin_15  ((u16)0x8000)
#define GPIO_Pin_All ((u16)0xFFFF)

void GPIO_SetBits(GPIO_TypeDef *GPIOx,u16 GPIO_PIN);
void GPIO_ReSetBits(GPIO_TypeDef *GPIOx,u16 GPIO_PIN);
#endif 

 置位和复位函数

#include "stm32f10x_gpio.h"

void GPIO_SetBits(GPIO_TypeDef *GPIOx,u16 GPIO_PIN)
{
	GPIOx->BSRR |= GPIO_PIN;
}

void GPIO_ReSetBits(GPIO_TypeDef *GPIOx,u16 GPIO_PIN)
{
	GPIOx->BRR |= GPIO_PIN;
}

函数实现 

//库函数雏形
	RCC->APB2ENR |= (1<<6);
	GPIOE->CRL &=~(0x0F<<(4*5));
	GPIOE->CRL |= (3<<(5*4));
	GPIO_SetBits(GPIOE,GPIO_Pin_5);
	while(1)
	{
		GPIO_SetBits(GPIOE,GPIO_Pin_5);
		delay(0xFFFFF);
		GPIO_ReSetBits(GPIOE,GPIO_Pin_5);
		delay(0xFFFFF);
		
	}

 

4、初始化结构体函数

 

void GPIO_Init(GPIO_TypeDef*GPIOx,GPIO_InitTypeDef* GPIO_Initstruct)
{
	u32 currentmode = 0x00,currentpin = 0x00,pinpos = 0x00,pos = 0x00;
	u32 tmpreg = 0x00,pinmask = 0x00;
	//读取GPIO的第四位模式
	currentmode = ((u32)GPIO_Initstruct->GPIO_Mode ) & ((u32)0x0F);
	//判断bit4是1还是0,1是输入,0是输出
	if((((u32)GPIO_Initstruct->GPIO_Mode) & ((u32)0x10)) != 0x00)
	{
		//输出模式,设置输出速度
		currentmode |= (u32)GPIO_Initstruct->GPIO_Speed;
	}
	
	//GPIO_CRL寄存器配置,低八位
	if(((u32)GPIO_Initstruct->GPIO_Pin &((u32)0x00FF))!=0x00)
	{
		//先备份CRL寄存器的值
		tmpreg = GPIOx->CRL;
		
		//循环,从Pin0开始配对,找出具体的Pin
		for(pinpos = 0x00;pinpos<0x08;pinpos++)
		{
			//将pos位pinpos左移一位
			pos = ((u32)0x01)<<pinpos;
			//将pos和GPIO_PIN相与
			currentpin = ((GPIO_Initstruct->GPIO_Pin)&pos);
			
			//如果pos == currentpin则找到pin
			if(currentpin == pos)
			{
				//pinpos的值左移两位(乘以4),因为寄存器中4个寄存器位置配置一个引脚
				pos = pinpos<<2;
				
				//把控制这个引脚的4个寄存器位清零,其他寄存器不变
				pinmask = ((u32)0x0F)<<pos;
				tmpreg &= ~pinmask;
				
				//向寄存器写入要配置的引脚的模式
				tmpreg  |= (currentmode<<pos);
				
				//判断是否位下拉输入模式
				if(GPIO_Initstruct->GPIO_Mode == GPIO_Mode_IPD)
				{
					//下拉模式,引脚置0
					GPIOx->BRR = (((u32)0x01)<<pinpos);
				}
				else
				{
					if(GPIO_Initstruct->GPIO_Mode == GPIO_Mode_IPU)
					{
						//上拉模式,引脚默认为1
						GPIOx->BSRR = (((u32)0x01)<<pinpos);
					}
				}
			}
		}
		//把前面暂存的值写入
		GPIOx->CRL = tmpreg;
	}
	
	//配置高八位
	if(GPIO_Initstruct->GPIO_Pin>0X00FF)
	{
		tmpreg = GPIOx->CRH;
		//循环,从pin8开始
		for(pinpos = 0x00;pinpos<0x08;pinpos++)
		{
			pos = ((u32)0x01)<<(pinpos+0x08);
			
			将pos和GPIO_PIN相与
			currentpin = ((GPIO_Initstruct->GPIO_Pin)&pos);
			
			//如果pos == currentpin则找到pin
			if(currentpin == pos)
			{
				//pinpos的值左移两位(乘以4),因为寄存器中4个寄存器位置配置一个引脚
				pos = pinpos<<2;
				
				//把控制这个引脚的4个寄存器位清零,其他寄存器不变
				pinmask = ((u32)0x0F)<<pos;
				tmpreg &= ~pinmask;
				
				//向寄存器写入要配置的引脚的模式
				tmpreg  |= (currentmode<<pos);
				
				//判断是否位下拉输入模式
				if(GPIO_Initstruct->GPIO_Mode == GPIO_Mode_IPD)
				{
					//下拉模式,引脚置0
					GPIOx->BRR = (((u32)0x01)<<(pinpos+0x08));
				}
				else
				{
					if(GPIO_Initstruct->GPIO_Mode == GPIO_Mode_IPU)
					{
						//上拉模式,引脚默认为1
						GPIOx->BSRR = (((u32)0x01)<<(pinpos+0x08));
					}
				}
			}
		}
		
		GPIOx->CRH = tmpreg;
	}
}

 

 修改后的代码

//库函数雏形
	RCC->APB2ENR |= (1<<6);
//	GPIOE->CRL &=~(0x0F<<(4*5));
//	GPIOE->CRL |= (3<<(5*4));
    GPIO_InitTypeDef GPIO_InitStruct;
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_5;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHZ;
	GPIO_Init(GPIOE,&GPIO_InitStruct);
	GPIO_SetBits(GPIOE,GPIO_Pin_5);
	while(1)
	{
		GPIO_SetBits(GPIOE,GPIO_Pin_5);
		delay(0xFFFFF);
		GPIO_ReSetBits(GPIOE,GPIO_Pin_5);
		delay(0xFFFFF);
		
	}
}

 5、提高代码的可移植性

可以将变量设置成宏定义,移植代码时就可以直接修改宏定义的部分。

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 松下FP-X0 L30R编程软件是用于松下FP-X0系列PLC(可编程逻辑控制器)的软件工具。该编程软件提供了一个用户友好的界面,使用户能够轻松地创建、编辑和测试PLC程序。它具有直观的图形化编程环境,使用户能够使用拖放功能来快速构建程序。此外,它还提供了丰富的代码库,包括各种常用功能块和代码片段,方便用户实现各种自定义功能。 松下FP-X0 L30R编程软件还具有强大的调试和监视功能。用户可以使用在线监视功能实时查看程序的运行情况,并进行实时调试和修改。此外,软件还提供了丰富的调试工具,如断点、单步执行等,帮助用户快速定位和修复程序中的错误。 该编程软件还支持多语言编程,用户可以根据自己的需求选择使用不同的编程语言来开发PLC程序,如基于结构化文本的编程语言(ST),或者图形化编程语言(FBD、LD)等。这使得程序的开发更加灵活和方便。 总的来说,松下FP-X0 L30R编程软件是一款功能强大、易于使用的软件工具,它提供了丰富的功能和工具,帮助用户轻松创建和调试PLC程序,实现各种自动化控制任务。 ### 回答2: 松下FP-X0 L30R是一款先进的PLC(可编程逻辑控制器)设备。为了对该设备进行编程,我们可以使用松下提供的编程软件。 松下FP-X0 L30R编程软件是一款功能强大且易于使用的工具,它可以帮助用户快速、高效地编写和调试PLC程序。该软件具有直观的用户界面,使得即使对于初学者来说也能轻松上手。通过该软件,用户可以创建、编辑和管理PLC程序,并对其进行调试和优化。 该编程软件支持多种编程语言,例如ladder diagram(梯形图)、instruction list(指令列表)和structured text(结构化文本),以满足不同用户的需求。用户可以根据自己的编程经验和熟悉程度选择合适的编程语言进行开发。 此外,松下FP-X0 L30R编程软件还提供了丰富的库函数和指令集,以支持用户完成各种常见的自动化任务。用户可以轻松地使用这些库函数和指令来实现数字逻辑、数据处理、通信和控制等功能。软件还具有实时监控和调试功能,可以帮助用户快速定位和解决程序中的问题。 总之,松下FP-X0 L30R编程软件是一款功能全面、易用性强的工具,可以帮助用户高效地编写和调试PLC程序,实现自动化控制任务。无论是初学者还是有经验的工程师,都可以通过该软件轻松地进行PLC编程

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值