6614|17

2144

帖子

3

TA的资源

五彩晶圆(中级)

楼主
 

【 Atmel创意大赛作品提交】+基于SAM R21的6LoWPAN低功耗网络平台研究 [复制链接]

 
汇总帖子,方便阅读,可以配合视频一起看,感谢各位的支持。


【Atmel SAM R21创意大赛周计划】+ GPU运行

【Atmel SAM R21创意大赛周计划】+ 6LoWPAN之应用层CoAP协议







可以打开声音,录制过程中加了一些解说。

一些图片































1、硬件介绍,6LoWPAN整体介绍

2、网关结构,openwrt路由器+R21开发板

3、显示终端,FT800 GPU+R21开发板

4、网关上电,跟节点地址aaaa::11

5、显示终端启动信息,设备地址aaaa::22

6、控制板上电,设备地址aaaa::33

7、边界路由器SSID

8、网络节点联通性测试

9、网络邻居节点打印

10、网络组播控制功能,aaaa::33按钮SW0控制aaaa::22的LED0

11、根节点WEB服务演示,路由和邻居信息

12、COAP相关演示,REST构架的东西,GET/POST     浏览器输入coap:\\[aaaa::33]

13、显示终端coap应用协议演示     浏览器输入coap:\\[aaaa::22]

14、GPU一些演示,用按键切换,演示终端只有一颗控制器就是R21       GPU仅仅是一个协处理器,细节参考我之前的帖子和FTDI的官网FT800

字幕没有转换进去,视频太大了,试了两个软件都没成功。。字幕文件见文件类型为srt的附件


zimu.rar (750 Bytes, 下载次数: 9)


来总体看一下这款芯片
处理器:
ARM Cortex-M0+ CPU最大到48MHz
单周期硬件乘法器----有用的自然很有用,用不上基本上不关心他
微型调试缓存----这玩意切实很有用,有机会开贴说说怎么用


存储器:
64/128/256KB Flash---如我前面所说,Atmel不愧是很早做Flash的,当年的AT45DBxx,哪个产品上没有,这个内置的Flash很有这种味道,支持单row擦写操作,256Byte为一个row,每个row由4个page组成,每个page是64byte

8/16/32KB SRAM,这个就不细说了,总体看起来非常有优势,最大能到32KB,可选性大

时钟:
内部和外部时钟---8MHz/32768KHz
DFFL---48MHz
FDPLL--96MHz

外设:
这玩意太多了,说点特色的吧
ADC---12位350Kbps速度,这个速度在M0内核中算是最高的了

USB---全速12MHz,也不错,仔细看了EP个数,16个。不得不说确认不错,不信你去看看st或者别家的给你8个就不错了,印象里Microchip也是有16个的不过是在PIC系列上。或者你会怀疑要这么多干啥,呵呵,一般情况下8个足够了,不过你要是专业做相关USB开发的不用说你懂的,8个经常不够用,模拟一个CDC需要3个EP,如果你需要模拟出4个的话,起码要12个EP的。。

SERCOM---这个不细说了,前面我有仔细分析

PTC---这个要说一下,最大支持48通道电容触摸,Atmel不愧是专业做Qtouch,据我所知塞朴拉斯和TI的触摸方案都没这么自由,只能说给力了。当然官方提供的一系列的Qtouch的库也是完美支持用户开发。前段时间在网上看了Atmel的一个qtouch演示,还是挺震惊的,考虑全面。对高温/高湿环境进行了严格的测试和自保护功能,高湿度会自动检测并且自锁。演示采用的是那种喷气式电熨斗。

RADIO--太强了,太难说了,看了好几遍手册,这个驱动写起来最费劲6lowpan的驱动框架比较完善了。有机会开贴单独






很幸运最近能试用R21的开发套件,目前已经能运行contiki了,关于移植的细节后面要好好的说说,涉及的外设还是挺多的,基本上需要结合数据手册和官方的drivers下面的quickstart就能搞定了,虽然这次我选择的开发环境是IAR而并非官方的AtmelStudio,原因只是因为这个项目有点复杂,还是用自己熟悉的开发环境好一些。不过AtmelStudio还是相当不错的一款IDE了,可以说是后面的一种趋势吧,基本上和开源界的Eclipse很像。当然不止是IDE了,还有集成的AFS开发框架,真的很不错哦,里面包含的各种插件,开发者基本上不需要太关心如何去关联这些第三方的软件包,直接在AtmelStudio中使用可视化的方式就能够把这些软件包包含到自己的项目中,我认为这在将来一定是一个趋势也是一种必然,当然了很有可能是arm的mbed或者是atmel的arduino触发的一种新的开发趋势。

