- <font face="微软雅黑">#define unsigned char INT8U
- #define READ_PIN P01 //你连接在ASK无线模块的IO口
- #define FRAME_BYTE_LENGTH 7
- #define FRAME_BIT_LENGTH FRAME_BYTE_LENGTH *8
- INT8U detect_done ;
- INT8U rx_data[FRAME_BYTE_LENGTH] ;
- //这个函数需要放在100us的定时器中
- void RxDataThread(void)
- {
- static INT8U prev_read = 0,read_period = 0,read_low_cnt = 0,read_high_cnt = 0,read_bit_cnt = 0;
- static INT8U read_buff[FRAME_BYTE_LENGTH] = {0};
- INT8U i;
-
- if (READ_PIN == HIGH)
- {
- if (prev_read == 1)
- {
- if ((read_period >= 6) && (read_period <= 16))
- {
- if (read_high_cnt > read_low_cnt)
- {
- read_buff[read_bit_cnt / 8] |= (0x01 << (0x07 - (read_bit_cnt % 8)));
- }
- read_bit_cnt++;
- if (read_bit_cnt >= FRAME_BIT_LENGTH)
- {
- detect_done = 1; //检测结束
- read_bit_cnt = 0;
- for (i = 0; i < FRAME_BYTE_LENGTH; i++)
- {
- rx_data[i] = read_buff[i];
- read_buff[i] = 0x00;
- }
- }
- }//判断是否符合误差要求,这里标准read_period = 12,但由于误差,需要左右放宽。
- else
- {
- read_bit_cnt = 0;
- for (i = 0; i < FRAME_BYTE_LENGTH; i++)
- {
- read_buff[i] = 0x00;
- }
- }
-
- read_high_cnt = 0;
- read_low_cnt = 0;
- read_period = 0;
- }
-
- read_high_cnt++;
- read_period++;
- prev_read = 0;
- }
- else
- {
- read_period++;
- read_low_cnt++;
- prev_read = 1;
- }
- }
- 关于这段代码的解释:
- 1)read_period完成计算一个位的总时间,比如上图中的A7位。
- 2)read_low_cnt、read_high_cnt对一个位中的高低电平计数,然后,通过这两者的大小来确定收到的位是0还是1。
- 3)prev_read作用是第一次检测到上升沿后开始计数,第二次检测到上升沿后计数结束,紧接着判断检测到的位是否符合误差要求。
- main()
- {
- while(1)
- {
- if(detect_done == 1)
- {
- detect_done = 0;
- //处理接收到的数据
- }
- }
- }</font>
这种方法在解码时不仅占用的资源相对较少,而且有时还能为其他任务提供运行时钟,但是,使用它的要求是定时器查询周期远小于一个位的周期(100us << 1200us),
如果一个位周期本身很短,这种方法也就不适用了。
上述介绍了3种可以用来检测无线码的方法,不同的时候可能需要使用不同的方法,并没有哪一种方法适合所有应用,这里,仅仅提供一种解码思路。当然,仅仅是一种解码
思路并不足以为我们提供多少帮助,但是,从上述的过程,我们却可以看出更多的能应用在其他工作中的一些非技术经验。
1、在解决问题时,先不要立即动手,而是要先考虑解决这个问题我们有哪些已知条件
2、在动手解决问题前,我们尽量先提出尽可能多的有可能解决问题的方案
3、在动手解决问题前,基于上述提出的可能方案,尽量预先评估各种方案的优缺点,然后选择最适用的方案
仔细看看,这个过程还真有点像我们在做题时的思维过程,做题时,老师总会强调做题时,尽量找到多种解法,这样不仅有利于你更好的找到知识之间的联系,而且也能有更好的解决问题的方案。