|
阅读:1707回复:15
to:Loo_jack, 位流的实现
APH上学的时候的例子,很想把所有的东西教给刷院的同学们,可发现这很难啊!
有点长,因为是C++写的,要求类比较完整. class BitOutputStream { protected: _UINT8 *m_pBuffer; _UINT8 *m_pPointer; _INT32 m_nBitsPerComponent; _INT32 m_nNextBits; _UINT32 m_nNextData; public: BitOutputStream() { m_pBuffer = NULL; m_pPointer = NULL; m_nBitsPerComponent = 0; m_nNextData = 0; m_nNextBits = 0; }; BitOutputStream(void *pSource, _INT32 nBits) { m_pBuffer = (_UINT8 *)pSource; m_pPointer = m_pBuffer; m_nBitsPerComponent = nBits; m_nNextData = 0; m_nNextBits = 0; } ~BitOutputStream(){}; public: void Reset() { m_pPointer = m_pBuffer; m_nNextData = 0; m_nNextBits = 0; } void Attach(void *pSource, _INT32 nBits) { m_pBuffer = (_UINT8 *)pSource; m_pPointer = m_pBuffer; m_nBitsPerComponent = nBits; m_nNextData = 0; m_nNextBits = 0; } void PutBits(_UINT32 code) { PutBits(code, m_nBitsPerComponent); }; void PutBits(_UINT32 code, _INT32 n) { _INT32 c; assert(m_pPointer); assert(n >= 0 && n <= 32); if ( n > 24 ) { PutBits(code >> 24, n - 24); code &= 0x00ffffff; n = 24; } m_nNextData = (m_nNextData << n) | code; m_nNextBits += n; while (m_nNextBits >= 8) { c = (m_nNextData >> (m_nNextBits - 8)) & 0xff; *m_pPointer++ = c; m_nNextBits -= 8; } } void Flush() { _INT32 c; assert(m_pPointer); if ( m_nNextBits == 0 ) return; c = (m_nNextData << (8 - m_nNextBits)) & 0xff; *m_pPointer++ = c; } _INT32 GetPosition() { assert(m_pPointer); return m_pPointer - m_pBuffer; } }; class BitInputStream { protected: // For read const _UINT8 *m_pBuffer; const _UINT8 *m_pPointer; _INT32 m_nBitsPerComponent; _INT32 m_nBitsAvail; _UINT32 m_nBitAcc; public: BitInputStream() { m_pBuffer = NULL; m_pPointer = NULL; m_nBitsPerComponent = 0; m_nBitsAvail = 0; m_nBitAcc = 0; }; BitInputStream(const void *pSource, _INT32 nBits) { m_pBuffer = (_UINT8 *)pSource; m_pPointer = m_pBuffer; m_nBitsPerComponent = nBits; m_nBitsAvail = 0; m_nBitAcc = 0; } ~BitInputStream(){}; public: void Reset() { m_pPointer = m_pBuffer; m_nBitsAvail = 0; m_nBitAcc = 0; } void Attach(const void *pSource, _INT32 nBits) { m_pBuffer = (_UINT8 *)pSource; m_pPointer = m_pBuffer; m_nBitsPerComponent = nBits; m_nBitsAvail = 0; m_nBitAcc = 0; } _INT32 GetBits() { _INT32 nBits; assert(m_pPointer); while (m_nBitsAvail < m_nBitsPerComponent) { m_nBitAcc <<= 8; m_nBitAcc |= (*m_pPointer); m_pPointer++; m_nBitsAvail += 8; } nBits = m_nBitAcc >> (m_nBitsAvail - m_nBitsPerComponent); nBits &= (1 << m_nBitsPerComponent) - 1; m_nBitsAvail -= m_nBitsPerComponent; return nBits; }; _UINT32 GetBits(_INT32 n) { _INT32 nBits; _INT32 nBase = 0; assert(m_pPointer); if ( n > 24 && m_nBitsAvail != 0) { n -= m_nBitsAvail; //nBase = GetBits(m_nBitsAvail) << n; nBase = m_nBitAcc & ((1 << m_nBitsAvail) - 1); nBase <<= n; m_nBitsAvail = 0; } while (m_nBitsAvail < n) { m_nBitAcc <<= 8; m_nBitAcc |= (*m_pPointer); m_pPointer++; m_nBitsAvail += 8; } nBits = m_nBitAcc >> (m_nBitsAvail - n); nBits &= (1 << n) - 1; m_nBitsAvail -= n; return nBits | nBase; }; _INT32 GetPosition() { assert(m_pPointer); return m_pPointer - m_pBuffer; } }; |
|
|
1C#
发布于:2006-01-19 23:17
Re:to:Loo_jack, 位流的实现
如果阿Sir现在要重写的话,会改哪里呢? |
|
|
|
2C#
发布于:2006-01-20 13:43
Re:to:Loo_jack, 位流的实现
谢谢kmWang
能在毕业后还聆听先生的教诲 很是荣幸。 代码刚刚浏览了一遍 看得不是很明白,下班后再继续研究。 在校的时候我是什么都想学点,但结果什么都没有学好 现在由于工作的需要所以写些代码 很是生疏 不会的地方 还请先生和wait4c里面其他达人多多指点 先行谢过!! |
|
|
|
3C#
发布于:2006-01-20 13:54
Re:to:Loo_jack, 位流的实现
另外还想就这个问题请教一下先生。
我现在面对的是avr单片机的编程 具体情况如下: 码流是通过SPI输出的 要求的是unsigned char类型的数组 而这个数组由两部分数据组成 一部分是一个 8 x 75的点阵 而另一部分是1 x 75的标志信号 SPI要求输出的码流是一个8bit的点阵数据+1bit标志信号+一个8bit的点阵数据+1bit标志信号+一个8bit的点阵数据+1bit标志信号+……………… 点阵信息和标志信号的存储可以自己设置 不过对速度和内存要求比较严格 按我现在的做法 一不小心就堆栈溢出和被中断干扰 请问先生有没有更优化一点的方式 |
|
|
|
4C#
发布于:2006-01-21 11:26
Re:to:Loo_jack, 位流的实现
[em100]
能用中文加以注解么?[em099] |
|
|
5C#
发布于:2006-01-22 09:47
Re:to:Loo_jack, 位流的实现
崇拜硬件达人
mark继续看 |
|
|
|
6C#
发布于:2006-01-22 11:14
Re:to:Loo_jack, 位流的实现
to:mumu,不准备改了;)
to Loo_jack:把数据和标记分开存储,即一个数组存数据,另一个数组存标记.栈溢出主要是函数局部数组太大,或递归调用造成的,如果受中断干扰,说明问题主要还是出在中断响应函数上,一般中断处理要尽可能小,把没必要在中断处理的程序分离出来,这也是为什么多数设备驱动程序要把中断分上下两个半部的原因.优化你的中断响应函数,而不是这部分,这部分的效率按上面的数据进行组织可以做的足够高. |
|
|
7C#
发布于:2006-01-23 21:43
Re:to:Loo_jack, 位流的实现
[em154]晕死,根本不明白作用是啥~~
比如这个吧 void PutBits(_UINT32 code) {
PutBits(code, m_nBitsPerComponent);
};
是重载么? |
|
|
8C#
发布于:2006-01-23 22:40
Re:to:Loo_jack, 位流的实现
拿IDE一步步跟踪就知道是不是重载了.
[ 2006-01-23 22:51:06 mumu 修改 ] |
|
|
|
9C#
发布于:2006-01-24 09:07
Re:to:Loo_jack, 位流的实现
万贤同学, 你需要的是把数据结构教程里的代码全部调试通过一遍, 最好是能做掉课后的习题集
因为你看以上的代码都得很晕的话, 说明你的思维能力还没有达到, 要多加以锻炼程序员的思考能力, 熟能生巧. |
|
|
|
10C#
发布于:2006-01-24 14:21
Re:to:Loo_jack, 位流的实现
delete me
[ 2006-01-24 21:27:33 mumu 修改 ] |
|
|
|
11C#
发布于:2006-01-24 21:27
Re:to:Loo_jack, 位流的实现
万贤同学, 你需要的是把数据结构教程里的代码全部调试通过一遍, 最好是能做掉课后的习题集因为你看以上的代码都得很晕的话, 说明你的思维能力还没有达到, 要多加以锻炼程序员的思考能力, 熟能生巧. 谢谢铁板大哥指点,数据结构考试虽然过了,但现在真是忘的一干二净了,还是要从头来过,再次感谢!不过~不知我们学的那本<数据结构>(清华大学计算机系列教材)如何? |
|
|
12C#
发布于:2006-02-07 09:37
to: kmwang
谢谢kmwang!
回旧石器时代过年去了,没能来论坛看看 所以今天才看到kmwang的回复。很是抱歉! 我的做法和您讲的差不多 我说的堆栈溢出后来发现并不是溢出了 错误有两个 一个对数组的误操作,操作了申请范围以外的地址 另一个是中断中调试信息太多了 导致中断过长 致使在spi传输的时候中断发生的那几个周期被拖长了 出现了少量误码 我用逐步调试,再加示波器终于看出来了 去掉调试信息以后中断就变得很短了 也没有误码了。 奇怪的是我的中断发生的时间是固定的 而传输发生的时间是没有规律的 但结果在出现误码的位置却很有规律 还值得好好考虑考虑。 |
|
|
|
13C#
发布于:2006-02-08 08:34
Re:to:Loo_jack, 位流的实现
为什么示波器都能用上....>_<* |
|
|
|
14C#
发布于:2006-02-08 08:54
Re:to:Loo_jack, 位流的实现
为什么示波器都能用上....>_<* 用来观察信号的传输 发现某些时候信号的周期被拉长变形了,而变形的部分正好是误码出现的地方 去掉中断这些东西就没有了 于是推测是中断过长导致传输错误的 其实我的信号传输速率很慢的,周期是3*5=15ns |
|
|
|
15C#
发布于:2006-02-08 11:14
Re:to:Loo_jack, 位流的实现
如果上学的时候能认识kmwang,bigc也没这么多不学无术得人了,我也不会整天这么的怨天尤人了,哎 |
|
|