说完IDE继续说AFS软件构架包,这是一个好东西,可以说是必不可少的开发利器,基本上支持atmel全系列的mcu产品和demo板子。说到板子还想提一下板子上自带的CMSIS-DAP的调试器可以说也是未来的一个趋势,在老外眼里没有什么山寨的jlink/ulink这些对他们来说是很奢侈的,当然IAR/MDK这些都是一样的。渐渐的中国这几年也会有这种保护知识产权的趋势。这种板载的调试器可以说以后是比不可少的东西,基本上现在所有的官方的评估板都有这种支持。继续说afs最好还是打开它的目录看一下,东西有点多。根目录下有针对不同mcu的目录基本上是和外设相关的,还有两个common的目录里面都是一些通用的东西,比如延时函数,stdio,一些相关的服务等。重点看一下thirdpart,这玩意很多厂家都有的最早接触的是ti的开发包中的,印象比较深刻的是有freertos,这也会是一个趋势,更多的人会去使用这种开源的os而不仅仅局限于ucos这种。截个图吧,东西就这么多了,基本上都很有用。



继续说SAMR21/SAMD21的外设吧,关于时钟部分充分考虑到低功耗,可以说是花了不少的精力去考虑如何更加合理的分配,自然让用于感觉到更加复杂,其实也不算复杂,看clock的arch和sam0\drivers\system\clock\clock_samd21_r21\clock.c文件就够了,当然等你熟悉了只需要关心SAMR21_Xplained_Pro\Board_Config\conf_clocks.h文件就可以了,基本上和stm32那套东西很像了,只是结构不太一样,不熟悉而已。
其实配置时钟到48MHz还是需要花一些时间来摸索一下的,看到有不少网友折腾过,等你折腾过就知道了
我的配置如下,大家参考下,配置到48MHz就是这么简单,修改这两个地方就好了
  • /* DFLL closed loop mode configuration */
  • #  define CONF_CLOCK_DFLL_SOURCE_GCLK_GENERATOR         GCLK_GENERATOR_1
  • #  define CONF_CLOCK_DFLL_MULTIPLY_FACTOR               4
  • #  define CONF_CLOCK_DFLL_QUICK_LOCK                    true
  • #  define CONF_CLOCK_DFLL_TRACK_AFTER_FINE_LOCK         true
  • #  define CONF_CLOCK_DFLL_KEEP_LOCK_ON_WAKEUP           true
  • #  define CONF_CLOCK_DFLL_ENABLE_CHILL_CYCLE            true
  • #  define CONF_CLOCK_DFLL_MAX_COARSE_STEP_SIZE          (0x1f / 4)
  • #  define CONF_CLOCK_DFLL_MAX_FINE_STEP_SIZE            (0xff / 4)

[color=rgb(51, 102, 153) !important]复制代码



  • /* Configure GCLK generator 0 (Main Clock) */
  • #  define CONF_CLOCK_GCLK_0_ENABLE                      true
  • #  define CONF_CLOCK_GCLK_0_RUN_IN_STANDBY              false
  • #  define CONF_CLOCK_GCLK_0_CLOCK_SOURCE                SYSTEM_CLOCK_SOURCE_DFLL
  • #  define CONF_CLOCK_GCLK_0_PRESCALER                   1
  • #  define CONF_CLOCK_GCLK_0_OUTPUT_ENABLE               false

[color=rgb(51, 102, 153) !important]复制代码



继续说其他外设,关于systick恩这玩意是ARM规定的所以还是蛮通用的,基本上都是一样的,我想这也是ARM出这些core的初衷吧,以后将会有更多统一的外设而不仅仅是core,这也是一个大趋势。一般会把这个systick作为定时器使用或者延时用,在atmel的afs中就提供了systick用于延时的例子在\common2\services\delay\sam0\systick_counter.c这个文件就是了,当然还提供了一个通用的方式和msp430的__delay_cycles是一致的或者说这里更直白的告诉你如何自行实现这个函数吧。先看看我的systick函数在来分析官方的那个通用延时吧,参考野火的fsl m0库写法。
  • /**
  • * @brief  systick_delay
  • * @note   SysTick延时函数
  • * @param  none
  • * @retval none
  • */
  • void systick_delay(uint32_t time)
  • {
  •     if (time == 0) {
  •         return;
  •     }
  •     /* 24位 */
  •     if (time <= SysTick_LOAD_RELOAD_Msk) {
  •         /*
  •          * 关systick,清标志位
  •          * 设置延时时间
  •          * 清空计数器
  •          */
  •         SysTick->CTRL   = 0x00;
  •         SysTick->LOAD   = time;
  •         SysTick->VAL    = 0x00;
  •         SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk;
  •         /* 等待时间到 */
  •         while( !(SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk));
  •     }
  • }
  • /**
  • * @brief  systick_timing
  • * @note   SysTick定时函数
  • * @param  none
  • * @retval none
  • */
  • void systick_timing(uint32_t time)
  • {
  •     if (time <= SysTick_LOAD_RELOAD_Msk) {
  •         SysTick->CTRL = 0x00;
  •         /* 设置延时时间 */
  •         SysTick->LOAD = time;
  •         /* 设置优先级 */
  •         NVIC_SetPriority (SysTick_IRQn, (1 << __NVIC_PRIO_BITS) - 1);
  •         /* 清空计数器 */
  •         SysTick->VAL  = 0x00;
  •         SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk;
  •     }
  • }

