打印

怎样判断一个变量里面是否有连续8个以上的1?

[复制链接]
3201|35
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
forrest11|  楼主 | 2017-4-5 01:19 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 forrest11 于 2017-4-6 10:35 编辑

有没有好的方法(C语言)判断:一个16bit变量里面是否有连续8个以上的1?
如0xFF00就有,0xFEFE就没有, 0x7F80就有,等等。
方法有,比如我想到的是用窗口法:先和0xFF00比较,然后和0x7F80比较.....最后和0xFF比较。 但这个方法太蠢了。
16bit数据其实是输入码流,你不能随便改变它的值,因为它随时(2kHz速率)被中断更改。我想到的方式是:
disableInt();
data=buf;
buf=0;
enableInt();
这样就用data把buf里面的数据取出。但后期处理更复杂。因为要做数据拼接。我不知道怎么做拼接数据,因为第二次的数据要哪一段拼接到第一次数据我还没有想清楚。拼接好了后再判断,就像T叔说的那样没有问题了。
所以,对这样的码流信号,有什么好办法判断8个连1信号(帧头)?

当然可以在中断服务程序里面1bit1bit地处理,这样逻辑比较简单。

但如果在中断处理bit数据,带来的问题是所有的收数据处理都必须在中断中处理,这样中断函数太大了,不合理。
所以还是回到初始,在主程序中处理input data。这样中断函数必须记录接收到的数据序列和bit个数。
回到主程序中,问题又来了:bit个数不一定是16位,而是一个变化数字。要考虑的事情有:
1.    等待与下一批数据拼接.
2.   检查bit个数是否大于7,如果没有,则跳到5;(其实处理也可以,比如记录现有的1bit,但太复杂了)
3.   查数列中有没有连续8个1,检测的办法总是有的;
4.   如果检测到了,则到7
5.   找到最后一个0bit,保留右边的全部1bit,左边的数据全部丢弃,更新有效bit个数
6.   回到1;
7.   到下一个状态

你们有更好的办法吗?

相关帖子

沙发
tyw| | 2017-4-5 07:59 | 只看该作者
屏蔽出低8位,检查是否为11111111,是则把数挑出来,不是则右环移1位,重复前面动作,16次后结束

使用特权

评论回复
评论
zhaoyu2005 2017-4-5 08:10 回复TA
不用16次,8次就行了吧 
板凳
tyw| | 2017-4-5 08:51 | 只看该作者
tyw 发表于 2017-4-5 07:59
屏蔽出低8位,检查是否为11111111,是则把数挑出来,不是则右环移1位,重复前面动作,16次后结束 ...

ok,8次够了,哈哈

使用特权

评论回复
地板
forrest11|  楼主 | 2017-4-5 09:44 | 只看该作者
本帖最后由 forrest11 于 2017-4-5 10:26 编辑
tyw 发表于 2017-4-5 08:51
ok,8次够了,哈哈

嗯,这个是可以解的。
不过我现在这个问题难度加大:
16bit数据其实是输入码流,你不能随便改变它的值,因为它随时(2kHz速率)被中断更改。我想到的方式是:
disableInt();
data=buf;
buf=0;
enableInt();
这样就用data把buf里面的数据取出。但后期处理更复杂。因为要做数据拼接。我不知道怎么做拼接数据,因为第二次的数据要哪一段拼接到第一次数据我还没有想清楚。拼接好了后再判断,就像T叔说的那样没有问题了。
所以,对这样的码流信号,有什么好办法判断8个连1信号(帧头)?

使用特权

评论回复
5
tyw| | 2017-4-5 10:40 | 只看该作者
本帖最后由 tyw 于 2017-4-5 10:47 编辑
forrest11 发表于 2017-4-5 09:44
嗯,这个是可以解的。
不过我现在这个问题难度加大:
16bit数据其实是输入码流,你不能随便改变它的值,因 ...


哈哈,用汇编思路就清晰了,码流再怎么流,进了内存,就得按字节存放.这样动到哪个字节,看指针就知道了.具体右移到哪一位,看位指针.再调整到起始位.(注意,这个动作要把接收到的全部字节同时环移)这样才能获得帧头后的完整数据.
其实你才2k速度,每bit有0.5ms间隙,对"1"累加一下判下'8",碰到"0"则重新计数,时间还是足够的.这样就不用折腾了,哈哈

使用特权

