4.19 X9C103S 电位器模块(来自彭宏喜的贡献)
4.19.1 模块来源
采购链接: https://detail.tmall.com/item.htm?id=597981969263&spm=a1z0d.6639537/tb.1997196601.14.59b97484no0kbK
资料下载: https://pan.baidu.com/s/1yOOysOmXCJhcUsq7jDaFdw?pwd=HXDZ 提取码:HXDZ
4.19.2 规格参数
工作电压:3V~5V
额定功率:1mW
工作电流:3mA(最大)
滑动端电流:1mA(最大)
滑动端电阻:40Ω(1mA 时)
端点间电阻误差:±20%
电阻分辨率:1%
噪声:1%<-120dB/Hz(基准为 1V)
4.19.3 模块原理
(注:文章中引脚的名称仅为简写,实际引脚以 X9C103S 规格书/图 3.1 X9C103 引脚图为准)
目前数字电位器阻值的变化均是阶梯式或增量式,台阶数抽头数越多,则阻值变化就愈小,调节的灵敏度就愈高。但是台阶数愈多,内部开关管和电路越复杂,价格也随之提高。因此,在选择数字电位器时,一定要在台阶数和价格之间作出权衡。
X9C103 是 100 阶数字电位器,也是 X9C102/103/104/503 系列中的一种型号,它的电阻范围为 40Ω~10KΩ,X9C103 片内包含有 99 个电阻单元的电阻阵列,在每个单元之间和二个端点都有被滑动单元访问的抽头点。滑动单元的位置由 CS、U_D 和 INC 个输人端控制,一旦位置选定后,可存放在非易失性存贮器中,因而在下次上电时可重新调用。
X9C103 引脚图如图 3.1 所示。
图 X9C103 引脚图
X9C103 引脚功能如表 3.1 所示。
表 X9C103 引脚功能
| 引脚 | 名称 | 功能 |
|---|---|---|
| 1 | “增加/减小”输入脚。INC引脚是负边沿触发,触发INC将使滑动端向计数器增加或减小的方向移动,移动的方向由U_D的逻辑电平决定。 | |
| 2 | 升/降输入端。U_D输入控制滑动端移动的方向,因而控制计数器是增加或是减小。 | |
| 3 | 高电压端及低电压端。X9C103的高和低电压端等效于一个机械电位器的固定端。其最小电压是-5V,而最大电压是+5V。需要注意的其只是规定了升/降输入端选择的关于滑动端滑动方向的相对位置,而并不是端点上的电压。 | |
| 4 | 地 | |
| 5 | 滑动端。V_W相当于机械电位器的可移动端,滑动端在电阻阵列中的位置由控制输入端决定,滑动端的串联电阻值典型是40Ω。 | |
| 6 | (此处功能描述同引脚3的V_H部分) | |
| 7 | 片选输入端。当CS输入端为低时器件被选中,当CS变为高,且INC输入端也为高时,当前计数器的值被存储在非易失性存储器中,当存储操作完成后,X9C103将处于低功耗的等待方式,直到器件再次被选中。 | |
| 8 | 电源电压 |
X9C103 内部功能图如图 1.2 所示。该电路由输入控制、计数器和译码器、非易失存贮器及电阻阵列三部分组成。输入控制部分类似一个可逆计数器计数器的输出被译码后就接通一个单接点的电子开关从而把电阻阵列上的一个点连接到滑动输出端。在某种条件下,计数器的内容可以存贮到非易失性存贮器中,以便今后调用。电阻阵列中包含 99 个单独的电阻,它们以串联的形式连接。在两个端点(V_H 和 V_L)和每个电阻之间有一个电子开关,它能把该点的电位传输到滑动端。
INC、U_D 和 CS 三个输入引脚能控制滑动端在电阻阵列中移动的位置,当 CS 为电平时,则 X9C103 被选中。这时 INC 和 U_D 输入引脚才能接收信号,当 INC 输入引脚由高到低变化可能增加或减小一个 7 位计数器的值,这主要决定 U_D 输入引脚的电平,当 U_D 为高电平,计数器的值增加;当 U_D 为低电平,计数器的值减小,7 位可逆计时器输出译码后,立即进行一百选一的操作,从而使滑动端的位置沿着电阻阵列移动,当滑动端位于一个固定点时,就像等效的机械滑动端那样,不会移到超出终端位置,即计数器达到一个极限端(0000000 或 1111111)时,不会循环回复。
图 X9C103 内部功能图
当 CS 和 INC 同时为高电平时,计数器的值被存储到非易失性存储器中,当 X9C103 断电,最后存储在计数器的值仍然维持在非易失性存储器中,当电源恢复后,存储器中的内容就是断电时计数器的值。
X9C103 工作时序如图 3.3 所示,INC、CS 和 U_D 三个输入引脚的电平决定工作方式的选择,具体情况如表 3.2 所示。
图 X9C103 工作时序图
表 方式选择
| 方式 | |||
|---|---|---|---|
| 低电平 | ↓ | 高电平 | 向上滑动 |
| 低电平 | ↓ | 低电平 | 向下滑动 |
| ↑ | 高电平 | 高电平或低电平 | 存储滑动端位置 |
| 高电平 | 高电平或低电平 | 高电平或低电平 | 等待电流 |
| ↑ | 低电平 | 高电平或低电平 | 不存储,放回等待 |
4.19.4 移植工程
讲解移植到立创梁山派的大致步骤,并基于该模块移植的代码实现什么功能。
4.19.5 引脚选择
| X9C103 | 立创·梁山派 |
|---|---|
| VCC | 5V |
| CS | PA4 |
| INC | PA2 |
| U_D | PA3 |
| GND | GND |
| VH | 5V |
| VL | GND |
| KEY_UP | PA0 |
| KEY_DOWN | PA1 |
4.19.6 移植步骤
移植步骤中的导入.c 和.h 文件与上一节相同,只是将.c 和.h 文件更改为 x9c103s.c 与 x9c103s.h。这里不再过多讲述。移植完成后面修改相关代码。
在文件 x9c103s.c 中,编写如下代码。
/********************************************************************************
* 文 件 名: x9c103s.c
* 版 本 号: 初版
* 修改作者: LC
* 修改日期: 2023年07月28日
* 功能介绍:
******************************************************************************
* 注意事项:
*********************************************************************************/
#include "x9c103s.h"
unsigned int STEP = 2;
/******************************************************************
* 函 数 名 delay_us
* 函 数 说 明:微秒延时,延时us
* 函 数 形 参:i=延时时长
* 函 数 返 回:无
* 作 者:LC
* 备 注:无
******************************************************************/
void delay_us(uint32_t i)
{
uint32_t temp;
SysTick->LOAD=9*i; //设置重装数值, 72MHZ时
SysTick->CTRL=0X01; //使能,减到零是无动作,采用外部时钟源
SysTick->VAL=0; //清零计数器
do
{
temp=SysTick->CTRL; //读取当前倒计数值
}
while((temp&0x01)&&(!(temp&(1<<16)))); //等待时间到达
SysTick->CTRL=0; //关闭计数器
SysTick->VAL=0; //清空计数器
}
/******************************************************************
* 函 数 名 volume
* 函 数 说 明:X9C103S数字电位器加减控制
* 函 数 形 参:无
* 函 数 返 回:无
* 作 者:LC
* 备 注:无
******************************************************************/
void volume()
{
if(flag_UP==1)
{
gpio_bit_write(PORT_X9C103S,PIN_CS,RESET); //CS = 0;
delay_1ms(1);
gpio_bit_write(PORT_X9C103S,PIN_U_D,SET); //U_D = 1; 向上滑动
delay_1ms(1);
for(STEP=5;STEP>0;STEP--)
{
gpio_bit_write(PORT_X9C103S,PIN_INC,RESET); //INC = 0;
delay_1ms(1);
gpio_bit_write(PORT_X9C103S,PIN_INC,SET); //INC = 1;
delay_1ms(1);
}
gpio_bit_write(PORT_X9C103S,PIN_CS,SET); //CS = 1;
delay_1ms(1);
flag_UP=0;
}
if(flag_DO==1)
{
gpio_bit_write(PORT_X9C103S,PIN_CS,RESET); //CS = 0;
delay_1ms(1);
gpio_bit_write(PORT_X9C103S,PIN_U_D,RESET); //U_D = 0; 向下滑动
delay_1ms(1);
for(STEP=5;STEP>0;STEP--)
{
gpio_bit_write(PORT_X9C103S,PIN_INC,RESET); //INC = 0;
delay_1ms(1);
gpio_bit_write(PORT_X9C103S,PIN_INC,SET); //INC = 1;
delay_1ms(1);
}
gpio_bit_write(PORT_X9C103S,PIN_CS,SET); //CS = 1;
delay_1ms(1);
flag_DO=0;
}
}
/******************************************************************
* 函 数 名 x9c103s_gpio_config
* 函 数 说 明:x9c103s电位器gpio引脚配置
* 函 数 形 参:无
* 函 数 返 回:无
* 作 者:LC
* 备 注:无
******************************************************************/
void x9c103s_gpio_config(void)
{
/* 使能时钟 */
rcu_periph_clock_enable(RCU_X9C103S);
/* 配置为输出模式 浮空模式 */
gpio_mode_set(PORT_X9C103S,GPIO_MODE_OUTPUT,GPIO_PUPD_NONE,PIN_INC|PIN_U_D|PIN_CS);
/* 配置为推挽输出 50MHZ */
gpio_output_options_set(PORT_X9C103S,GPIO_OTYPE_PP,GPIO_OSPEED_50MHZ,PIN_INC|PIN_U_D|PIN_CS);
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
在文件 x9c103s.h 中,编写如下代码。
#ifndef _BSP_X9C103S_H
#define _BSP_X9C103S_H
#include "gd32f4xx.h"
#include "systick.h"
#define uchar unsigned char
#define uint unsigned int
#define RCU_X9C103S RCU_GPIOA // GPIOA的时钟
#define PORT_X9C103S GPIOA // GPIOD的端口
#define PIN_INC GPIO_PIN_2 // GPIOA的引脚
#define PIN_U_D GPIO_PIN_3 // GPIOA的引脚
#define PIN_CS GPIO_PIN_4 // GPIOA的引脚
extern char flag_UP;
extern char flag_DO;
void delay_us(uint32_t i); //延时函数
void x9c103s_gpio_config(void); // x9c103s gpio引脚配置
void volume();
#endif2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
修改官方例程中的 bsp_key.c 中的按键扫描函数,编写如下代码。
/************************************************
函数名称 : key_scan
功 能 : 按键扫描函数
参 数 : 无
返 回 值 : 无
作 者 : LC
*************************************************/
void key_scan(void)
{
/* 先读取按键引脚的电平 如果低电平,按键按下 */
if(gpio_input_bit_get(BSP_KEY_PORT,KEY_UP_PIN) == SET) // 按键按下
{
delay_1ms(20); // 延迟消抖
if(gpio_input_bit_get(BSP_KEY_PORT,KEY_UP_PIN) == SET) // 再次检测按键是否按下
{
/* 执行对应的功能 */
gpio_bit_toggle(PORT_LED2,PIN_LED2); // led电平状态翻转
flag_UP = 1;
printf("key UP press!\r\n"); // 串口打印key press!
while(gpio_input_bit_get(BSP_KEY_PORT,KEY_UP_PIN) == SET); // 检测按键松开
printf("key UP release!\r\n"); // 串口打印key release!
}
}
/* 先读取按键引脚的电平 如果高电平,按键按下 */
if(gpio_input_bit_get(BSP_KEY_PORT,KEY_DO_PIN) == SET) // 按键按下
{
delay_1ms(20); // 延迟消抖
if(gpio_input_bit_get(BSP_KEY_PORT,KEY_DO_PIN) == SET) // 再次检测按键是否按下
{
/* 执行对应的功能 */
gpio_bit_toggle(PORT_LED2,PIN_LED2); // led电平状态翻转
flag_DO = 1;
printf("key DOWN press!\r\n"); // 串口打印key press!
while(gpio_input_bit_get(BSP_KEY_PORT,KEY_DO_PIN) == SET); // 检测按键松开
printf("key DOWN release!\r\n"); // 串口打印key release!
}
}
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
修改官方例程中的 bsp_key.h,编写如下代码。
#ifndef _BSP_KEY_H
#define _BSP_KEY_H
#include "gd32f4xx.h"
#include "systick.h"
#define BSP_KEY_RCU RCU_GPIOA // 按键端口时钟
#define BSP_KEY_PORT GPIOA // 按键端口
#define KEY_UP_PIN GPIO_PIN_0 // 按键引脚
#define KEY_DO_PIN GPIO_PIN_1 // 按键引脚
void key_gpio_config(void); // key gpio引脚配置
void key_scan(void); // 按键扫描
#endif /* BSP_KEY_H */2
3
4
5
6
7
8
9
10
11
12
13
14
15
在文件 main.c 中,编写如下代码。
/************************************************
函数名称 : main
功 能 : 主函数
参 数 : 无
返 回 值 : 无
作 者 : LC
*************************************************/
char flag_UP;//向上滑标志
char flag_DO;//向下滑标志
int main(void)
{
uint16_t uicount = 0;
float fcount = 0.0;
systick_config(); // 滴答定时器初始化
led_gpio_config(); // led初始化
key_gpio_config(); // key初始化
usart_gpio_config(9600U); // 串口0初始化
x9c103s_gpio_config(); // x9c103s gpio引脚配置
while(1)
{
key_scan(); // 按键扫描
volume(); //X9C103S数字电位器加减控制
}
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
4.19.7 移植验证
现对本工程进行验证:
此处只验证向上滑动,向下滑动同理:
(注意:VH 和 VL 只是规定由 U_D 输人端选择的关于滑动端滑动方向的相对位置, 而并不是端点上的电压)
实验环境如下:
点击向上滑动按键,电脑端和万用表现象如下:
移植成功示例,见文件 3.7.4-2 。
文件 3.7.4-2 移植成功示例
通过网盘分享的文件:立创·梁山派GD32F470ZGT6开发板【模块移植手册代码】
链接: https://pan.baidu.com/s/1pp44yjD1Dhh7U9iZ2a11IA 提取码: LCKF