[color=rgb(51, 102, 153) !important]复制代码




好吧,继续说到那个通用的延时函数,目录在\common2\services\delay\sam0\cycle_counter.c
  • OPTIMIZE_HIGH
  • RAMFUNC
  • void portable_delay_cycles(unsigned long n)
  • {
  •         UNUSED(n);
  •         __asm (
  •                 "loop: DMB        \n"
  • #ifdef __ICCARM__
  •                 "SUBS r0, r0, #1 \n"
  • #else
  •                 "SUB r0, r0, #1 \n"
  • #endif
  •                 "CMP r0, #0  \n"
  •                 "BNE loop         "
  •         );
  • }

[color=rgb(51, 102, 153) !important]复制代码

关于OPTIMIZE_HIGH和RAMFUNC留着给大家自己学习吧,不得不说现在IDE越做越好,让工程师都变得低能了不少,直接一个RAMFUNC就把函数放到RAM中执行了,哎,殊不知还需要实现拷贝函数。在IAR中就是我们熟悉的__ramfunc。跟多的delay细节参考这个路径下的cycle_counter.c和cycle_counter.h文件吧,毕竟是点评不好深入分析。




继续说sercom吧,这玩意呵呵,以前使用过富士通的m3,那是第一次接触这种外设,只能说是高级了。在fujitsu而言被他们称为MFS还有一个类似的东西是定时器被称为MFT。哎,这东西就一个字灵活好用,自由。富士通最大支持8个串口,还是比较给力的。当然了atmel是我在mcu产品中第二个使用这种外设的,暂时不去追究他和Fujitsu哪个更早,只是从我的认知过程来看。继续说说这种外设的驱动,不得不说,现在我算是有一些认可了,以前Fujitsu我看这种外设我总是去把他和stm32去比较,怎么没别人的写的那么好呢。哎,觉今是而昨非啊,这种复杂的外设不能做的那么简单,这个驱动人家也是花了不少心思来做了。恩,还要说说驱动本身,不管是atmel还是Fujitsu都是采用的linux的风格,基本上都是那套read/write,真正使用过这个外设的同伴会知道,这驱动在中断上给你做了一层封装,有个缓冲当你配置为中断模式后会自动进入中断把你的数据缓存起来,当你要使用的时候直接调用read类似的函数就行了,同时还支持用户设置回调函数,让你可以做类似在中断中做一些相关的事情。不过倒不是真实的中断回调hock函数,而仅仅是在你调用read类似的函数的时候才会被调用,说来也好,这种方式你仔细想想,比通常的方式倒还优越不少,不想过多分析了,太辛苦。当然write也是支持回调函数的,这样可以直接把闪灯放置到回调hock中这样可以实现以下场景,当你的485数据写数据的时候需要闪灯指示,那这种是在好不过的了。我的配置函数,使用的板子默认的I2C接口,建议大家用这种口来试试,会有不少收获,而不仅仅是板载原生支持的配置,忘记说了针对串口中断接收,做法是开启回调函数,设置回调函数,同时一定要注意轮询read类似函数才可以,针对atmel我调用的是uart_recv_process();。
  • /**
  • * brief  slip_arch_init
  • * note   SLIP初始化移植接口
  • * param  None
  • * retval None
  • */
  • void slip_arch_init(unsigned long ubr)
  • {
  •         struct usart_config usart_conf;
  •         usart_get_config_defaults(&usart_conf);
  •         usart_conf.mux_setting      = CONF_SLIP_MUX_SETTING;
  •         usart_conf.pinmux_pad0      = CONF_SLIP_PINMUX_PAD0;
  •         usart_conf.pinmux_pad1      = CONF_SLIP_PINMUX_PAD1;
  •         usart_conf.pinmux_pad2      = CONF_SLIP_PINMUX_PAD2;
  •         usart_conf.pinmux_pad3      = CONF_SLIP_PINMUX_PAD3;
  •     if (ubr) {
  •         usart_conf.baudrate     = ubr;
  •     } else {
  •         usart_conf.baudrate     = CONF_SLIP_BAUDRATE;
  •     }
  •         usart_serial_init(&uart_module, CONF_SLIP_USART_MODULE, &usart_conf);
  •         usart_enable(&uart_module);
  •     usart_register_callback(&uart_module, usart_read_callback, USART_CALLBACK_BUFFER_RECEIVED);
  •     usart_enable_callback(&uart_module, USART_CALLBACK_BUFFER_RECEIVED);
  • }

