【STM32F0实验】基于STM32 M0的ASK报警接收系统

[复制链接]
10486|43
 楼主| littleshrimp 发表于 2012-8-27 22:25 | 显示全部楼层

  1. if(highlevels[j]>10000)//数值大于10000视为1,否则为0

这句话仅适用于在指定速率下解码,如果想兼容不同速率的ASK码,需要判断有效ID区域中的近似数据个数,如果ID正确的话,近似个数只能小于等于2个。然后查找最大值或最大值的近视平均值,以它为参考将相应的“位”转换为01

这里提供一个思路,有兴趣的网友可以自己尝试。
 楼主| littleshrimp 发表于 2012-8-29 22:53 | 显示全部楼层
完成ASK的解码后,下一步需要将指定设备的ID绑定到STM32 M0报警主机上。让其只识别指定的报警设备发来的报警信号
绑定的大至的流程就是用户先按一下开发板上的USER按键,然后LED3会闪烁20次,如果再20次以内接收到报警设备ID就将其存入FLASH,存入前先将FLASH内的ID读出(因为写入时一次最少写1024个字节),第一个字为FLASHID的数量,然后通过第一个字将FLASH内的所有ID读出。判断新添加的ID是否已经存在,如果存在则退出。否则,将第一个字加1,并将新ID存入队列结尾入,然后重新写回FLASH
操作FLASH的相关函数

  1. /*
  2.           清除绑定数据
  3. */
  4. void BDClear(void)
  5. {
  6.            FLASH_Unlock();//FLASH解锁
  7.            FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPERR);
  8.            if (FLASH_ErasePage(FLASH_USER_START_ADDR)== FLASH_COMPLETE)//擦除FLASH
  9.     {
  10.                    }
  11.                    FLASH_Lock(); //锁定FLASH
  12. }
  13. /*
  14.          获取绑定ID 第0字节为数据长度
  15. */
  16. void BDGetSlaveID(uint32_t bd_slave_id[])
  17. {
  18.          uint16_t i;
  19.          Address = FLASH_USER_START_ADDR;//定位FLASH起始地址
  20.          bd_slave_id[0]= *(__IO uint32_t *)Address;//读取ID数量
  21.          for(i=1;i<=bd_slave_id[0];i++)
  22.          {
  23.                    Address += 4;
  24.                    bd_slave_id[i]=*(__IO uint32_t *)Address;
  25.          }
  26. }
  27. /*
  28.          判断指定ID是否已经存在
  29. */
  30. uint8_t ExistingSlaveID(uint32_t bd_slv_id)
  31. {
  32.          uint16_t i;
  33.          BDGetSlaveID(buffer);//查询已经绑定的ID
  34.          if(buffer[0] >= MAX_ID_COUNT) return 1;//如果大于可绑定的最多数量则返回1
  35.          for(i=1;i<=buffer[0];i++)
  36.          {
  37.                    if(buffer[i] == bd_slv_id)return 1;//如果ID已经存在返回1
  38.          }
  39.          return 0;
  40. }
  41. /*
  42.          添加绑定ID
  43. */
  44. void BDAddSlaveID(uint32_t bd_slv_id)
  45. {
  46.          uint16_t i;
  47.          if(!ExistingSlaveID(bd_slv_id))//如果ID不存在
  48.          {
  49.                    buffer[0]++;//第0个WORD为绑定的ID数量
  50.                    buffer[buffer[0]] = bd_slv_id;//将新ID添加到ID队列结尾
  51.                    Address = FLASH_USER_START_ADDR;//定位FLASH起始地址
  52.                    FLASH_Unlock();//解锁FLASH
  53.                    FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPERR);
  54.                    if (FLASH_ErasePage(FLASH_USER_START_ADDR)== FLASH_COMPLETE)//擦除FLASH
  55.                    {
  56.                             for(i=0;i<=buffer[0];i++)
  57.                             {
  58.                                      if (FLASH_ProgramWord(Address, buffer[i]) == FLASH_COMPLETE)//将ID数量及全部ID写回FLASH
  59.                                      {
  60.                                                Address = Address + 4;
  61.                                      }
  62.                             }
  63.                    }
  64.          }
  65.          FLASH_Lock(); //锁定FLASH
  66. }
按键相关函数

  1.   STM_EVAL_LEDInit(LED3);//LED3初始化
  2.   STM_EVAL_LEDInit(LED4);//LED4初始化
  3.   STM_EVAL_PBInit(BUTTON_USER, BUTTON_MODE_EXTI); //按键初始化

  1.                    if(bd)
  2.                    {
  3.                             /* Turn on LED3 and LED4 */
  4.                             bd=0;
  5.                             for(i=0;i<20;i++)
  6.                             {
  7.                                      STM_EVAL_LEDOn(LED3);//点亮LED3
  8.                                      slave_id=GetSlaveID();//获取触发的报警ID
  9.                                      if(slave_id)        //如果ID不为零
  10.                                      {
  11.                                                BDAddSlaveID(slave_id);//添加ID
  12.                                                STM_EVAL_LEDOn(LED4);//点亮LED4
  13.                                                break;//退出绑定
  14.                                      }
  15.                                      Delay(10000000);
  16.                                      STM_EVAL_LEDOff(LED3);//熄灭LED3
  17.                                      Delay(10000000);
  18.                             }
  19.                    }


  1. /*
  2.          按键中断
  3. */
  4. void EXTI0_1_IRQHandler(void)
  5. {
  6.   if(EXTI_GetITStatus(USER_BUTTON_EXTI_LINE) != RESET)
  7.   {
  8.     EXTI_ClearITPendingBit(USER_BUTTON_EXTI_LINE);
  9.   
  10.     bd = 1;
  11.   }  
  12. }
