OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 2007|回复: 4

自定义通用函数库(不同单片机用相同的指令)

[复制链接]

2

主题

66

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
204
金钱
204
注册时间
2017-8-20
在线时间
49 小时
发表于 2018-9-5 21:27:36 | 显示全部楼层 |阅读模式
在实际工作中,企业会频繁变换单片机,实现自定义函数库,能对不同的单片机及编译环境实现自简化易记,使用条件汇编,程序碰见不同的MCU会调用不同的函数体,我就以端口初始化为例说明这样做的优势!
#if defined API_STM32
//SN:CT-API800083  API_port_mode_init
/*
VI_parameter: 1:[port_pin]        PA1-PH15
VI_parameter: 2:[mode]            IN_AN/IN_FL/IN_PD/IN_PU/OUT_OD/OUT_PP/AF_OD/AF_PP
VI_parameter: 3:[level]           1 0
VI_parameter: 4:[speed]           2/10/50/0(default)
VI_parameter: 5:[locl]            1 0
VI_parameter: 6:[GPIOx_RCC_EN]    1 0
return        NC
Desiger:      LSL
DATA:         2018-03-05
*/
void API_port_mode_init(u16 port_pin,u8 mode,u8 level,u8 speed,u8 lock,u8 GPIOx_RCC_EN)
{

u8 port;
u8 pin;
port = (u8)(port_pin>>8);
pin = (u8)port_pin;
//开启或关闭端口时钟设置
    if(GPIOx_RCC_EN != 0)
{
  RCC->APB2ENR |= (0X02<<port);
}
else
{
  RCC->APB2ENR &= (~(0X02<<port));
  return;
}

//端口电平与上下拉设置.
if(mode==IN_PU || level!=0)
{
  *(u32*)((GPIOA_BASE+((port-1)<<10))+0x0C) |= pin;
}
    else
    {
  *(u32*)((GPIOA_BASE+((port-1)<<10))+0x0C) &= ~pin;
}

//端口模式设置
u32 CNFx_MODEy = 0x0000; //2-3位放CNFx,0-1位放MODEy
if(!(mode>>8))
{
  switch(speed)
  {
   case 2:  CNFx_MODEy = 0x02;break;
   case 10: CNFx_MODEy = 0x01;break;
   case 50: CNFx_MODEy = 0x03;break;
   default: CNFx_MODEy = 0x01;break;//默认10M输出
  }
}
    switch(mode)  
{
  case IN_AN:  
  case OUT_PP: break;         
  case IN_FL:  
  case OUT_OD: CNFx_MODEy += 0x04;break;         
  case IN_PU:  
  case IN_PD:  
  case AF_PP:  CNFx_MODEy += 0x08;break;
  case AF_OD:  CNFx_MODEy += 0x0C;break;
}
//pin SYS
u32 CRL_CRH;
if(pin<0x08)
{
  CRL_CRH = 0x00;
}
else // >= 0x0100
{
  CRL_CRH = 0x04;
  pin -= 8;
}
for(u8 i=0;i<8;i++)
{
  if((pin & 0x01) == 1)
  {
   CNFx_MODEy +=(CNFx_MODEy<<(i*4));
   pin >>= 1;
  }
}
*(u32*)((GPIOA_BASE+((port-1)<<10))+CRL_CRH) = ((*(u32*)((GPIOA_BASE+((port-1)<<10))+CRL_CRH) & (~(0x0F<<(pin*4)))) | (CNFx_MODEy <<= pin*4));   
}
#endif

不同MCU在公共define中定义如下
//SN:CT-D000501  PORTx_PINx               
#define PA0  0x0100
#define PA1  0x0101
#define PA2  0x0102
#define PA3  0x0103
#define PA4  0x0104
#define PA5  0x0105
#define PA6  0x0106
#define PA7  0x0107
#define PA8  0x0108
#define PA9  0x0109
#define PA10 0x010A
#define PA11 0x010B
#define PA12 0x010C
#define PA13 0x010D
#define PA14 0x010E
#define PA15 0x010F
#define PB0  0x0200
#define PB1  0x0201
......................
#define PH15 0x080F

//SN:CT-D005002  GPIP MODE
/*
mode            IN_AN    IN_FL    IN_PD       IN_PU       OUT_OD         OUT_PP        AF_OD       AF_PP   
*/
#define IN_AN       0x10   //模拟输入                                         
#define IN_FL       0x20   //浮空输入
#define IN_PD       0x30   //下拉输入
#define IN_PU  0x40   //上拉输入
#define OUT_OD  0x01   //开漏输出
#define OUT_PP  0x02   //推挽输出
#define AF_OD  0x03   //复用开漏输出
#define AF_PP  0x04   //复用推挽输出



正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

2

主题

66

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
204
金钱
204
注册时间
2017-8-20
在线时间
49 小时
 楼主| 发表于 2018-9-5 21:31:36 | 显示全部楼层
使用时  #define API_STM32  1  //MCU选择

API_port_mode_init(PD2,OUT_PP,1,50,0,1);
关键的是不同的单片机也用这命令,有的单片机后面不带的功能,也可传进区,函数体内忽略
当然AD DA SPI 中断也改自定义函数,编程极快又不易出问题
回复 支持 反对

使用道具 举报

2

主题

66

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
204
金钱
204
注册时间
2017-8-20
在线时间
49 小时
 楼主| 发表于 2018-9-5 21:36:41 | 显示全部楼层
中技电子实验室 发表于 2018-9-5 21:31
使用时  #define API_STM32  1  //MCU选择

API_port_mode_init(PD2,OUT_PP,1,50,0,1);

PWM只需传入总脉宽和高电平时间,函数自己能根据不同MCU处理
更离谱的是 int main(void) 有的单片机不支持 要void main(void),我们也定义了
API_main()   碰见不同的MCU自己会去选择int或void类型
回复 支持 反对

使用道具 举报

2

主题

66

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
204
金钱
204
注册时间
2017-8-20
在线时间
49 小时
 楼主| 发表于 2018-9-5 21:43:53 | 显示全部楼层
中技电子实验室 发表于 2018-9-5 21:36
PWM只需传入总脉宽和高电平时间,函数自己能根据不同MCU处理
更离谱的是 int main(void) 有的单片机不支 ...

//SN:CT-API800083  API_port_mode_init
/*
VI_parameter: 1:[port_pin]        PA1-PH15
VI_parameter: 2:[mode]            IN_AN/IN_FL/IN_PD/IN_PU/OUT_OD/OUT_PP/AF_OD/AF_PP
VI_parameter: 3:[level]           1 0
VI_parameter: 4:[speed]           2/10/50/0(default)
VI_parameter: 5:[locl]            1 0
VI_parameter: 6:[GPIOx_RCC_EN]    1 0
return        NC
Desiger:      LSL
DATA:         2018-03-05
*/
回复 支持 反对

使用道具 举报

2

主题

66

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
204
金钱
204
注册时间
2017-8-20
在线时间
49 小时
 楼主| 发表于 2018-9-5 21:48:34 | 显示全部楼层
中技电子实验室 发表于 2018-9-5 21:43
//SN:CT-API800083  API_port_mode_init
/*
VI_parameter: 1:        PA1-PH15

第1个参数传端口                        PD2
第2个参数传端口模式                   OUT_PP
第3个参数传端口初始化电平          1
第4个参数传端口速度                    50
第5个参数传锁定端口                     0
第6个参数开启/关闭GPIOx时钟       1
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-19 10:39

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表