[color=rgb(51, 102, 153) !important]复制代码


  • /**
  • * brief  usart_read_callback
  • * note   UART读取回调函数--类似中断(采用官方驱动的回调机制,需要轮询线程配合)
  • * param  None
  • * retval None
  • */
  • void usart_read_callback(const struct usart_module *const usart_module)
  • {
  •         unsigned char c;
  •     c = RX_BUF[0];
  •     slip_input_byte(c);
  • }


[color=rgb(51, 102, 153) !important]复制代码



其他外设,继续说吧。RTIME也就是关于TC定时器的使用,还有关于NVM的使用。后面继续说吧,也压压楼看看运气吧,


继续说NVM,不得不说atmel是做flash的,这玩意考虑的很全面,有点当年at45dbxxx的感觉,到目前为止我没见过哪个MCU内置的flash是全区支持这种擦写操作的,不得不说就是给力。这里说一下R21和D21是一样的仅仅多了一个RADIO所以不用担心一致性。

* 针对SAMR21G18 NVM存储结构确定,Flash一共256K
* 页大小64Bytes,页数量4096,程序区128K,剩余128K用于文件系统
* SAMR21G18 NVM支持的擦除方式为ROW擦除,4个页为一个ROW,所以最小的擦除单位是256Byte


目前我已经在他的NVM上实现了微型日志文件系统的移植工作,支持擦写磨损均衡等,主要是采用垃圾回收和链表结构来实现的。
XMEM写驱动,已经测试过的,还要说说官方自带的drivers的事情,恩,这个驱动很不错,不要试图和stm32的库来比较,没得比,他是优秀的,不要怀疑他,看起来乱,不会用,不方便,我只好说,是你不懂用,水平low千万别怪别人的东西不好。
重要的路径\sam0\utils\cmsis\samr21\include\instance\nvmctrl.h这个文件很重要,相关外设都会有类似的子头文件,需要引起注意,多看他就好了。
  • /**
  • * @brief   xmem_pwrite
  • * @note    XMEM写操作--addr由上层控制为ROW地址对齐
  • * @param   none
  • * @retval  none
  • */
  • int xmem_pwrite(const void *_buf, int size, unsigned long addr)
  • {
  •     uint8_t *bufPtr;
  •     int  sizeCur, sizePae;
  •     enum status_code error_code;
  •     if (size > NVMCTRL_ROW_SIZE) {
  •         PRINTF("xmem_pwrite size too big\r\n");
  •     }
  •     do {
  •                 error_code = nvm_erase_row(addr);
  •         } while (error_code == STATUS_BUSY);
  •     /*
  •      * 注意此次的写操作是在本次的ROW对齐地址范围内
  •      * 函数nvm_write_buffer实现在PAGE对齐地址范围内写操作
  •      */
  •     bufPtr  = (uint8_t*)_buf;
  •     sizeCur = size;
  •     while (sizeCur > 0) {
  •         sizePae = NVMCTRL_PAGE_SIZE - addr%NVMCTRL_PAGE_SIZE;
  •         sizePae = (sizeCur > NVMCTRL_PAGE_SIZE) ? sizePae : sizeCur;
  •         do {
  •             error_code = nvm_write_buffer(addr, bufPtr, sizePae);
  •         } while (error_code == STATUS_BUSY);
  •         bufPtr  = bufPtr  + sizePae;
  •         addr    = addr    + sizePae;
  •         sizeCur = sizeCur - sizePae;
  •     }
  •     return size;
  • }

[color=rgb(51, 102, 153) !important]复制代码

