前言
这个芯片第一次用的时候,我花了不少心思,在网上找不到相关的编程资料,说实话,规格书都看的费劲,写下这篇博文来分享一下如何使用这颗芯片。
规格书分析

初看这个时序图时,人可能会有点懵,这个是芯片的输出管脚发出的波形,在写程序时,目的就是解析时序,分析判断出数据是“0”还是“1”。
芯片在发出数据信号前,会先发送两个周期的低电平,为启动信号,接着就会连续发送16个数据信号,当要发送数据“0”时,其波形时序是1个周期的高电平+1个周期的低电平;当要发送数据“1”时,其波形时序是1个周期的高电平+3个周期的低电平。两个数据的低电平持续时间有区别,所以在判断时,重点也就在这里,可以参考官方的判断数据方法:

代码分析
po代码
宏
1
2
|
#define LOW_V 0
#define HIGH_V 1
|
数据结构
这里只有一个全局变量,用于保存16位的键值数据
1
|
u16 edited_key_code = 0;
|
函数体
1
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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
|
/*************************************************************/
/*函数名:hw_key_code_edit
/*输 入:无
/*输 出:无
/*描 述:中断中调用此函数,将按键时序转化为16位的编码值,低位为1号按键
/*************************************************************/
void hw_key_code_edit(void)
{
static u8 index = 0;
static u8 high_v_count = 0;
static u8 low_v_count = 0;
static u8 last_v = LOW_V;
volatile u8 now_v = LOW_V;
now_v = KEY_INPUT;
if(index>=2 && index<=16) //数据信号
{
//状态切换的条件
if(last_v==LOW_V && now_v==HIGH_V)
{
if(low_v_count>=1 && low_v_count<=4)
{
editing_key_code &= ~(1<<(index-2));
}
else if(low_v_count>=7 && low_v_count<=12)
{
editing_key_code |= (1<<(index-2));
}
index++;
}
//2.计数低电平个数
if(now_v==HIGH_V){
low_v_count = 0;
}
else
{
low_v_count++;
}
//3.异常情况清零,重新等待空闲信号
if(low_v_count > 12){
index = 0;
low_v_count = 0;
}
}
else if(index == 0) //空闲信号
{
//1.状态切换的条件
if((now_v==LOW_V) && (high_v_count>=18 && high_v_count<=33))
{
low_v_count = 1;
index = 1;
}
//2.计数高电平个数
if(now_v == LOW_V){
high_v_count = 0;
}
else{
high_v_count++;
}
//3.异常情况清零,重新等待空闲信号
if(high_v_count > 33){
high_v_count = 0;
}
// (now_v == 0) ? (high_v_count = 0): (high_v_count++);
}
else if(index == 1) //启动信号
{
//1.状态切换的条件
if((now_v == HIGH_V) && (low_v_count>=5 && low_v_count<=8))
{
high_v_count = 1;
index = 2;
}
//2.计数低电平个数
if(now_v == HIGH_V){
low_v_count = 0;
}
else{
low_v_count++;
}
//3.异常情况清零,重新等待空闲信号
if(low_v_count > 8){
index = 0;
low_v_count = 0;
}
}
else //最后一个数据信号
{
//状态切换的条件
if(last_v==LOW_V && now_v==HIGH_V)
{
if(low_v_count>=1 && low_v_count<=4)
{
editing_key_code &= ~(1<<15);
}
else if(low_v_count>=7 && low_v_count<=12)
{
editing_key_code |= (1<<15);
}
edited_key_code = editing_key_code;
index = 0;
editing_key_code &= 0x0000;
}
//2.计数低电平个数
if(now_v==HIGH_V){
low_v_count = 0;
}
else
{
low_v_count++;
}
//3.异常情况清零,重新等待空闲信号
if(low_v_count > 12){
index = 0;
low_v_count = 0;
}
}
last_v = now_v;
}
|
代码思路
虽然代码看起来很长,但是整体的思路还是比较简单的,就是通过静态变量来保存读到的高低电平个数,看它是复合数据0还是数据1,如果过程中有错误数据,直接重新等待空闲信号,开始新一轮的判断。
注意事项
这段代码我是放在了单片机100us的定时器中断中,它的作用是解析出16位的键值数据
补充
官方在设计芯片时,为了增加可靠性,16位数据是有校验功能的,上面的函数仅仅是读取到了16位的数据,并没有对其校验,因此我又补充了下面这个函数,作用是:16位数据校验通过后,输出8位的按键键值信息,若未通过校验,则输出0x00(空按键)。
1
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
|
/*************************************************************/
/*函数名:get_key_value
/*输 入:无
/*输 出:u8 key_value
/*描 述:校验编码后的键值,检验成功后返回按键总线按键值,
校验失败返回无效键值。
/*************************************************************/
u8 get_key_value(void)
{
u8 key_value = 0;
u8 temp_high = 0;
u8 temp_low = 0;
u16 temp_key_code = 0;
temp_key_code = edited_key_code;
temp_low = (u8)temp_key_code;
temp_high = (u8)(temp_key_code>>8);
if(((temp_low&0x0f) + (temp_low>>4)) == 0x0f)
{
if(((temp_high&0x0f) + (temp_high>>4)) == 0x0f)
{
key_value = ((temp_low&0x0f) | ((temp_high&0x0f) << 4));
key_value = (key_value>>1)&0x1f;
}
else
{
key_value = 0x00;
}
}
else
{
key_value = 0x00;
}
return key_value;
}
|
这个函数要被消抖函数调用,用于读取键值信息,通过消抖函数消抖处理后,便是一个可靠的键值了。
总结
以上便是关于FTC333G的使用总结了,函数可以实现功能,但是可能比较长,不是很精简,抛砖引玉嘛,希望能引出读者朋友们更好的使用方式。