5295|16

1305

帖子

0

TA的资源

纯净的硅(高级)

楼主
 

【Atmel SAM R21创意大赛周计划】(5) RF学习-简单的点对点 [复制链接]

本帖最后由 yang_alex 于 2015-3-16 22:38 编辑

         这个帖子昨天就写好了,只是验证的程序有些问题,本想解决了再一起写。结果有个网友很??那就先贴出来后面再补充吧。

        无线的网络架构有多种,关键是挑个合适自己项目的。
     

       项目中使用到的无线传输的网络拓扑很简单,点对点就可以了。刚开始的时候想照着文档《Atmel AT02607: Wireless Product Development Using Atmel Studio and ASF》的方法,自己在AtmelStudio中自己添加“AVR?2025 TAL component (Transceiver Abstraction Layer)”。结果添加完TAL component,在配置相关引脚时才发现这家伙有个坑。


         我们知道,SAM R21 实际上是双芯片集成,说白了就是芯片封装内部吧AT86RF233芯片和SAM D21 连起来,封装成一个IC。从下面的图中可以看出,AT86RF233芯片是通过SPI连接到SAM D21 ,占用了PC16、PC18、PC19、PB30、PB31、PB00、PB15、PA20。



但是在上面添加的TAL component中,相关的配置竟然是下面这种:(文件:conf_trx_access.h)

  1. #if (SAMD || SAMR21)
  2. #ifndef AT86RFX_SPI
  3. #define AT86RFX_SPI                     SERCOM0
  4. #define AT86RFX_RST_PIN             PIN_PA23
  5. #define AT86RFX_MISC_PIN           PIN_PA23
  6. #define AT86RFX_IRQ_PIN             PIN_PA22
  7. #define AT86RFX_SLP_PIN             PIN_PA24
  8. #define AT86RFX_SPI_CS              PIN_PA19
  9. #define AT86RFX_SPI_MOSI          PIN_PA16
  10. #define AT86RFX_SPI_MISO          PIN_PA18
  11. #define AT86RFX_SPI_SCK            PIN_PA17
  12. #define AT86RFX_CSD                  PIN_PA23
  13. #define AT86RFX_CPS                  PIN_PA23
  14. #define LED0                                LED0_PIN
复制代码

        还是先找个SAM R21例子程序,在例子程序上改吧。LWMesh-Peer2Peer Application - SAM R21 Xplained Pro这个例子程序就是针对SAM R21 Xplained Pro开发版的,相关端口配置肯定不会错了。
       也确实是正确的,但是相关定义却跑到板定义文件samr21_xplained_pro.h中了。

  1. #define AT86RFX_SPI                       SERCOM4
  2. #define AT86RFX_RST_PIN               PIN_PB15
  3. #define AT86RFX_IRQ_PIN               PIN_PB00
  4. #define AT86RFX_SLP_PIN               PIN_PA20
  5. #define AT86RFX_SPI_CS                PIN_PB31
  6. #define AT86RFX_SPI_MOSI            PIN_PB30
  7. #define AT86RFX_SPI_MISO            PIN_PC19
  8. #define AT86RFX_SPI_SCK              PIN_PC18
  9. #define PIN_RFCTRL1                      PIN_PA09
  10. #define PIN_RFCTRL2                       PIN_PA12
  11. #define RFCTRL_CFG_ANT_DIV       4
复制代码

          我猜测,ATMEL的写例子代码的人也发现了原来的代码不能用。原因估计是SAMD 系列的PC16、PC18、PC19、PB30、PB31、PB00、PB15、PA20没有引出,回头再确认一下吧。如果真是这样,代码中完全可以把两种MCU分开。



         参照文档《AVR2130_LWMesh_Developer_Guide_v1.2.1》,了解相关函数的功能,修改成自己需要的代码。



RF模块初始化

第1步:设置网络地址

NWK_SetAddr(0x0001);

注意:不同节点的网络地址不同,在这个例子里,一个是0x0001,一个是0x0000。

第2步:设置网络ID,也就是 PAN ID  

NWK_SetPanId(0x1234);

第3步:设置无线通讯频率通道

PHY_SetChannel(0x0f);

第4步:设置无线接收状态

PHY_SetRxState(true);

第5步:设置无线通讯安全密码

NWK_SetSecurityKey((uint8_t *)"Security12345678");

第6步:设置无线通讯安全密码

NWK_OpenEndpoint(APP_ENDPOINT, appDataInd);

注意 2~6部分在相同的网络里是一样的。