\sam0\utils\cmsis\samr21\include\instance\nvmctrl.h的一些细节,暴露给大家
  • /* ========== Instance parameters for NVMCTRL peripheral ========== */
  • #define NVMCTRL_AUX0_ADDRESS        (NVMCTRL_USER_PAGE_ADDRESS + 0x00004000)
  • #define NVMCTRL_AUX1_ADDRESS        (NVMCTRL_USER_PAGE_ADDRESS + 0x00006000)
  • #define NVMCTRL_AUX2_ADDRESS        (NVMCTRL_USER_PAGE_ADDRESS + 0x00008000)
  • #define NVMCTRL_AUX3_ADDRESS        (NVMCTRL_USER_PAGE_ADDRESS + 0x0000A000)
  • #define NVMCTRL_CLK_AHB_ID          4
  • #define NVMCTRL_FACTORY_WORD_IMPLEMENTED_MASK 0xC0000007FFFFFFFF
  • #define NVMCTRL_FLASH_SIZE          (NVMCTRL_PAGES*NVMCTRL_PAGE_SIZE)
  • #define NVMCTRL_LOCKBIT_ADDRESS     (NVMCTRL_USER_PAGE_ADDRESS + 0x00002000)
  • #define NVMCTRL_PAGES               4096
  • #define NVMCTRL_PAGE_HW             (NVMCTRL_PAGE_SIZE/2)
  • #define NVMCTRL_PAGE_SIZE           (1<#define NVMCTRL_PAGE_W              (NVMCTRL_PAGE_SIZE/4)
  • #define NVMCTRL_PMSB                3
  • #define NVMCTRL_PSZ_BITS            6
  • #define NVMCTRL_ROW_PAGES           4
  • #define NVMCTRL_ROW_SIZE            (NVMCTRL_PAGE_SIZE*NVMCTRL_ROW_PAGES)
  • #define NVMCTRL_TEMP_LOG_ADDRESS    (NVMCTRL_USER_PAGE_ADDRESS + 0x00006030)
  • #define NVMCTRL_USER_PAGE_ADDRESS   (FLASH_ADDR + NVMCTRL_USER_PAGE_OFFSET)
  • #define NVMCTRL_USER_PAGE_OFFSET    0x00800000
  • #define NVMCTRL_USER_WORD_IMPLEMENTED_MASK 0xC01FFFFFFFFFFFFF

[color=rgb(51, 102, 153) !important]复制代码


[color=rgb(51, 102, 153) !important]


最新回复

make  详情 回复 发表于 2015-5-19 18:48

赞赏

3

查看全部赞赏

点赞 关注
个人签名电工
 

回复
举报

940

帖子

0

TA的资源

纯净的硅(高级)

沙发
 
 
 
 

回复

2144

帖子

3

TA的资源

五彩晶圆(中级)

板凳
 
继续说NVM,不得不说atmel是做flash的,这玩意考虑的很全面,有点当年at45dbxxx的感觉,到目前为止我没见过哪个MCU内置的flash是全区支持这种擦写操作的,不得不说就是给力。这里说一下R21和D21是一样的仅仅多了一个RADIO所以不用担心一致性。

* 针对SAMR21G18 NVM存储结构确定,Flash一共256K
* 页大小64Bytes,页数量4096,程序区128K,剩余128K用于文件系统
* SAMR21G18 NVM支持的擦除方式为ROW擦除,4个页为一个ROW,所以最小的擦除单位是256Byte


目前我已经在他的NVM上实现了微型日志文件系统的移植工作,支持擦写磨损均衡等,主要是采用垃圾回收和链表结构来实现的。
XMEM写驱动,已经测试过的,还要说说官方自带的drivers的事情,恩,这个驱动很不错,不要试图和stm32的库来比较,没得比,他是优秀的,不要怀疑他,看起来乱,不会用,不方便,我只好说,是你不懂用,水平low千万别怪别人的东西不好。
重要的路径\sam0\utils\cmsis\samr21\include\instance\nvmctrl.h这个文件很重要,相关外设都会有类似的子头文件,需要引起注意,多看他就好了。
  • /**
  • * @brief   xmem_pwrite
  • * @note    XMEM写操作--addr由上层控制为ROW地址对齐
  • * @param   none
  • * @retval  none
  • */
  • int xmem_pwrite(const void *_buf, int size, unsigned long addr)
  • {
  •     uint8_t *bufPtr;
  •     int  sizeCur, sizePae;
  •     enum status_code error_code;
  •     if (size > NVMCTRL_ROW_SIZE) {
  •         PRINTF("xmem_pwrite size too big\r\n");
  •     }
  •     do {
  •                 error_code = nvm_erase_row(addr);
  •         } while (error_code == STATUS_BUSY);
  •     /*
  •      * 注意此次的写操作是在本次的ROW对齐地址范围内
  •      * 函数nvm_write_buffer实现在PAGE对齐地址范围内写操作
  •      */
  •     bufPtr  = (uint8_t*)_buf;
  •     sizeCur = size;
  •     while (sizeCur > 0) {
  •         sizePae = NVMCTRL_PAGE_SIZE - addr%NVMCTRL_PAGE_SIZE;
  •         sizePae = (sizeCur > NVMCTRL_PAGE_SIZE) ? sizePae : sizeCur;
  •         do {
  •             error_code = nvm_write_buffer(addr, bufPtr, sizePae);
  •         } while (error_code == STATUS_BUSY);
  •         bufPtr  = bufPtr  + sizePae;
  •         addr    = addr    + sizePae;
  •         sizeCur = sizeCur - sizePae;
  •     }
  •     return size;
  • }