评论回复
6
forrest11|  楼主 | 2017-4-5 10:54 | 只看该作者
tyw 发表于 2017-4-5 10:40
哈哈,用汇编思路就清晰了,码流再怎么流,进了内存,就得按字节存放.这样动到哪个字节,看指针就知道了.具体 ...

多谢!
你的意思是实时处理,不要做拼接工作了。我再仔细考虑一下,因为这意味着要在中断处理数据流。

使用特权

评论回复
7
xxzouzhichao| | 2017-4-5 10:57 | 只看该作者
楼主位的方法不就挺好么?时间和空间都不错

使用特权

评论回复
8
icecut| | 2017-4-5 10:59 | 只看该作者
如果是面试题的话,肯定不是这么解.比如一个32bit 数里面大于8个1
或者说求1的个数

使用特权

评论回复
9
xxzouzhichao| | 2017-4-5 11:11 | 只看该作者
int8_t func(uint16_t word) {
        int8_t i = 8:
        for ( ; i != 0; i--) {
                if (0xff == (word & 0xff)) {
                        return 0;
                }
                word >>= 1;
        }
        return -1;
}

使用特权

评论回复
10
linqing171| | 2017-4-5 11:15 | 只看该作者
AVR 模拟的USB的汇编代码,是在中断中一边收一边处理的。收完一起处理满足不了1.5MHz的USB的速度。

使用特权

评论回复
11
xmar| | 2017-4-5 11:31 | 只看该作者
本帖最后由 xmar 于 2017-4-5 11:32 编辑

移位逻辑与,为1计数加一,为0计数清0。计数满8返回找到连续8个1,计数清0。然后,重复下一个移位逻辑与。

使用特权

评论回复
12
123654789| | 2017-4-5 15:18 | 只看该作者
case "1111,1111,0000,0000"

case "0111,1111,1000,0000"

这样 写 8 行 Case 语句 就 行了 。

你这个例子不能包括
case 0B 0111,1111,1000,0001
case 0B 0111,1111,1000,0010
case 0B 0111,1111,1000,0011

所以我给你评价错误了

使用特权

评论回复
13
lxyppc| | 2017-4-5 15:55 | 只看该作者
楼主位的方法看起来蠢,实际上很有效

使用特权

评论回复
14
kmnl| | 2017-4-5 16:39 | 只看该作者
左移或右移,判断最高位或最低位,是1个数加1,否则个数清零,判断个数是否累计到8,够8跳出,最多移15次后结束判断

使用特权

评论回复
15
banxiafeixia| | 2017-4-5 16:44 | 只看该作者
tyw 发表于 2017-4-5 08:51
ok,8次够了,哈哈

如果低八位是11111110呢,所以还觉得是循环右移8次吗?

使用特权

评论回复
16
banxiafeixia| | 2017-4-5 16:48 | 只看该作者
forrest11 发表于 2017-4-5 09:44
嗯,这个是可以解的。
不过我现在这个问题难度加大:
16bit数据其实是输入码流,你不能随便改变它的值,因 ...

除了按位右移没有更好的办法了,八个连续1的数字具有什么特性呢,实在想不出。

使用特权

评论回复
17
banxiafeixia| | 2017-4-5 16:52 | 只看该作者
xxzouzhichao 发表于 2017-4-5 11:11
int8_t func(uint16_t word) {
        int8_t i = 8:
        for ( ; i != 0; i--) {

确定?if语句对吗

使用特权

评论回复
18
banxiafeixia| | 2017-4-5 16:53 | 只看该作者
banxiafeixia 发表于 2017-4-5 16:44
如果低八位是11111110呢,所以还觉得是循环右移8次吗?

哇,我好蠢

使用特权

评论回复
19
forrest11|  楼主 | 2017-4-5 17:07 | 只看该作者
icecut 发表于 2017-4-5 10:59
如果是面试题的话,肯定不是这么解.比如一个32bit 数里面大于8个1
或者说求1的个数 ...

你想多了。找8个连续的比数一的个数要难一点。

使用特权

评论回复
20
forrest11|  楼主 | 2017-4-5 17:09 | 只看该作者
caosix 发表于 2017-4-5 14:05
你在 “变量” 里的数据,,已经是 并行16Bit 的了。

如果 是 串行状态 反而好办,弄个 CPLD + 移位寄存 ...

错得大了点啊,而且CPLD和单片机的处理方式不一样。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

37

主题

1093

帖子

14

粉丝