首页 视频 图库 新闻 体育 博客 娱乐
查看: 6296 | 回复: 10

[原创] 欢迎您进入-七夕鹊桥搭建-基于超宽带技术的心动“鹊桥”设计

[复制链接]

主题

好友

115

积分

童生

  • TA的每日心情
    开心
    2019-8-19 09:55
  • 签到天数: 3 天

    连续签到: 1 天

    [LV.2]偶尔看看I

    发表于 2019-8-7 20:43:29 | 显示全部楼层
    本帖最后由 AUST 于 2019-8-8 21:19 编辑

    “那一眼看见你,就知道这辈子都逃不掉了”。曾听过这样一句话:“从不想独身,却有预感晚婚,我想在茫茫人海中寻找那唯一与之契合的灵魂伴侣。”

    因为今天,又到了牛郎织女见面的日子——七夕。

    同样,今天也是2019年大学生电子设计竞赛开赛的日子,祝愿赛场上的你们都取得好成绩!


    一、思路篇


    本人和女友也是在异地中,常常以“两情若是久长时,又岂在朝朝暮暮。”来安慰自己。晚上无意看到这个征集帖,就想利用手上的UWB模块做一个“心动鹊桥”。主要功能:在有效范围内,两个模块距离越近,红色LED闪烁越快,寓意着心跳越快。当两个模块完全接近时,红色LED常亮,寓意着彼此惺惺相惜。


    二、原理篇

    双向飞行时间法(TW-TOF,two way-time of flight)每个模块从启动开始即会生成一条独立的时间戳。模块 A 的发射机在其时间戳上的 Ta1 发射请求性质的脉冲信号,模块 B 在 Tb2 时刻发射一个响应性质的信号,被模块 A 在自己的时间戳 Ta2 时刻接收。有次可以计算出脉冲信号在两个模块之间的飞行时间,从而确定飞行距离 S。

    S=Cx[(Ta2-Ta1)-(Tb2-Tb1)]/2 (C 为光速)

    二、软件篇

    SPI初始化

    1. /***************************************************************************************************
    2. *函 数 名: Spi_Init
    3. *功能说明: SPI从机设备CS引脚初始化
    4. *形 参: 无
    5. *返 回 值: 无
    6. ***************************************************************************************************/
    7. void SPI_Configuration(void)
    8. {
    9. SPI_InitTypeDef SPI_InitStructure;
    10. GPIO_InitTypeDef GPIO_InitStructure;

    11. SPI_I2S_DeInit(SPIx);
    12. GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);

    13. SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
    14. SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
    15. SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
    16. SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
    17. SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
    18. SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
    19. SPI_InitStructure.SPI_BaudRatePrescaler = SPIx_PRESCALER;
    20. SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
    21. SPI_InitStructure.SPI_CRCPolynomial = 7;
    22. SPI_Init(SPIx, &SPI_InitStructure);

    23. // SPIx SCK and MOSI pin setup
    24. GPIO_InitStructure.GPIO_Pin = SPIx_SCK | SPIx_MOSI;
    25. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    26. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    27. GPIO_Init(SPIx_GPIO, &GPIO_InitStructure);

    28. // SPIx MISO pin setup
    29. GPIO_InitStructure.GPIO_Pin = SPIx_MISO;
    30. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
    31. GPIO_Init(SPIx_GPIO, &GPIO_InitStructure);

    32. // SPIx CS pin setup
    33. GPIO_InitStructure.GPIO_Pin = SPIx_CS;
    34. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    35. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    36. GPIO_Init(SPIx_CS_GPIO, &GPIO_InitStructure);

    37. // Disable SPIx SS Output
    38. SPI_SSOutputCmd(SPIx, DISABLE);

    39. // Enable SPIx
    40. SPI_Cmd(SPIx, ENABLE);

    41. // Set CS high
    42. GPIO_SetBits(SPIx_CS_GPIO, SPIx_CS);
    43. }
    复制代码

    USART2初始化

    1. /***************************************************************************************************
    2. *函 数 名: uart_init
    3. *功能说明: USART2初始化
    4. *形 参: bound波特率
    5. *返 回 值: 无
    6. ***************************************************************************************************/
    7. void uart_init(u32 bound){
    8. GPIO_InitTypeDef gpioInitStruct;
    9. USART_InitTypeDef usartInitStruct;
    10. NVIC_InitTypeDef nvicInitStruct;

    11. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    12. RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);

    13. //PA2 TXD
    14. gpioInitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
    15. gpioInitStruct.GPIO_Pin = GPIO_Pin_2;
    16. gpioInitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    17. GPIO_Init(GPIOA, &gpioInitStruct);

    18. //PA3 RXD
    19. gpioInitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    20. gpioInitStruct.GPIO_Pin = GPIO_Pin_3;
    21. gpioInitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    22. GPIO_Init(GPIOA, &gpioInitStruct);

    23. usartInitStruct.USART_BaudRate = bound;
    24. usartInitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //无硬件流控
    25. usartInitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //接收和发送
    26. usartInitStruct.USART_Parity = USART_Parity_No; //无校验
    27. usartInitStruct.USART_StopBits = USART_StopBits_1; //1位停止位
    28. usartInitStruct.USART_WordLength = USART_WordLength_8b; //8位数据位
    29. USART_Init(USART2, &usartInitStruct);

    30. USART_Cmd(USART2, ENABLE); //使能串口

    31. USART_ITConfig(USART2, USART_IT_RXNE, ENABLE); //使能接收中断

    32. nvicInitStruct.NVIC_IRQChannel = USART2_IRQn;
    33. nvicInitStruct.NVIC_IRQChannelCmd = ENABLE;
    34. nvicInitStruct.NVIC_IRQChannelPreemptionPriority = 0;
    35. nvicInitStruct.NVIC_IRQChannelSubPriority = 0;
    36. NVIC_Init(&nvicInitStruct);
    37. }
    复制代码

    调用DWM1000官方的API函数

    1. int instance_run(void)
    2. {
    3. int instance = 0 ;
    4. int done = INST_NOT_DONE_YET;
    5. int message = instance_peekevent(); //get any of the received events from ISR

    6. while(done == INST_NOT_DONE_YET)
    7. {
    8. //int state = instance_data[instance].testAppState;
    9. done = testapprun(&instance_data[instance], message) ; // run the communications application

    10. //we've processed message
    11. message = 0;
    12. }

    13. if(done == INST_DONE_WAIT_FOR_NEXT_EVENT_TO) //we are in RX and need to timeout (Tag needs to send another poll if no Rx frame)
    14. {
    15. if(instance_data[instance].mode == TAG) //Tag (is either in RX or sleeping)
    16. {
    17. int32 nextPeriod ;

    18. // next period will be a positive number because correction is -0.5 to +1.5 periods, (and tagSleepTime_ms is the period)
    19. nextPeriod = instance_data[instance].tagSleepRnd + instance_data[instance].tagSleepTime_ms + instance_data[instance].tagSleepCorrection;

    20. instance_data[instance].nextSleepPeriod = (uint32) nextPeriod ; //set timeout time, CAST the positive period to UINT for correct wrapping.
    21. instance_data[instance].tagSleepCorrection2 = instance_data[instance].tagSleepCorrection;
    22. instance_data[instance].tagSleepCorrection = 0; //clear the correction
    23. instance_data[instance].instanceTimerEn = 1; //start timer
    24. }
    25. instance_data[instance].stopTimer = 0 ; //clear the flag - timer can run if instancetimer_en set (set above)
    26. instance_data[instance].done = INST_NOT_DONE_YET;
    27. }

    28. //check if timer has expired
    29. if((instance_data[instance].instanceTimerEn == 1) && (instance_data[instance].stopTimer == 0))
    30. {
    31. if(instance_data[instance].mode == TAG)
    32. {
    33. if((portGetTickCount() - instance_data[instance].instanceWakeTime) > instance_data[instance].nextSleepPeriod)
    34. {
    35. event_data_t dw_event;
    36. instance_data[instance].instanceTimerEn = 0;
    37. dw_event.rxLength = 0;
    38. dw_event.type = 0;
    39. dw_event.type_save = 0x80 | DWT_SIG_RX_TIMEOUT;
    40. //printf("PC timeout DWT_SIG_RX_TIMEOUT\n");
    41. instance_putevent(dw_event, DWT_SIG_RX_TIMEOUT);
    42. }
    43. }
    44. #if (ANCTOANCTWR == 1) //allow anchor to anchor ranging
    45. else if(instance_data[instance].mode == ANCHOR)
    46. {
    47. uint32_t slotTime = portGetTickCount() % instance_data[instance].sframePeriod;

    48. if(instance_data[instance].gatewayAnchor)
    49. {
    50. //if we are in the last slot - then A0 ranges to A1 and A2
    51. if( slotTime >= instance_data[instance].a0SlotTime)
    52. {
    53. port_DisableEXT_IRQ(); //enable ScenSor IRQ before starting
    54. //anchor0 sends poll to anchor1
    55. instance_data[instance].mode = ANCHOR_RNG; //change to ranging initiator
    56. dwt_forcetrxoff(); //disable DW1000
    57. instance_clearevents(); //clear any events
    58. //change state to send a Poll
    59. instance_data[instance].testAppState = TA_TXPOLL_WAIT_SEND ;
    60. instance_data[instance].msg_f.destAddr[0] = 0x1 ;
    61. instance_data[instance].msg_f.destAddr[1] = (GATEWAY_ANCHOR_ADDR >> 8);
    62. instance_data[instance].instanceTimerEn = 0;
    63. instance_data[instance].rangeNumAnc++;
    64. port_EnableEXT_IRQ(); //enable ScenSor IRQ before starting
    65. }
    66. }
    67. else if (instance_data[instance].instanceAddress16 == A1_ANCHOR_ADDR) //A1 ranges to A2 in the 2nd half of last slot
    68. {
    69. if(portGetTickCount() >= instance_data[instance].a1SlotTime)
    70. {
    71. port_DisableEXT_IRQ(); //enable ScenSor IRQ before starting
    72. //anchor1 sends poll to anchor2
    73. instance_data[instance].mode = ANCHOR_RNG; //change to ranging initiator
    74. dwt_forcetrxoff(); //disable DW1000
    75. instance_clearevents(); //clear any events
    76. //change state to send a Poll
    77. instance_data[instance].testAppState = TA_TXPOLL_WAIT_SEND ;
    78. instance_data[instance].msg_f.destAddr[0] = 0x2 ;
    79. instance_data[instance].msg_f.destAddr[1] = (GATEWAY_ANCHOR_ADDR >> 8);

    80. instance_data[instance].instanceTimerEn = 0;
    81. //instance_data[instance].a1SlotTime = 0;
    82. port_EnableEXT_IRQ(); //enable ScenSor IRQ before starting
    83. }
    84. }
    85. }
    86. #endif
    87. }

    88. #if (ANCTOANCTWR == 1) //allow anchor to anchor ranging
    89. else if (instance_data[instance].instanceTimerEn == 0)
    90. {
    91. if((instance_data[instance].mode == ANCHOR) && (instance_data[instance].gatewayAnchor))
    92. {
    93. uint32_t slotTime = portGetTickCount() % instance_data[instance].sframePeriod;
    94. //enable the timer in 1st slot
    95. if(slotTime < instance_data[instance].slotPeriod)
    96. {
    97. instance_data[instance].instanceTimerEn = 1;
    98. }
    99. }
    100. }
    101. #endif
    102. return 0 ;
    103. }
    复制代码

    三、硬件篇

    2.1 硬件

    DW1000是完全集成的单芯片超宽带(UWB)符合IEEE802.15.4-2011标准的低功耗低成本收发器IC。它可用于双向测距或TDOA定位系统定位,精度为10厘米。它还支持高达6.8 Mbps的数据传输,相关的原理图官网有详细说明。整个原理图我放在文文末,喜欢的可以回复下载。


    • 通用软件:Altium Designer
    • 主控芯片:nRF52832
    • 通讯芯片:DWM1000

    4.jpg

    nRF52832外围原理图


    3.jpg

    DW1000外围原理图

    2.2 丝印

    如果有小伙伴不会制作logo的,这里把相关文件上传,以及“鹊桥”的丝印样板。


    • DXP-->Run Script-->Browse
    • 选择目录D:\Altium Design\Examples\Scripts\Delphiscript Scripts\PCB\PCB Logo Creator
    • 打开PCBLogoCreator.PRJSCR


    1.jpg

    效果图1

    1

    1

    效果图2

    5.jpg

    Top Overlay


    游客,如果您要查看本帖隐藏内容请 回复

    丝印.zip (45.23 KB, 下载次数: 11)

    DWM1001_Schematics.zip (560.4 KB, 下载次数: 16)


    主题

    好友

    1727

    积分

    进士

    该用户从未签到

    发表于 2019-8-8 10:02:31 | 显示全部楼层
    期待

    主题

    好友

    60

    积分

    童生

  • TA的每日心情
    开心
    2019-8-31 07:12
  • 签到天数: 2 天

    连续签到: 1 天

    [LV.1]初来乍到

    发表于 2019-8-9 12:39:58 | 显示全部楼层
    厉害啊

    主题

    好友

    5865

    积分

    管理员

    该用户从未签到

    发表于 2019-8-9 13:06:04 | 显示全部楼层
    优秀

    主题

    好友

    115

    积分

    童生

  • TA的每日心情
    开心
    2019-8-19 09:55
  • 签到天数: 3 天

    连续签到: 1 天

    [LV.2]偶尔看看I

    发表于 2019-8-10 11:53:13 | 显示全部楼层

    主题

    好友

    115

    积分

    童生

  • TA的每日心情
    开心
    2019-8-19 09:55
  • 签到天数: 3 天

    连续签到: 1 天

    [LV.2]偶尔看看I

    发表于 2019-8-10 22:07:43 | 显示全部楼层

    后续有更新,谢谢关注!

    主题

    好友

    81

    积分

    童生

  • TA的每日心情
    开心
    2019-8-11 13:37
  • 签到天数: 3 天

    连续签到: 1 天

    [LV.2]偶尔看看I

    发表于 2019-8-11 10:53:15 | 显示全部楼层
    谢谢分享,学习了

    主题

    好友

    115

    积分

    童生

  • TA的每日心情
    开心
    2019-8-19 09:55
  • 签到天数: 3 天

    连续签到: 1 天

    [LV.2]偶尔看看I

    发表于 2019-8-11 15:27:36 | 欢迎您进入-显示全部楼层

    主题

    好友

    2974

    积分

    进士

  • TA的每日心情
    开心
    2017-6-22 18:07
  • 签到天数: 4 天

    连续签到: 1 天

    [LV.2]偶尔看看I

    发表于 2019-8-11 16:49:34 | 显示全部楼层
    谢谢

    主题

    好友

    115

    积分

    童生

  • TA的每日心情
    开心
    2019-8-19 09:55
  • 签到天数: 3 天

    连续签到: 1 天

    [LV.2]偶尔看看I

    发表于 2019-8-12 10:17:55 | 显示全部楼层

    共同学习,共同进步
    您需要登录后才可以回帖 登录 | 立即注册

    关闭

    站长推荐上一条 /4 下一条

    手机版|betway必威

    GMT+8, 2019-12-14 00:03 , Processed in 0.094390 second(s), 21 queries , MemCache On.

    ICP经营许可证 苏B2-20140176 苏ICP备14012660号-2 betway必威官网 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz!

    返回顶部