[color=rgb(51, 102, 153) !important]复制代码

\sam0\utils\cmsis\samr21\include\instance\nvmctrl.h的一些细节,暴露给大家
  • /* ========== Instance parameters for NVMCTRL peripheral ========== */
  • #define NVMCTRL_AUX0_ADDRESS        (NVMCTRL_USER_PAGE_ADDRESS + 0x00004000)
  • #define NVMCTRL_AUX1_ADDRESS        (NVMCTRL_USER_PAGE_ADDRESS + 0x00006000)
  • #define NVMCTRL_AUX2_ADDRESS        (NVMCTRL_USER_PAGE_ADDRESS + 0x00008000)
  • #define NVMCTRL_AUX3_ADDRESS        (NVMCTRL_USER_PAGE_ADDRESS + 0x0000A000)
  • #define NVMCTRL_CLK_AHB_ID          4
  • #define NVMCTRL_FACTORY_WORD_IMPLEMENTED_MASK 0xC0000007FFFFFFFF
  • #define NVMCTRL_FLASH_SIZE          (NVMCTRL_PAGES*NVMCTRL_PAGE_SIZE)
  • #define NVMCTRL_LOCKBIT_ADDRESS     (NVMCTRL_USER_PAGE_ADDRESS + 0x00002000)
  • #define NVMCTRL_PAGES               4096
  • #define NVMCTRL_PAGE_HW             (NVMCTRL_PAGE_SIZE/2)
  • #define NVMCTRL_PAGE_SIZE           (1<#define NVMCTRL_PAGE_W              (NVMCTRL_PAGE_SIZE/4)
  • #define NVMCTRL_PMSB                3
  • #define NVMCTRL_PSZ_BITS            6
  • #define NVMCTRL_ROW_PAGES           4
  • #define NVMCTRL_ROW_SIZE            (NVMCTRL_PAGE_SIZE*NVMCTRL_ROW_PAGES)
  • #define NVMCTRL_TEMP_LOG_ADDRESS    (NVMCTRL_USER_PAGE_ADDRESS + 0x00006030)
  • #define NVMCTRL_USER_PAGE_ADDRESS   (FLASH_ADDR + NVMCTRL_USER_PAGE_OFFSET)
  • #define NVMCTRL_USER_PAGE_OFFSET    0x00800000
  • #define NVMCTRL_USER_WORD_IMPLEMENTED_MASK 0xC01FFFFFFFFFFFFF

[color=rgb(51, 102, 153) !important]复制代码


[color=rgb(51, 102, 153) !important]


 
个人签名电工
 
 

回复

3416

帖子

0

TA的资源

纯净的硅(高级)

4
 
nice
来围观一下神作
 
个人签名

So TM what......?

 

 

回复

2144

帖子

3

TA的资源

五彩晶圆(中级)

5
 
ljj3166 发表于 2015-3-11 12:21
nice
来围观一下神作


  哇  评了好多分啊 ,非常感谢

 
个人签名电工
 
 

回复

3416

帖子

0

TA的资源

纯净的硅(高级)

6
 
lyzhangxiang 发表于 2015-3-11 12:39
哇  评了好多分啊 ,非常感谢



好东西,肯定要支持。向大神学习
 
个人签名

So TM what......?

 

 

回复

1297

帖子

2

TA的资源

纯净的硅(中级)

7
 
很厉害啊!!!
 
 
 

回复

35

帖子

0

TA的资源

一粒金砂(中级)

8
 
编程很厉害
 
个人签名监控工程
 
 

回复

2453

帖子

19

TA的资源

五彩晶圆(中级)

9
 
ECG信号怎么产生的?
 
个人签名    懒得很
 
 

回复

1403

帖子

1