数据发送很简单,调用下面的函数就可以了。

        NWK_DataReq(&appDataReq);

不过在此之前,需要把准备发送的内容放入发送缓冲区,并配置好发送相关参数。

  1. appDataReq.dstAddr = 1 - APP_ADDR;
  2.         appDataReq.dstEndpoint = APP_ENDPOINT;
  3.         appDataReq.srcEndpoint = APP_ENDPOINT;
  4.         appDataReq.options = NWK_OPT_ENABLE_SECURITY;
  5.         appDataReq.data = appDataReqBuffer;
  6.         appDataReq.size = appUartBufferPtr;
  7.         appDataReq.confirm = appDataConf;
复制代码


数据接收也很简单,调用下面的函数。

static bool appDataInd(NWK_DataInd_t *ind)

不过这个函数需要自己实现。
  1. static bool appDataInd(NWK_DataInd_t *ind)
  2. {
  3.        for (uint8_t i = 0; i < ind->size; i++)
复制代码

任务调度中会用到系统提供的软件定时器,当然,你也可以不用,自己安排调用。

软件定时器

     SYS_TimerStart() – 启动一个软件定时器

     SYS_TimerStop() – 停止一个软件定时器

     SYS_TimerStarted() – 查询软件定时器是否启动


定时到会调用下面的处理程序。

static void appTimerHandler(SYS_Timer_t *timer)

具体内容需要自己实现,一般会把发送数据的函数放在里面。

  1. static void appTimerHandler(SYS_Timer_t *timer)
  2. {
  3.           appSendData();
  4.           (void)timer;
  5. }
复制代码


RF部分功率管理

NWK_Busy()   检查RF模块是否空闲,空闲时才方便进入睡眠。

NWK_SleepReq()  RF模块进入睡眠请求。

NWK_WakeupReq()RF模块唤醒请求。


系统管理

SYS_Init()

SYS_TaskHandler()

用户任务

static void APP_TaskHandler(void)

应用程序框架

  1. <blockquote>int main(void)
复制代码



先写这么多,后面再修改吧。





最新回复

本帖最后由 ljj3166 于 2015-3-18 11:27 编辑 一个case里面就有30w+次循环,再好的编译器折腾出来也至少好几百万条执行语句吧 R21全速运行才48M 然后就没有然后了  详情 回复 发表于 2015-3-18 11:17
点赞 关注
 

回复
举报

1万

帖子

25

TA的资源

版主

沙发
 
问题解决没有?

点评

遇到的问题是: 如果程序中增加一个LED阵列扫描驱动的代码(就几个嵌套for循环,驱动行列开关),就会发现RF通讯反应慢好多,2、3秒后才有反应。如果LED阵列扫描驱动的代码不运行,则即时反应。 因  详情 回复 发表于 2015-3-17 06:45
 
 
 

回复

1305

帖子

0

TA的资源

纯净的硅(高级)

板凳
 

       遇到的问题是:
       如果程序中增加一个LED阵列扫描驱动的代码(就几个嵌套for循环,驱动行列开关),就会发现RF通讯反应慢好多,2、3秒后才有反应。如果LED阵列扫描驱动的代码不运行,则即时反应。 因为用的不是直接中断处理,而是回调函数,估计和这个相关,但还是有些想不通。

点评

虽然内部机制没有仔细研究,但是初步看RF部分是用轮询的方式处理的。这样如果两个地方都有轮询,就会有冲突。  详情 回复 发表于 2015-3-17 11:57
 
 
 

回复

1万

帖子

25

TA的资源

版主

4
 
yang_alex 发表于 2015-3-17 06:45
遇到的问题是:
       如果程序中增加一个LED阵列扫描驱动的代码(就几个嵌套for循环,驱动行列开关),就会发现RF通讯反应慢好多,2、3秒后才有反应。如果LED阵列扫描驱动的代码不运行,则即时反应。 因为用的不是直接中断处理,而是回调函数,估计和这个相关,但还是有些想不通。


虽然内部机制没有仔细研究,但是初步看RF部分是用轮询的方式处理的。这样如果两个地方都有轮询,就会有冲突。

 
 
 

回复

524

帖子

0

TA的资源

一粒金砂(高级)

5
 
可以把用的代码传上来么?这样好分析下原因
 
 
 

回复

2144

帖子

3

TA的资源

五彩晶圆(中级)

6
 
默认的是poll的方式
PHY_TaskHandler中调用phyReadFrame函数

不过从理论上来说不可能会delay这么多,当然了前提是你的led-task没有引入阻塞等
当纯的poll一下led-task应该不会有2-3s吧,在看看。

就怎么安排任务的事情
 
个人签名电工
 
 

回复

3416

帖子

0

TA的资源

纯净的硅(高级)

7
 
个人理解
貌似R21的一些例程貌似直接引用D21的,不过外设配置在samr21_xplained_pro.h做了重新封装
这种相对比较复杂的通信模块,用中断可能实时性会比较好一些
过多的查询和延时,控制器的任务调用比较难掌控。
 
个人签名

So TM what......?

 

 

回复

1305

帖子

0

TA的资源

纯净的硅(高级)

8
 
代码来了
  1. int main(void)
  2. {
  3.         volatile uint16_t k,i,j;       
  4.        
  5.         irq_initialize_vectors();
  6.         #if SAMD || SAMR21
  7.         system_init();
  8.         delay_init();
  9.         #else
  10.         sysclk_init();
  11.         board_init();
  12.         #endif
  13.         SYS_Init();
  14. //        sio2host_init();
  15.         cpu_irq_enable();
  16.        
  17.        
  18.         //! [setup_init]
  19.         configure_extint_channel();
  20.         configure_extint_callbacks();
  21.                
  22.         //! [setup_init]
  23.         configure_adc();
  24.         configure_adc_callbacks();
  25.         //! [setup_init]


  26.         system_interrupt_enable_global();
  27.         //! [setup_init]
  28.        
  29.        
  30.         LED_On(LED0);
  31.        
  32.        
  33.        
  34.        
  35.         Turn_num = 0;
  36.         Turn_ok = 0;
  37.         Display_Direct = 0;
  38.        
  39.        
  40.         while (1) {
  41.                 SYS_TaskHandler();
  42.                 APP_TaskHandler();
  43.                
  44.                 //TODO:: Please write your application code .
  45.                                
  46.                                
  47.                 //! [start_adc_job]
  48.                 adc_read_buffer_job(&adc_instance, adc_result_buffer, ADC_SAMPLES);               
  49.                
  50.                
  51.                 Voltage_bat_s = adc_result_buffer[3]* 5*VOLT_REF / MAX_DIGITAL;  //分压比 5
  52.                
  53.                
  54.                
  55.                 switch ( Display_Direct )   //Display_Direct  //Turn_ok
  56.                 {
  57.                         case 0:            //  <<
  58.                                 for (k = 0;k < 5; k++)
  59.                                 {
  60.                                         for (j = 0;j <20000; j++)
  61.                                         {

  62.                                                 for (i = 0;i < 3; i++)
  63.                                                 {       
  64.                                                         led_row(i);
  65.                                                         led_line(k + i);
  66.                                                         led_line(8);
  67.                                                 }
  68.                                         }
  69.                                 }
  70.                                 break;
  71.                         case 1:                         //  >>

  72.                                 for (k = 5;k > 0; k--)
  73.                                 {
  74.                                         for (j = 0;j <20000; j++)
  75.                                         {                               
  76.                                                 for (i = 0;i < 3; i++)
  77.                                                 {
  78.                                                         led_row(i);
  79.                                                         led_line(k + 1 - i);
  80.                                                         led_line(8);
  81.                                                 }
  82.                                         }
  83.                                 }
  84.                                 break;
  85.                         case 2:                         //  ==
  86.                                 for (j = 0;j <20000; j++)
  87.                                 {
  88.                                         led_row(0);
  89.                                         led_line(8);
  90.                                 }
  91.                                 for (j = 0;j <20000; j++)
  92.                                 {
  93.                                         led_row(0);
  94.                                         led_line(9);
  95.                                 }
  96.                                 break;                                                               
  97.                         case 3:                         //  XX

  98.                                         led_line(8);
  99.                                         break;                       
  100.                         default:
  101.                                         break;                                       
  102.                                
  103.                 }
  104.                
  105.                
  106.                
  107.                
  108.         }
  109. }
复制代码
 
 
 

回复

1305

帖子

0

TA的资源

纯净的硅(高级)

9
 
  1. static void APP_TaskHandler(void)
  2. {
  3.         switch (appState) {
  4.         case APP_STATE_INITIAL:
  5.         {
  6.                 appInit();
  7.                 appState = APP_STATE_IDLE;
  8.         }
  9.         break;

  10.         case APP_STATE_IDLE:
  11.                 break;

  12.         default:
  13.                 break;
  14.         }
  15.        
  16.         if ( Display_Direct == 4)
  17.         {
  18.                 appSendData();
  19.                
  20.                 SYS_TimerStop(&appTimer);
  21.                 SYS_TimerStart(&appTimer);
  22.                
  23.         }
  24.        
  25.        
  26. }
复制代码
 
 
 

回复

2144

帖子

3

TA的资源

五彩晶圆(中级)

10
 
那么多for我能说什么好。。
用timer后台定时吧

点评

正在改定时中断的。 以前以为RF部分是中断方式通讯,主程序又不大,偷懒就用了FOR。  详情 回复 发表于 2015-3-18 17:11
 
个人签名电工
 
 

回复

524

帖子

0

TA的资源

一粒金砂(高级)

11
 
你是在原来例程基础上改的吧,建议看看底层的吧,可以通过计算下哪条语句费时然后一步一步推下去,因为例程考虑的比较全面,很多费时的功能函数都可以省略或用其他方式的,这样再来看看是不是好点。还有就给出的例程看,for语句貌似很多,而且数值较大,也会使动作缓慢下来。

这只是个人建议啦,仅供参考
 
 
 

回复

3416

帖子

0

TA的资源

纯净的硅(高级)

12
 
本帖最后由 ljj3166 于 2015-3-18 11:27 编辑

一个case里面就有30w+次循环,再好的编译器折腾出来也至少好几百万条执行语句吧
R21全速运行才48M
然后就没有然后了
 
个人签名

So TM what......?

 

 

回复

1305

帖子

0

TA的资源

纯净的硅(高级)

13
 
lyzhangxiang 发表于 2015-3-18 02:22
那么多for我能说什么好。。
用timer后台定时吧



正在改定时中断的。  以前以为RF部分是中断方式通讯,主程序又不大,偷懒就用了FOR。

 
 
 

回复

1305

帖子

0

TA的资源

纯净的硅(高级)

14
 
改成了定时器中断回调方式。

但问题来了

如果回调函数里没有条件判断语句(if 或 switch),运行正常,如果有,程序就不知跑哪去了。

有个提示,我看不懂。请大家指点。谢谢!




 
 
 

回复

1305

帖子

0

TA的资源

纯净的硅(高级)

15
 
本帖最后由 yang_alex 于 2015-3-19 04:51 编辑

发现前面没说对,屏蔽掉条件判断语句,仅加一个赋值语句也不行。去掉就正常了。奇怪!!

 
 
 

回复

1305

帖子

0

TA的资源

纯净的硅(高级)

16
 
把RF部分屏蔽后试了试,问题依旧存在。  估计是回调函数需要有什么地方需要注意,我忽略了。
 
 
 

回复

1305

帖子

0

TA的资源

纯净的硅(高级)

17
 
for 循环改成定时器中断方式,果然一切正常。看来如果设计时能多想想,还是可以少让MCU忙活的。

  1. #include <asf.h>
  2. #include "tc_init.h"
  3. #include "conf_tc_timer.h"

  4. extern uint8_t Display_Direct,Row_num,Line_num;

  5. //! [module_inst]
  6. struct tc_module tc_instance_row,tc_instance_line;
  7. //! [module_inst]
  8. /*
  9. void tc_callback_to_led(struct tc_module *const module_inst)
  10. {
  11.        
  12.                 port_pin_toggle_output_level(LED0_PIN);
  13. }
  14. */
  15. //! [callback_funcs]
  16. void tc_callback_to_row(struct tc_module *const module_inst)
  17. {
  18.         uint8_t  n = 0;               
  19.         port_pin_toggle_output_level(LED0_PIN);
  20.         switch ( Display_Direct )
  21.         {
  22.                 case 0:
  23.                                 n = Row_num + Line_num - 1;
  24.                                 led_line(8);
  25.                                 led_row(Row_num);
  26.                                 led_line( n );
  27.                                 Row_num++;
  28.                                 if (Row_num > 2)
  29.                                 {
  30.                                         Row_num = 0;
  31.                                 }
  32.                                 break;
  33.                 case 1:       
  34.                                 led_line(8);
  35.                                 led_row(Row_num);
  36.                                 led_line(Line_num - Row_num);
  37.                                 Row_num++;                               
  38.                                 if (Row_num > 2)
  39.                                 {
  40.                                         Row_num = 0;
  41.                                 }                       
  42.                                 break;
  43.                 case 2:       
  44.                                 led_row(0);
  45.                                 led_line(8 + ( Line_num % 2 ));                                                                       
  46.                                 break;
  47.                                
  48.                 case 3:        //  XX
  49.                                 led_line(8);
  50.                                 Row_num = 2;                               
  51.                                 break;
  52.                 default:
  53.                                 Row_num = 2;
  54.                                 break;       
  55.         }

  56. }

  57. void tc_callback_to_line(struct tc_module *const module_inst)
  58. {
  59.         port_pin_toggle_output_level(LED0_PIN);       
  60.         switch ( Display_Direct )   
  61.         {
  62.                 case 0:
  63.                                 led_line(8);
  64.                                 if (Line_num > 6)
  65.                                 {
  66.                                         Line_num = 0;
  67.                                 }       
  68.                                 Line_num++;
  69.                                 break;                               
  70.                 case 1:
  71.                                 led_line(8);
  72.                                 if (Line_num < 1)
  73.                                 {
  74.                                         Line_num = 7;
  75.                                 }       
  76.                                 Line_num--;
  77.                                 break;       
  78.                 case 2:
  79.                                 if (Line_num > 6)
  80.                                 {
  81.                                         Line_num = 0;
  82.                                 }       
  83.                                 Line_num++;
  84.                                 break;                                                                               
  85.                 default:               
  86.                                 break;
  87.         }               
  88.         Row_num = 0;
  89. }
  90. //! [callback_funcs]

  91. //! [setup]
  92. void configure_tc(void)
  93. {
  94.         //! [setup_config]
  95.         struct tc_config config_tc;
  96.         //! [setup_config]
  97.         //! [setup_config_defaults]
  98.         tc_get_config_defaults(&config_tc);
  99.         //! [setup_config_defaults]

  100.         //! [setup_change_config]
  101.         config_tc.counter_size = TC_COUNTER_SIZE_8BIT;
  102.         config_tc.clock_source = GCLK_GENERATOR_1;
  103.         config_tc.clock_prescaler = TC_CLOCK_PRESCALER_DIV256;
  104.         config_tc.counter_8_bit.period = 255;
  105. //        config_tc.counter_8_bit.compare_capture_channel[0] = 10;
  106. //        config_tc.counter_8_bit.compare_capture_channel[1] = 80;
  107.         //! [setup_change_config]

  108.         //! [setup_set_config]
  109.        
  110. //        tc_init(&tc_instance, CONF_TC_MODULE, &config_tc);       
  111.        
  112.         tc_init(&tc_instance_row, CONF_TC_MODULE, &config_tc);


  113.         config_tc.counter_size = TC_COUNTER_SIZE_16BIT;
  114.         config_tc.clock_source = GCLK_GENERATOR_1;       
  115.         config_tc.clock_prescaler = TC_CLOCK_PRESCALER_DIV64;       
  116.         config_tc.counter_16_bit.value = 255;       
  117. //        config_tc.counter_16_bit.compare_capture_channel[0] = 10;
  118. //        config_tc.counter_16_bit.compare_capture_channel[1] = 80;       
  119.        
  120.        
  121.         tc_init(&tc_instance_line, CONF_TC_MODULE1, &config_tc);       
  122.        
  123.        
  124.         //! [setup_set_config]

  125.         //! [setup_enable]
  126.        
  127. //        tc_enable(&tc_instance);
  128.                
  129.         tc_enable(&tc_instance_row);
  130.        
  131.         tc_enable(&tc_instance_line);
  132.         //! [setup_enable]
  133. }

  134. void configure_tc_callbacks(void)
  135. {
  136.         //! [setup_register_callback]
  137.         tc_register_callback(&tc_instance_row, tc_callback_to_row,
  138.         TC_CALLBACK_OVERFLOW);
  139.        
  140.         tc_register_callback(&tc_instance_line, tc_callback_to_line,
  141.         TC_CALLBACK_OVERFLOW);
  142. //        tc_register_callback(&tc_instance_row, tc_callback_to_row,
  143. //        TC_CALLBACK_CC_CHANNEL0);
  144. //        tc_register_callback(&tc_instance_row, tc_callback_to_line,
  145. //        TC_CALLBACK_CC_CHANNEL1);
  146.         //! [setup_register_callback]

  147.         //! [setup_enable_callback]
  148.         tc_enable_callback(&tc_instance_row, TC_CALLBACK_OVERFLOW);
  149.         tc_enable_callback(&tc_instance_line, TC_CALLBACK_OVERFLOW);       
  150.        
  151. //        tc_enable_callback(&tc_instance_row, TC_CALLBACK_CC_CHANNEL0);
  152. //        tc_enable_callback(&tc_instance_row, TC_CALLBACK_CC_CHANNEL1);
  153.         //! [setup_enable_callback]
  154. }
复制代码
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/7 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表