yybj 发表于 2012-8-29 23:43 | 显示全部楼层
LZ共享精神值得表扬,相当给力
 楼主| littleshrimp 发表于 2012-8-31 12:28 | 显示全部楼层
本帖最后由 littleshrimp 于 2012-8-31 12:30 编辑


完成设备的绑定功能后我们还落下一个功能,就是清除绑定。我们需要增加一些代码在main函数中。当用户按下USER键时LED3闪烁,再次按下USER键系统进入撤布防切换,同时LED4闪烁1次。再次按下会清除已经绑定的ID数据,同时LED4闪烁2次。


接下来是报警的触发,为了便于在STM32F0-Discovery上演示报警防区的提示功能,我们可以选择使用DAC播放不同防区的语音使用户对报警来源加以区分。因为需要录制音频,时间关系,这里使用LED4的闪烁次数来区分报警来源。对已经绑定过的设备。如果其触发报警系统会根据报警IDFLASH的索引位置使LED4闪烁不同的次数。使用语音时只需将不同的索引对应到指定的音频数组并通过DAC输出即可。

下面是修改后的代码:

  1.   while (1)

  2.   {



  3. if(bd == ALARM_SWITCH)//修改防区状态



  4. {







  5. LEDBlink(LED3,1);//




  6. if(alarm_on)




  7. {





  8. alarm_on = 0;





  9. STM_EVAL_LEDOff(LED4);//熄灭LED4




  10. }




  11. else




  12. {





  13. alarm_on = 1;





  14. STM_EVAL_LEDOn(LED4);//点亮LED4




  15. }




  16. STM_EVAL_LEDOff(LED3);//熄灭LED3




  17. bd = NONE;



  18. }



  19. else if(bd == CLEAR_ID)//清除已绑定ID



  20. {




  21. LEDBlink(LED3,1);//




  22. BDClear();//清除绑定数据




  23. LEDBlink(LED4,2);//LED4闪烁2次





  24. bd = NONE;//退出绑定



  25. }



  26. else if(bd == BINDING)//绑定



  27. {




  28. LEDBlink(LED3,1);//




  29. slave_id=GetSlaveID();//获取触发的报警ID




  30. if(slave_id)
  31. //如果ID不为零




  32. {





  33. BDAddSlaveID(slave_id);//添加ID





  34. LEDBlink(LED4,1);//闪亮LED4一次





  35. bd = NONE;//退出绑定




  36. }



  37. }



  38. else



  39. {




  40. if(alarm_on)//如果布防开启




  41. {





  42. slave_id=GetSlaveID();//获取触发的报警ID





  43. if(slave_id)
  44. //如果ID不为零





  45. {






  46. slvId_index = GetSlaveIdIndex(slave_id);






  47. LEDBlink(LED4,slvId_index);//将对应的索引位置输出到LED4





  48. }



  49. }




  50. if(i++>=20)




  51. {







  52. bd = NONE;//退出绑定





  53. i = 0;




  54. }



  55. }
  56. }
 楼主| littleshrimp 发表于 2012-8-31 12:30 | 显示全部楼层
到现在为止,所有的功能基本全部实现。
代码和发贴笔记在一楼。
 楼主| littleshrimp 发表于 2012-9-1 16:40 | 显示全部楼层
这么酷的帖子我要是不督促你,你若忘记发了,那岂不是论坛的一大损失哦!:lol
21小跑堂 发表于 2012-8-26 01:14

实验俺做了,贴子也发了。您看开发板是不就不往回要了?
aozima 发表于 2012-10-14 17:26 | 显示全部楼层
请问有没什么方法可以不通过GPIO就可以判断刚才是上升沿还是下降沿?
怕万一输入信号变化过快,等读GPIO时电平状态已变化。
  1. void TIM2_IRQHandler(void)
  2. {
  3. //判断捕获引脚电平
  4.     if(GPIOA->IDR & GPIO_Pin_1)
  5.     {
  6.         //如果引脚电平为高,说明是上升沿捕获,即前一个电平为低电平.
  7.     }
  8. }
baidudz 发表于 2012-10-14 23:17 | 显示全部楼层
相当给力
dfsa 发表于 2012-10-14 23:24 | 显示全部楼层
这个笔记和代码对我很有用,多谢分享
秋天落叶 发表于 2012-10-14 23:33 | 显示全部楼层
这个产品再完善一下,应该很有市场价值
xsgy123 发表于 2012-10-14 23:41 | 显示全部楼层
讲解的相当清晰
weikezhi 发表于 2012-10-15 11:26 | 显示全部楼层
很不错,很详细。
zzyaizll 发表于 2013-2-21 13:12 | 显示全部楼层
顶一个
拿起书本 发表于 2013-2-23 03:55 | 显示全部楼层
楼主的这这种钻研精神令人钦佩啊,顶一下。
sinadz 发表于 2013-2-23 10:24 | 显示全部楼层
很有参考价值
火箭球迷 发表于 2013-2-23 10:39 | 显示全部楼层
还有没有更多的笔记,很不错
yybj 发表于 2013-2-23 10:52 | 显示全部楼层
再改进一下,估计可以做产品了:lol
cjhk 发表于 2013-2-23 17:55 | 显示全部楼层
**很不错  呵呵  很好  需要消化一下啊   呵呵  顶一个
hellome11 发表于 2013-3-22 13:56 | 显示全部楼层
very good!
pino66 发表于 2014-7-22 15:17 | 显示全部楼层
太有用了,最近在学习ASK解码。谢谢楼主分享
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 在线客服 返回列表 返回顶部