TA的资源

纯净的硅(中级)

10
 
赞一个~~
 
个人签名HELLO_WATER
 
 

回复

1149

帖子

3

TA的资源

五彩晶圆(初级)

11
 
不错不错,赞一个~~~~~~~~~
 
个人签名construction complete!
 
 

回复

2144

帖子

3

TA的资源

五彩晶圆(中级)

12
 
zca123 发表于 2015-3-11 14:10
ECG信号怎么产生的?
ECG信号是模拟的数据哦,不是真实的,回头贴上代码



 
个人签名电工
 
 

回复

2144

帖子

3

TA的资源

五彩晶圆(中级)

13
 
zca123 发表于 2015-3-11 14:10
ECG信号怎么产生的?

贴个代码,ECG模拟


  1. static FT8   beats_Incr[10] = {-10,10,5,-5,-20,20,12,-12,-5,5};
复制代码


  1. /**
  2. * brief  Heartbeat
  3. * note   心率
  4. * param  None
  5. * retval None
  6. */
  7. FTVOID Heartbeat(FTVOID)
  8. {
  9.     x += rate;
  10.     if (x > QVGA_WIDTH) {
  11.         x       = 0;
  12.         temp_p  = 0;
  13.         temp_y  = 0;
  14.         y       = QVGA_HIGH/2;
  15.         en      = 0;
  16.         temp_x  = 0;
  17.     }
  18.     tx = 5*rate;
  19.     tx = ((temp_p+1)*tx) + temp_p*temp_x;
  20.     if (tx <= x){
  21.         if (0 == en) en = 1;
  22.     }
  23.    
  24.     if (en == 1){       
  25.         if (y != beats[temp_y]) {
  26.             y += beats_Incr[temp_y] * 5;
  27.             if (y==(QVGA_HIGH/2)+beats_Incr[4] * 5) {
  28.                 Play_Sound((108<<8 | 0x10), 100);
  29.             }
  30.         } else {
  31.             temp_y++;
  32.             if (temp_y > 9) {       
  33.                 temp_y  = 0;   
  34.                 temp_p++;
  35.                 en      = 0;  
  36.                 temp_x  = x - tx;
  37.             }
  38.         }
  39.     }  
  40.     HAL_Write32(RAM_G+(x/rate)*4, VERTEX2F(x*16,y*16));       
  41.    
  42. }
复制代码
  1.         /* ========Display list start======================================== */   
  2.         HAL_CmdBufIn( CMD_DLSTART );
  3.         HAL_CmdBufIn( CLEAR_COLOR_RGB(0, 0, 0) );
  4.         HAL_CmdBufIn( CLEAR(1,1,1) );
  5.         HAL_CmdBufIn( COLOR_RGB(0,0,0) );
  6.         
  7.         HAL_CmdBufIn( BITMAP_SOURCE(2048L));       
  8.         HAL_CmdBufIn( BITMAP_LAYOUT(L8,1,QVGA_HIGH) );       
  9.         HAL_CmdBufIn( BITMAP_SIZE(NEAREST, REPEAT, BORDER, QVGA_WIDTH, QVGA_HIGH) );       
  10.         HAL_CmdBufIn( BEGIN(BITMAPS) );
  11.         HAL_CmdBufIn( TAG(0) );
  12.         HAL_CmdBufIn( VERTEX2F(0,0) );
  13.         HAL_CmdBufIn( COLOR_RGB(0x1B,0xE0,0x67) );       

  14.         HAL_CmdBufIn( LINE_WIDTH(2*16) );
  15.         HAL_CmdBufIn( BEGIN(LINE_STRIP) );
  16.         Gpu_CoCmd_Append( RAM_G,(x/rate)*4 );
  17.         HAL_CmdBufIn( END() );
  18.         
  19.         HAL_CmdBufIn( BEGIN(LINE_STRIP) );  
  20.         if ((x/rate)<(QVGA_WIDTH/rate)-(50/rate)) {
  21.             Gpu_CoCmd_Append( RAM_G+(x/rate)*4+((50/rate)*4), ((QVGA_WIDTH/rate)*4)-((x/rate)*4)-((50/rate)*4) );
  22.         }
  23.         HAL_CmdBufIn( END() );       
  24.         
  25.         HAL_CmdBufIn( POINT_SIZE(6*16) );
  26.         HAL_CmdBufIn( BEGIN(FTPOINTS) );
  27.         HAL_CmdBufIn( VERTEX2F(x*16,y*16) );       
  28.         HAL_CmdBufIn( END() );
  29.         HAL_CmdBufIn( COLOR_RGB(255,255,255) );
  30.         HAL_CmdBufIn( COLOR_A(100) );       
  31.         HAL_CmdBufIn( BEGIN(EDGE_STRIP_R) );
  32.         HAL_CmdBufIn( VERTEX2F((hide_x+QVGA_WIDTH-80)*16,0) );
  33.         HAL_CmdBufIn( VERTEX2F((hide_x+QVGA_WIDTH-80)*16,QVGA_HIGH*16) );
  34.         HAL_CmdBufIn( COLOR_A(255) );
  35.         
  36.         Gpu_Radiobutton( hide_x+QVGA_WIDTH-70,QVGA_HIGH-48,0xffffff,0,8,3,opt );               
  37.         Gpu_Radiobutton( hide_x+QVGA_WIDTH-70,QVGA_HIGH-28,0xffffff,0,8,4,opt );
  38.         Gpu_Radiobutton( hide_x+QVGA_WIDTH-70,QVGA_HIGH-8 ,0xffffff,0,8,5,opt );
  39.         Gpu_Radiobutton( hide_x+QVGA_WIDTH-70,QVGA_HIGH-68,0xffffff,0,8,6,opt );
  40.         
  41.         Gpu_CoCmd_Text( (hide_x+QVGA_WIDTH-60),QVGA_HIGH-48,26,OPT_CENTERY,"Sine" );
  42.         Gpu_CoCmd_Text( (hide_x+QVGA_WIDTH-60),QVGA_HIGH-28,26,OPT_CENTERY,"Sawtooth" );
  43.         Gpu_CoCmd_Text( (hide_x+QVGA_WIDTH-60),QVGA_HIGH-8 ,26,OPT_CENTERY,"Triangle" );
  44.         Gpu_CoCmd_Text( (hide_x+QVGA_WIDTH-60),QVGA_HIGH-68,26,OPT_CENTERY,"ECG" );
  45.         Gpu_CoCmd_Text( (hide_x+QVGA_WIDTH-60),20,30,OPT_CENTERY|OPT_CENTERX,"-" );
  46.         Gpu_CoCmd_Text( (hide_x+QVGA_WIDTH-20),20,30,OPT_CENTERY|OPT_CENTERX,"+" );
  47.         
  48.         Gpu_CoCmd_Text  ( (hide_x+QVGA_WIDTH-80),50,28,0, "Rate:" );
  49.         Gpu_CoCmd_Number( (hide_x+QVGA_WIDTH-30),50,28,0, rate    );               
  50.         Gpu_CoCmd_Text  ( (hide_x+QVGA_WIDTH-80),80,28,0, "Pk:"   );
  51.         Gpu_CoCmd_Number( (hide_x+QVGA_WIDTH-40),80,28,0, amp     );               
  52.         
  53.         HAL_CmdBufIn( COLOR_A(50) );
  54.         HAL_CmdBufIn( POINT_SIZE(15*16) );
  55.         HAL_CmdBufIn( BEGIN(FTPOINTS) );
  56.         HAL_CmdBufIn( TAG(1) );
  57.         HAL_CmdBufIn( VERTEX2F((hide_x+QVGA_WIDTH-60)*16,20*16) );               
  58.         HAL_CmdBufIn( TAG(2));
  59.         HAL_CmdBufIn( VERTEX2F((hide_x+QVGA_WIDTH-20)*16,20*16) );       
  60.         
  61.                /* DL显示结束 */
  62.         HAL_CmdBufIn( DISPLAY() );
  63.         HAL_CmdBufIn( CMD_SWAP );
  64.         HAL_BufToReg( RAM_CMD, 0 );
复制代码




 
个人签名电工
 
 

回复

524

帖子

0

TA的资源

一粒金砂(高级)

14
 
很不错,向大神学习
 
 
 

回复

79

帖子

1

TA的资源

一粒金砂(中级)

15
 
好牛!围观学习一下!
 
 
 

回复

7622

帖子

18

TA的资源

五彩晶圆(高级)

16
 




视频挂掉啦?
 
个人签名

默认摸鱼,再摸鱼。2022、9、28

 
 

回复

2144

帖子

3

TA的资源

五彩晶圆(中级)

17
 
试试这个原始地址,可能是插入问题,有的浏览器不太行估计。。


http://v.youku.com/v_show/id_XOTA5MjM1ODIw.html




 
个人签名电工
 
 

回复

19

帖子

0

TA的资源

一粒金砂(中级)

18
 
make
 
个人签名联系邮箱:zzuzpb@163.com
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

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

 
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
快速回复 返回顶部 返回列表