flyword

  • 2019-02-18
  • 回复了主题帖: Python Tinker学习笔记(一)

    也有基于python的Qt啊

  • 2019-02-12
  • 发表了主题帖: 【 XMC4800 Relax EtherCAT Kit测评】+上手DAVE,WINUSB APP 应用体验

    本帖最后由 flyword 于 2019-2-12 22:42 编辑 继续xmc4800 kit开发板的评测使用,在DAVE软件中,关于USB的APP应用有2个:USB_VCOM和WINUSB。英飞凌公司在USB_VCOM APP中实现了USB虚拟串口模块,在WINUSB APP中实现了winusb的应用,本帖将主要介绍winusb的应用过程。 Winusb是微软公司提供的一个usb中间件,类似于libusb,这样使用户不再为USB驱动发愁,可直接使用winusb,就能快速完成与usb设备之间的通讯和数据交换。本帖将简单的应用WINUSB APP,利用ADC模块,实现最简单的usb接口的示波器。 具体的步骤如下:1.       添加相关的APP,这里我们添加1个WINUSB 和1个ADC_MEASUREMENT.2.       对ADC_MEASUREMENT 进行配置,这里选择ADC引脚为14.0,ADC工作模式非中断模式。3.       关于WINUSB APP的应用,具体内容如下:         使用流程依次为USB初始化、USB连接、USB枚举、开始USB数据传输。4.       这样配置后,生成代码,然后在main.c中简单的添加了一个ADC读取并通过USB口发送出去的程序。具体代码如下:#include                  //Declarations from DAVE Code Generation (includes SFR declaration) int main(void) {   DAVE_STATUS_t status;   status = DAVE_Init();           /* Initialization of DAVE APPs  */   if(status != DAVE_STATUS_SUCCESS)   {     /* Placeholder for error handler code. The while loop below can be replaced with an user error handler. */     XMC_DEBUG("DAVE APPs initialization failed\n");     while(1U)     {     }   }   if(USBD_WINUSB_Connect() != USBD_WINUSB_STATUS_SUCCESS)   {     return -1;   }   while(!USBD_WINUSB_IsEnumDone());   uint8_t adc_string[4];   /* Placeholder for user application code. The while loop below can be replaced with user application code. */   while(1U)   {           uint16_t adc_value=ADC_MEASUREMENT_GetResult(&ADC_MEASUREMENT_Channel_A);           sprintf(adc_string,"%d",adc_value);           USBD_WINUSB_WriteData(winusb_info.config.in_endpoint.Address,&adc_string,4);   } }复制代码 5.       之后切换xmc4800 kit usb连线,并插入到电脑,此时第一次使用winusb,需要安装驱动程序,具体的程序英飞凌已经在inf文件夹里提供了,添加安装即可,之后检查设备管理器,会出现winusb设备。至此,我们对于xmc4800 kit的操作就OK了。6.       如何读取winusb的数据呢?我这里采用了.NET的winusb库,在VS2017中添加winusb库以后,在程序中根据winusb的设备GUID建立设备实例,对USB 输入端点 进行操作即可读取xmc4800 kit usb口传输过来的ADC数据data_get。7.       进一步对data_get的数据处理后,得到最终的ADC电压值。利用曲线显示插件,最终显示xmc4800 kit ADC数据曲线截图如下,这里ADC由于没有外加电压,因此测出来的数值基本是一条线(红线)。8.       今天分享到此。可以看到APP的引入,我们在使用相关部件时,这里包括USB、ADC,都无需深入掌握相关的底层代码,从而能全力关注到自己的顶层应用上,极大的缩短了产品的开发时间,而APP应用也降低了这款MCU的应用难度和门槛。 此内容由EEWORLD论坛网友flyword原创,如需转载或用于商业用途需征得作者同意并注明出处

  • 2019-02-11
  • 回复了主题帖: 下载、评论赢双重好礼|PI 邀您跟littleshrimp一起拆解小米最新二合一充电宝

    看了大神拆解过程和分享,拆解果然非常暴力,也被PI INN2215K IC的芯片强大功能吸引了,利用这个可以做成小型的UPS啦。

  • 2019-02-08
  • 回复了主题帖: [转帖] Adafruit博客:新PyBoard在FOSDEM

    这个看起来很好玩,有种庞克的感觉啊:)

  • 回复了主题帖: 【 XMC4800 Relax EtherCAT Kit测评】+上手DAVE,快速搭建自己的webserver

    bigbat 发表于 2019-2-8 10:29 XMC4800的网口,可以使用标准的TCP/IP协议栈吗?我的意思是不需要EtherCAT网络,而是普通网络。
    我这个应用就是用的标准的lwip协议栈,跑的Http_server。 CPU的引脚分配上,EtherCAT物理接口与EThernet物理接口是分开的。

  • 2019-02-07
  • 回复了主题帖: 新年有芯意,新年快乐,给大家拜年了!

    猪年,祝大家过年好!!

  • 发表了主题帖: 【 XMC4800 Relax EtherCAT Kit测评】+上手DAVE,快速搭建自己的webserver

    本帖最后由 flyword 于 2019-2-7 19:17 编辑 春节年味正浓,这里也继续自己的分享,昨天晚上试了试HTTP_SERVER APP的应用。分享给大家。之前看到大神RSCN以及anger0925已经做出webserver了,工作的代码也有分析,参考了他们的帖子,利用HTTP_SERVER这个APP模块很快速就搭建了自己的webserver。具体的流程分享如下:一、DAVEAPP模块添加及相关的配置操作。这里与之前网友的web应用类似,我们通过CGI接口发送我们的指令给XMC4800,来分别控制LED1及LED2;而XMC4800通过SSI接口来嵌入ADC模块的数值到网页上,显示给客户端。因此需要添加的APP有:1.   HTTP_SERVER2.   ADC_MEASUREMENT3.   DIGITAL_IO具体如下:插一句,这里的网页内容都放在Resources这个文件里了。网页如何存放在rom里是通过makefsdata程序生成的,这里我们需要添加一下脚本,具体可以参考APPhelp,这里设置如下图:好了,设置后以后,我们看看其他具体的配置如下:1.        对于HTTP_SERVER APP的设置,主要包括两个地方,一是webserver的端口及CGI\SSI使能设置,一般为80,也可以设置为8080等。另一处是LWIP的设置,可以使用默认的设置,但是必须确认PHY的型号与电路板一致。最后就是引脚pin的分配了,对着XMC4800的电路图,补充相关的引脚即可。2.        ADC,这里采用的是轮询的方式读取数据。 3.        两个LED均设置为输出口,并设置好相应的引脚。二、我对CGI 及SSI 的理解。由于第一次使用LWIP,对于它的工作原理不是很理解,通过对比大神RSCN以及anger0925的帖子,初步了解了对CGI、SSI的理解。具体的内容可以在lwip里httpd相关文件可以看到,这里截屏如下:CGI一般通过GET的方式,以表单的形式提交数据给服务器,然后服务器查询提交表单action对应的CGI文件,进而通过pCGIs列表查询到相应的回调函数(callback函数),并执行函数,而相应的操作对应在相应的回调函数里。 SSI一般是通过查询表单里的标记符,一般是以<!--#abc-->为标识,其中abc是我们想要显示的标记,一般在一个标签列表TAGS[]里定义,服务器运行时对网页中的标识进行查询,并在对应的索引里进行相应的操作,也用的是回调函数。CGI和SSI在使用时,都需要进行相应的注册,这样才能正常使用。注册函数分别对应的是http_set_cgi_handlers和http_set_ssi_handler。对于用户而言,我们需要做的工作有三个个步骤。A.     首先,定义自己的句柄函数,对应CGI和SSI接口。B.     其次,定义对应CGI的pCGIs列表,以及对应SSI的标签列表TAGS。C.     最后,依次使能注册函数http_set_cgi_handlers和http_set_ssi_handler。我们完全不用关注底层的代码,只需要设计自己的上层应用即可。三、只在main.c中添加代码,就能实现自己的应用。1.先看CGI接口部分的程序,需要添加两个部分,一个部分是c程序,一个是html程序里cgi接口的定位,具体程序看后面html文件内容。程序如下:其中,pcValue[0]对应的是提交上去的第一个参数对应的值。const char *ledctrl_handler(int iIndex, int iNumParams, char *pcParam[],char *pcValue[]){       if(strcmp(pcValue[0], "led1_on") == 0)       {           DIGITAL_IO_SetOutputHigh(&LED_1);       }       if(strcmp(pcValue[0], "led1_off") == 0)       {           DIGITAL_IO_SetOutputLow(&LED_1);       }       if(strcmp(pcValue[0], "led2_on") == 0)       {           DIGITAL_IO_SetOutputHigh(&LED_2);       }       if(strcmp(pcValue[0], "led2_off") == 0)       {           DIGITAL_IO_SetOutputLow(&LED_2);       }       if(strcmp(pcValue[0], "leds_off_all") == 0)       {           DIGITAL_IO_SetOutputLow(&LED_1);           DIGITAL_IO_SetOutputLow(&LED_2);       }       if(strcmp(pcValue[0], "leds_on_all") == 0)       {           DIGITAL_IO_SetOutputHigh(&LED_1);           DIGITAL_IO_SetOutputHigh(&LED_2);       }       return "/index.shtml"; //一定要返回到首页,不然可能就跳转到空页面了。。 } tCGI pCGIs[]={            //定义的CGI对应的列表,分别对应html中多个cgi表单。         {                 .pcCGIName="/ledctrl.cgi",                 .pfnCGIHandler=ledctrl_handler         }, }; int web_cgi_init(void){     http_set_cgi_handlers(pCGIs, 1); //将相应的CGI列表注册到系统中个,这里因为只有1个列表,因此数字为1 。     return 0; }复制代码 2.再看看SSI接口部分的程序,需要添加两个部分,一个部分是c程序,一个是html程序里cgi接口的定位。const char *Tags[]={   //定了了网页中的SSI标记。用于服务器将相关的数据添加进去。         "ADC",         "INT", }; static uint16_t adc_read_ssihandler(int iIndex, char *pcInsert, int iInsertLen){     uint16_t ADC_value;     char value[4];     char num[5];     switch(iIndex){                  //iIndex is the index of identifier in the Tags[]                     case 0:                         ADC_value = ADC_MEASUREMENT_GetResult(&ADC_MEASUREMENT_Channel_A);                         sprintf(value,"%d",ADC_value);                         *pcInsert=value[0];                         *(pcInsert+1)=value[1];                         *(pcInsert+2)=value[2];                         *(pcInsert+3)=value[3];                         break;                     case 1:                         sprintf(num,"%d",12345);                         *pcInsert=num[0];                         *(pcInsert+1)=num[1];                         *(pcInsert+2)=num[2];                         *(pcInsert+3)=num[3];                         *(pcInsert+4)=num[4];                         break;                     default:                         break;     }     return strlen(pcInsert);//this is very important to run the ssi handler...这里非常重要,必须返回插入数据的长度,否则不能正常显示。 } int web_ssi_init(void){//注册函数。     http_set_ssi_handler(adc_read_ssihandler,(char const **)Tags,2);     return 0; }复制代码 完整的main函数如下:int main(void) {   DAVE_STATUS_t status;   status = DAVE_Init();           /* Initialization of DAVE APPs  */   if(status != DAVE_STATUS_SUCCESS)   {     /* Placeholder for error handler code. The while loop below can be replaced with an user error handler. */     XMC_DEBUG("DAVE APPs initialization failed\n");     while(1U)     {     }   }   //httpd_init();   web_cgi_init();   web_ssi_init();   /* Placeholder for user application code. The while loop below can be replaced with user application code. */   while(1U)   {       sys_check_timeouts(); //使能LWIP应用   } }复制代码 至此,我们的web网页就搭建完成了,相关的HTML文件见附件,上传code里会被解析出来。。。论坛的编辑器啊。。。。 四、具体的应用实现效果。下载程序以后,设置好电脑的IP地址,在浏览器中访问xmc4800IP即可得到网页内容。怎么样,简单吧!感兴趣的用户可以实验一下。我是第一次使用英飞凌的单片机,使用DAVE的APP,的确不一样的体验,不用再去翻手册,繁琐的操作那些寄存器了,直接面向应用设计自己的项目,赞!!但是缺点也有,就是APP的应用不是很灵活,要想灵活的应用的话,就必须对DAVE和APP有更深入的理解。 html文件 此内容由EEWORLD论坛网友flyword原创,如需转载或用于商业用途需征得作者同意并注明出处

  • 2019-02-06
  • 回复了主题帖: 【 XMC4800 Relax EtherCAT Kit测评】+评测结贴,EtherCAT从站模块应用扩展

    tdatd 发表于 2019-2-6 08:16 你这够拼,搞嵌入式还能干plc  是个人才
    也就玩玩简单的PLC:loveliness:

  • 2019-02-05
  • 发表了主题帖: 【 XMC4800 Relax EtherCAT Kit测评】+评测结贴,EtherCAT从站模块应用扩展

    本帖最后由 flyword 于 2019-2-6 12:34 编辑 [原创] 【 XMC4800 Relax EtherCAT Kit测评】+上手DAVE,EtherCAT从站模块应用扩展!(本次评测的结贴,后续陆续分享学习成果) 继续接上一篇帖子,关于EtherCAT模块的使用,这里其实上个帖子已经说得很清楚了,主要在process_app()中添加自己的应用并与相应的输入输出变量对应上就可以啦,哈哈,非常简单。英飞凌官方提供的从站例程中其实已经涉及到了开关量的输入和输出(分别对应按钮操作和LED灯的设置),以及整型量的输出(代码中对应的PWM的设置),这里我添加了ADC模块的简单应用,使用的是PIN14.0,具体可以参考之前帖子关于ADC模块的设置。相关的代码如下,我分别为3个整型量赋值了,第三个直接读取ADC的转换值。在后面TwinCAT应用中会使用该数值来控制LED灯。具体代码:void process_app(TOBJ7000 *OUT_GENERIC, TOBJ6000 *IN_GENERIC) {   /* OUTPUT PROCESSING */   /* Check bitfield set by master OUT_GEN_Bit1..8 and set LEDs accordingly */   XMC_GPIO_SetOutputLevel(P_LED1, MAP2LEVEL(OUT_GENERIC->OUT_GEN_Bit1));  //OUT_GEN_BIT COMES FROM THE MASTER   XMC_GPIO_SetOutputLevel(P_LED2, MAP2LEVEL(OUT_GENERIC->OUT_GEN_Bit2));   XMC_GPIO_SetOutputLevel(P_LED3, MAP2LEVEL(OUT_GENERIC->OUT_GEN_Bit3));   XMC_GPIO_SetOutputLevel(P_LED4, MAP2LEVEL(OUT_GENERIC->OUT_GEN_Bit4));   XMC_GPIO_SetOutputLevel(P_LED5, MAP2LEVEL(OUT_GENERIC->OUT_GEN_Bit5));   XMC_GPIO_SetOutputLevel(P_LED6, MAP2LEVEL(OUT_GENERIC->OUT_GEN_Bit6));   XMC_GPIO_SetOutputLevel(P_LED7, MAP2LEVEL(OUT_GENERIC->OUT_GEN_Bit7));   XMC_GPIO_SetOutputLevel(P_LED8, MAP2LEVEL(OUT_GENERIC->OUT_GEN_Bit8));   /* Check integer set by Master OUT_GEN_INT1 and set duty cycle of PWM driving LED 2 accordingly */   PWM_CCU8_SetDutyCycleSymmetric(&PWM_CCU8_0, XMC_CCU8_SLICE_COMPARE_CHANNEL_1,                   6000+((uint32_t)4000*(uint32_t)OUT_GENERIC->OUT_GEN_INT1)/65535);   /* INPUT PROCESSING */   /*Check Button 1 and set IN_GEN_Bit1 which is sent to master accordingly*/   if (XMC_GPIO_GetInput(P15_13))     IN_GENERIC->IN_GEN_Bit1 = 1;   else     IN_GENERIC->IN_GEN_Bit1 = 0;   /*Check Button 2 and set IN_GEN_Bit2 which is sent to master accordingly*/   if (XMC_GPIO_GetInput(P15_12))     IN_GENERIC->IN_GEN_Bit2 = 1;   else     IN_GENERIC->IN_GEN_Bit2 = 0; [color=#000000]  IN_GENERIC->IN_GEN_INT1=1234;//define the value test for the twincat3   IN_GENERIC->IN_GEN_INT2=56789; //start the ADC ,get the value input for EtherCat master   IN_GENERIC->IN_GEN_INT3 = ADC_MEASUREMENT_GetResult(&ADC_MEASUREMENT_Channel_A);[/color] }复制代码 至此,从站的应用扩展就结束了,是不是很简单啊,哈哈!对于这个从站模块而言,它就是接收和发送相关的数据信息而已,当然也可以实现一定的功能,但是要是与其他模块通讯,涉及到分布式控制的话,就要靠主站来协调资源啦,即由主站控制和配置从站啦!。那么重点来了,我们需要主站来与从站配合完成相关的功能啊,这就要TwinCAT登场啦,如果是win7以上的电脑,建议使用TwinCAT3,可以免费使用7天,重复注册就行,为什么不推荐TwinCAT2,主要是界面太丑了,我之前做了一个应用使用的就是TwinCAT2,优势是PLC编程支持梯形图,TW3似乎不支持梯形图。TW3的安装这里也不说了,遇到相关的问题百度,我这两天安装这个软件耗时太久了,软件使用要求很高,感觉兼容性一般。使用相关的TwinCAT软件扫描XMC4800从站的方法,就不再说了,有问题的话,看看软件安装或者xml描述文件是否添加到TW3的目录中呢。一、      成功扫描到从站开发板后,设置TW3的工作模式,使从站开发板工作在free run模式下,然后就可以看到相关的通讯已经成功了。点击BOX1后,会看到相关的变量定义,这些变量都是在excel表里定义的,我添加了一个INT型输入量和一个INT输出量。二、      这里是重点看看ADC模块的数据是否传递到主站上。如下图,我们读取的ADC测试数据已经在窗口中显示了。到这一步说明数据已经传递到TW3主站了。三、      编写主站程序,这里添加一个PLC程序,主要完成一个“起—保—停”电路控制程序和一个整型量判断处理函数,分别用于开关2个led灯。四、      PLC程序编写完毕后,记得需要编译一下,这样才能产生程序instance,这个是用来与IO模块的变量进行链接用的。五、      PLC程序相关的变量链接如下:PLC程序的输入变量链接情况:注意其中一个连接到IN_GEN_INT3,这个是ADC转换值。PLC程序的输出变量链接情况:分别链接到2个LED灯啦。六、      相应的设置好好,就可以开始运行程序啦,两步骤:设置TW3在run模式,Login进去PLC程序,并运行PLC程序。七、      之后就可以看到程序运行的实时状态了,如下图,可以看到ADC的值已经传递到主站了,并且参与到程序控制中了。相关实际演示视频我会后续会上传,因为在外地出差,网络受限,不能上传视频,敬请谅解! 最后总结:目前XMC4800相关的市场应用还很少,但是丝毫不能掩盖这枚芯片的强大功能以及其背后的DAVE软件绽放的巨大魅力,这次评测我从最简单的外设入手,分别对IO口模块、定时器模块、PWM模块、ADC模块、DAC模块、LWIP应用模块、USB模块、CAN模块进行了基本应用,基本上掌握了DAVE APP软件的应用流程和方法,最后对XMC4800的最大特色EtherCAT从站模块进行了简单分析和应用,并公布了相关的评测使用分享。其中关于LWIP、USB、CAN的相关评测,因为网友已经评测,因此并未公布相关心得体会,后续会根据学习情况继续发帖,感谢EE论坛提供的这一块强大的电路板。最后,祝大家猪事顺利!!!! 此内容由EEWORLD论坛网友flyword原创,如需转载或用于商业用途需征得作者同意并注明出处

  • 2019-02-04
  • 发表了主题帖: 【 XMC4800 Relax EtherCAT Kit测评】+上手DAVE,XMC4800 EtherCAT从站模块例程简析

    【 XMC4800 Relax EtherCAT Kit测评】+上手DAVE,XMC4800 EtherCAT从站模块例程简析 本次主要简单的分享一下XMC4800 relax kit EtherCAT从站例程的分析,为下一步我们添加自己的应用打下基础。 EtherCAT总线技术源自德国倍福公司,物理介质一般采用RJ45网络接口,即普通的网线形式,该技术最大的特点是实时性好,为什么会这样,主要是因为它对采用标准格式的以太网数据帧,但是重新定义了报文格式,满足EtherCAT硬件接口的处理需求,最终使得软硬件能完美结合。EtherCAT总线技术采用的是主—从模式,分为主站和从站,XMC4800系列单片机是面向从站开发的,也有XMC4800做主站的方案,例如基于SOME的,具体可以github上找找。       春节年前这几天看了看XMC4800 EtherCAT《从站例程用户指南》,里面关于工具、上位机测试环境等介绍的很清楚,可以说是手把手教你使用XMC4800的ESC模块,这里简单分析和总结一下。1.    关于ESC开发工具,SSC Tool软件工具是主角,必须要用到。我们自己开发相关的EtherCAT从站时,一般涉及到的输入、输出量,布尔类型或者INT类型都是在一个excel里面定义的,而SSC 工具通过这个excel表对应自动生成相关的从站协议栈代码。2.    SSC软件工具的使用需要涉及2个文件,上面的excel表是1个,还有1个是与MCU厂家IDE对应的相关的xml文件,这个文件与上面的excel文件配合,会生成符合ETG从站规范的协议栈,同时也会生成TwinCAT主站里的EtherCAT从站描述文件(生成后,需要手动存放在twincat软件目录里)。3.    我使用的是英飞凌提供最新V3.1版本的ESC例程,这个例程可以从DAVE软件中安装得到。与之前的例程相比,相关接口程序已经移植到main.c中了。4.    最重要的与指南里一直,首先是我们需要注意的是应用涉及到的输入输出如何映射出去。具体看下图:这里使用很简单,用的是memcpy函数,直接将数据拷贝,实现映射,非常简单!5.    输入输出口在xmc4800 kit中具体对应的是哪里呢?可以参考process_app()函数中的定义,这个函数非常重要,我们要添加自己的应用也是在这里,这里定义的变量名实际上是之前在excel表里定义的名称。比如OUT_GEN_Bit1,都是之前excel里定义好的。6.    上图可以看出,这里把XMC4800的led灯、按钮资源分别与输入端口、输出端口(相对于主站而言的)进行了对接,也就是我们会在主站TwinCAT软件中操作相关的OUT位,就可以操作相应的LED灯。我们在操作XMC4800 kit板上的2个按钮时,相应的IN位就变化了,这里不再截图说明了。7.    Process_app函数不是ETG官方定义的,我们需要把这个函数添加到相应的协议栈函数中。如下图:8.    在应用设计时,我们完全可以依靠英飞凌提供的这个例程,来完成自己的从站硬件开发,而不需要考虑更深层次的协议栈等。目前市场上的EtherCAT从站,一般都是开关量的IO模块,没有模拟量模块,通过这个例程简单的开发,就可以依靠ADC、DAC,来设计模拟量输入和输出模块。9.    XMC4800从站APP模块的配置,需要说明的是里面的4个引脚分配,如下图:这里面没有标明引脚具体位置,其实是在ESC从站APP的Pin分配里,一个细节问题,需要注意。10.   最后,编译相关的程序,下载运行,利用TwinCAT主站软件,让xmc4800 kit开发板在free run模式下,就可以看到相应通讯效果了。相关效果与指南手册一致,则说明程序配置没有问题。 猪年马上就要到了,当别人在与家人团圆时,我还在岗位坚守,一想到2018年自己的收获颇丰,现在的努力和辛苦就什么都不是了,2019年其实已经过去了一个月了,加油!下个帖子,将会分享一下在EtherCAT从站例程基础上,添加自己的应用,并编写简单的TwinCAT PLC程序,敬请期待!! 此内容由EEWORLD论坛网友flyword原创,如需转载或用于商业用途需征得作者同意并注明出处

  • 2019-02-01
  • 发表了主题帖: 【 XMC4800 Relax EtherCAT Kit测评】+上手DAVE,Modbus总线综合应用

    马上过年了,祝愿各位坛友猪年快乐,猪事顺利! 前面已经利用DAVE软件完成了多数基本部件的应用,由于本人之前一直使用的DAVE版本是4.3.2版本,有好多例程不能跑,例如基于XMC4700的modbus应用,为此重新下载了4.4.2版本,本次分享一下modbus的综合应用。在APP中,没有专门的Modbus总线应用。这里直接使用的是英飞凌提供的软件例程:MODBUS_RTU_MODE_XMC47。 这个应用中英飞凌已经把相关的移植做好了,我们只要对应配置即可。所使用的是freemodbus-1.5.0,这个协议栈是为从站应用设计的,不能作为主站使用。 对于freemodbus的移植应用,需要建立port文件夹,其实移植主要涉及2个硬件资源,一个是串口资源,一个是定时资源,分别是对应modbus协议栈运行时所需的通道和超时处理。另外就是对于4类寄存器(离散输入,输入寄存器、线圈输出、保持寄存器)的处理函数要有自己编写。本次,我在MODBUS_RTU_MODE_XMC47例程的基础上,分别对4类寄存器进行了测试,主要包括:1.    按钮对离散输入量,2.    PWM频率值对应输入寄存器,3.    用来设置PWM的频率,4.    读取ADC转换的值,作为保持寄存器数值。 在使用之前,我们需要定义4类寄存器的地址和有效数量。之后在单片机程序中定义4类数组,分别对应4类寄存器。然后依次编写相关寄存器的读写操作函数,把数据写入到缓冲区或者从缓冲区中读入,这里缓冲区与UART交互,完成modbus总线协议栈的底层数据交换。 而我们的应用需要在原来例程的基础上再添加2个IO模块,对应LED;添加ADC模块,对应读取ADC的值,并且写入到保持寄存器3中,另外添加PWM程序,将输入寄存器的值与PWM频率设置值对接。相应的操作可以看之前我的帖子,这里不再赘述。其中ADC的转换值采用了轮训的方式,直接读取,而没有采用中断方式,后续再优化。所有配置完成后,依次编写相关的处理程序。1,led处理函数如下,通过读取线圈输出值,来判断是否点亮或者关闭对应的LED。2.PWM中,我们引用了compare匹配模式,产生了一个呼吸灯,然后配置呼吸灯的频率。3.ADC直接去读的转换结果。在程序中我们还另外设置了固定数值,以及自加数值,用来检测modbus的应用。5.    另外,例程原本程序是读取离散输入的按钮值。具体可以看代码。 之后,编译下载程序,使用modscan32软件依次添加4类寄存器的操作面板,具体截图如下。输入寄存器的操作:保持寄存器的操作:离散输入寄存器:线圈寄存器: 最终一张全家福,看看各个窗口数据: 最后相关的代码,这里主要贴出main函数代码: /**************************************************************** * HEADER FILES ***************************************************************/ #include #include "port.h" #include "mbutils.h" #include "mb.h" /**************************************************************** * MACROS AND DEFINES ***************************************************************/ /* Input Register Definition (16 bit; Read-Only) */ /* Input Register Start Address */ #define REG_INPUT_START_ADDR 1U /* No of Input Registers*/ #define REG_INPUT_COUNT 4U /* Holding Register Definition (16 bit; Read-Write) */ /* Holding Register Start Address */ #define REG_HOLDING_START_ADDR 10U /* No of Holding Registers */ #define REG_HOLDING_COUNT 130U /* Coil Register Definition (1 bit; Read-Write) */ /* Coil Register Start Address */ #define REG_COILS_START_ADDR 1000U /* No of Coil Registers*/ #define REG_COILS_COUNT 16U /* Discrete Inputs Definition (1 bit; Read-Only) */ /* Discrete Inputs Start Address */ #define REG_DISC_START_ADDR 2000U /* No of Discrete Inputs */ #define REG_DISC_COUNT 16U /**************************************************************** * LOCAL DATA ***************************************************************/ /* Allocate buffer for Input Register (16bit; Read-Only) */ static uint16_t reg_input_buffer[REG_INPUT_COUNT]; /* Allocate buffer for Holding Register (16bit; Read-Write) */ static uint16_t reg_holding_buffer[REG_HOLDING_COUNT]; /* Allocate buffer for discrete input register (1bit; Read-Only) */ static uint8_t reg_discrete_input_buffer[ (((uint16_t)REG_DISC_COUNT-1U) / 8U) + 1U]; /* Allocate buffer for coil register (1bit; Read-Write) */ static uint8_t reg_coils_buffers[ (((uint16_t)REG_COILS_COUNT-1U) / 8U) + 1U]; /**************************************************************** * API PROTOTYPES ***************************************************************/ void readbuttons(void); void Rx_Cb(void); void Tx_Cb(void); void setleds(void); void setPWM_feq(void); /**************************************************************** * API IMPLEMENTATION ***************************************************************/ /** * @eMBRegInputCB * * Callback function called by the protocol stack for reading the 16bit value of input * register(s) * * @input :  - buffer  : Pointer to a buffer which is used to return the *                        current value of the modbus input registers to the stack. *           - address : Starting address of the registers. *           - count   : Number of registers to be returned. * * @output : - buffer  : Buffer which is updated with the modbus input registers. * * [url=home.php?mod=space&uid=784970]@return[/url] : MB_ENOERR if success *           MB_ENOREG if failure (illegal register access) * * */ eMBErrorCode eMBRegInputCB( uint8_t *buffer, uint16_t address, uint16_t count ) {   eMBErrorCode status = MB_ENOERR;   uint16_t     register_index;   if (( address >= (uint16_t)REG_INPUT_START_ADDR )      && ( (uint16_t)(address + count) 0U )     {       /* Pass current register values to the protocol stack. */       *buffer = ( uint8_t )( reg_input_buffer[register_index] >> 8 );       buffer++;       *buffer = ( uint8_t )( reg_input_buffer[register_index] & 0xFFU );       buffer++;       register_index++;       count--;     }   }   else   {     status = MB_ENOREG;   }   return status; } /** * @eMBRegHoldingCB * * Callback function called by the protocol stack for reading/writing the 16bit value of * holding register(s) * * @input :  - buffer  : Pointer to a buffer which is used to exchange (read/write) *                       current value of the modbus holding registers with the protocol stack. *           - address : Starting address of the register(s). *           - count   : Number of registers to be exchanged (read/write). *           - mode    : MB_REG_WRITE Protocol stack is writing input register(s). *                       MB_REG_READ  Protocol stack is reading input register(s). * * @output : - buffer  : Buffer which is updated with the modbus holding registers. * * @return:  MB_ENOERR if success *           MB_ENOREG if failure (illegal register access) * * */ eMBErrorCode eMBRegHoldingCB( uint8_t *buffer, uint16_t address, uint16_t count, eMBRegisterMode mode ) {   eMBErrorCode status = MB_ENOERR;   uint16_t register_index;   if ( ( address >= REG_HOLDING_START_ADDR ) &&      ( (uint16_t)(address + count) 0U )         {           *buffer = (uint8_t)( reg_holding_buffer[register_index] >> 8 );           buffer++;           *buffer = (uint8_t)( reg_holding_buffer[register_index] & 0xFFU );           buffer++;           register_index++;           count--;         }         break;       /* Update current register values with new values from the        * protocol stack. */       case MB_REG_WRITE:         while( count > 0U )         {           reg_holding_buffer[register_index] = (uint16_t)((uint16_t)*buffer = REG_COILS_START_ADDR ) &&       ( (uint16_t)(address + count) 0 )         {           if (signed_count > 8)           {             *buffer = xMBUtilGetBits( reg_coils_buffers, bit_offset, 8U);           }           else           {             *buffer = xMBUtilGetBits( reg_coils_buffers, bit_offset, (uint8_t)signed_count);           }           buffer++;           signed_count -= 8;           bit_offset += 8U;         }         break;       /* Update current register values. */       case MB_REG_WRITE:         while( signed_count > 0 )         {           if (signed_count > 8)           {             xMBUtilSetBits( reg_coils_buffers, bit_offset, 8U, *buffer );           }           else           {             xMBUtilSetBits( reg_coils_buffers, bit_offset, (uint8_t)signed_count, *buffer );           }           buffer++;           signed_count -= 8;           bit_offset += (uint8_t)8;         }         break;       default:         status = MB_ENOREG;         break;     }   }   else   {     status = MB_ENOREG;   }   return status; } /** * @eMBRegDiscreteCB * * Callback function called by the protocol stack for reading the 1bit value of discrete register(s) * * @input :  - buffer  : Pointer to a buffer which is used to return the *                       current value of the modbus discrete registers to the stack. *           - address : Starting address of the registers. *           - count   : Number of register bits to be returned. * * @output : - buffer  : Buffer which is updated with the modbus discrete registers. * * @return : MB_ENOERR if success *           MB_ENOREG if failure (illegal register access) * * */ eMBErrorCode eMBRegDiscreteCB( uint8_t *buffer, uint16_t address, uint16_t count ) {   eMBErrorCode status = MB_ENOERR;   int16_t signed_count = (int16_t)count;   uint16_t bit_offset;   /* Check if we have registers mapped at this block. */   if( ( address >= REG_DISC_START_ADDR ) &&     ( (uint16_t)(address + count) 0 )     {       if (signed_count > 8)       {          *buffer = xMBUtilGetBits( reg_discrete_input_buffer, bit_offset, 8U );       }       else       {          *buffer = xMBUtilGetBits( reg_discrete_input_buffer, bit_offset, (uint8_t)signed_count);       }       buffer++;       signed_count -= 8;       bit_offset += (uint8_t)8;     }   }   else   {     status = MB_ENOREG;   }   return status; } /** * @readbuttons * * Checks state of button1 and button2 and * sets bit0 and bit1 of discrete input registers accordingly * * @input :  none * * @output : none * * @return : none * * */ void readbuttons(void) {     /* Read input of button 1 and store inside bit 0 of discrete input registers */     if (XMC_GPIO_GetInput(P15_13))     {       xMBUtilSetBits( reg_discrete_input_buffer, 0U, 1U, 1U );    /* Set bit 0 to 1b. */     }     else     {       xMBUtilSetBits( reg_discrete_input_buffer, 0U, 1U, 0U );    /* Set bit 0 to 0b. */     }     /* Read input of button 2 and store inside bit 1 of discrete input registers */     if (XMC_GPIO_GetInput(P15_12))     {       xMBUtilSetBits( reg_discrete_input_buffer, 1U, 1U, 1U );    /* Set bit 1 to 1b. */     }     else     {       xMBUtilSetBits( reg_discrete_input_buffer, 1U, 1U, 0U );    /* Set bit 1 to 0b. */     } } void setleds(){         if((reg_coils_buffers[0]&0x01)!=0){           //check buffer[0] bit0 is 1.                 DIGITAL_IO_SetOutputHigh(&LED_1);         }         else{                 DIGITAL_IO_SetOutputLow(&LED_1);         }         if((reg_coils_buffers[0]&0x02)!=0){           //check buffer[0] bit1 is 1.                 DIGITAL_IO_SetOutputHigh(&LED_0);         }         else{                 DIGITAL_IO_SetOutputLow(&LED_0);         } } void setPWM_feq(){         PWM_SetFreq(&PWM_0,(uint32_t)reg_holding_buffer[0]); } void PWM_handler(){         static uint32_t duty = (uint32_t)100;         static bool decrement_duty = (bool)false;           if(decrement_duty != false)           {             //Decrement the duty cycle until it reaches 1%             duty -= (uint32_t)100;             // Once the duty has reached 1% flag status is changed to Increment             if (duty = (uint32_t)10000)             {              decrement_duty = true;             }           }           // Sets the duty cycle of the PWM           PWM_SetDutyCycle(&PWM_0,duty);           // Clear the compare match interrupt.           PWM_ClearEvent(&PWM_0,PWM_INTERRUPT_COMPAREMATCH ); } void Adc_Measurement(){         reg_input_buffer[2] = ADC_MEASUREMENT_GetResult(&ADC_MEASUREMENT_Channel_A); } /** * @brief * * Initialize Modbus RTU or ASCII mode, baudrate and device address. Enables the * modbus stack. * * * */ int32_t main(void) {   /*Initialize DAVE */   if(DAVE_Init() == DAVE_STATUS_FAILURE)   {     /* Placeholder for error handler code.*/     XMC_DEBUG(("DAVE APPs initialization failed\n"));     while(1U)     {         /* do nothing */     }   }   /* INITIALIZE BUTTON1 ON PORT 5.13 FOR INPUT */   /* Set mode to input tristate */   XMC_GPIO_SetMode(P15_13, XMC_GPIO_MODE_INPUT_TRISTATE);   /* Enable digital input. Only needed because P15.13 is an analog port */   XMC_GPIO_EnableDigitalInput(P15_13);   /* INITIALIZE BUTTON2 ON PORT 5.12 FOR INPUT */   /* Set mode to input tristate */   XMC_GPIO_SetMode(P15_12, XMC_GPIO_MODE_INPUT_TRISTATE);   /* Enable digital input. Only needed because P15.12 is an analog port */   XMC_GPIO_EnableDigitalInput(P15_12);   PWM_Start(&PWM_0);   ADC_MEASUREMENT_StartConversion(&ADC_MEASUREMENT_0);   /* Set FIFO trigger limits */   UART_SetRXFIFOTriggerLimit (&UART_0, (uint32_t)0);   UART_SetTXFIFOTriggerLimit (&UART_0, (uint32_t)1);   /* Register UART_0 interface for modbus usage */   MB_register_UART(&UART_0);   /* Initialization of modbus in RTU mode */   (void)eMBInit( MB_RTU,            /*eMode (MB_ASCII or MB_RTU*/                    (uint8_t)0x0A,     /*ucSlaveAddress*/                    (uint8_t)0,        /*ignored*/                    (uint8_t)19200,    /*ulBaudRate*/                    (eMBParity)0         /*ignored*/                  );   /*Enable modbus protocol stack.*/   (void)eMBEnable();   /* Initialise the discrete input registers with zero's and one's    * for demonstration purpose within this example. */   xMBUtilSetBits( reg_discrete_input_buffer, (uint16_t)2, (uint8_t)2, (uint8_t)3 );    /* Set bit 2:3 to 11b. */   xMBUtilSetBits( reg_discrete_input_buffer, (uint16_t)8, (uint8_t)1, (uint8_t)1 );    /* Set bit 8 to 1b. */   /* Modbus polling loop waiting for an Event*/   for( ;; )   {     /* Process modbus protocol stack */     (void)eMBPoll();     /* Change values inside local register banks for demonstration purpose*/     reg_input_buffer[0]++;     reg_input_buffer[1]=12345;     readbuttons();     setleds();     setPWM_feq();     Adc_Measurement();   } } /* Callback handler of UART receiving */ void Rx_Cb(void) {   MB_RxHandler(); } /* Callback handler of UART transmitting */ void Tx_Cb(void) {   MB_TxHandler(); } 复制代码 此内容由EEWORLD论坛网友flyword原创,如需转载或用于商业用途需征得作者同意并注明出处

  • 2019-01-30
  • 发表了主题帖: 【 XMC4800 Relax EtherCAT Kit测评】+上手DAVE,RTC模块应用及问题

    【XMC4800 Relax EtherCAT Kit测评】+上手DAVE,RTC模块应用及问题 实时时钟在XMC4800kit上有设置,这里分享给给大家,一般来说RTC使用比较简单,设置好时间及中断后就可以了。但是本人在使用RTC时,发现只能进入Alarm中断1次,后面就无法再进入了,参考的程序主要也是APP help文档里的例程,不知道是不是程序设计的bug。。 好了。进入主题前,首先看看图纸里的RTC设置。如下图,使用标准的32.768K晶振。硬件配置中默认使用的是内部的时钟,要是使用外部时钟,需要再CLOCK模块中进行配置,具体如下图:一、     添加相应的RTC模块和IO模块,这里添加2个IO模块,分别指向2个LED灯,分别用于对 秒事件和设置的报警事件进行翻转指示。二、     对RTC_0模块进行配置,具体如下:这里时间使用的是默认时间,在报警时间设置上,设置了1分钟,表明1分钟以后就会报警。在中断设置上,选择周期时间为秒,对应的每秒都会触发Time_Handler中断处理函数,在Alarm时间设置中,使能报警中断,并选择NMI(不可屏蔽中断),会在alarm时间相应时,执行NMI_Handler。 三、     对IO模块的设置可以参见之前发帖,这里不再赘述。四、     然后点击产生代码即可,在main函数中添加2个中断函数,在Time_Handler中我们翻转1个led灯,在NMI_Handler,我们读取报警设置时间,并重新设置时间,同时翻转另外一个led灯。五、     具体代码如下:/* * main.c * *  Created on: 2019 Jan 30 13:16:39 *  Author: ???? */ #include                  //Declarations from DAVE Code Generation (includes SFR declaration) /** * [url=home.php?mod=space&uid=159083]@brief[/url] main() - Application entry point * * Details of function * This routine is the application entry point. It is invoked by the device startup code. It is responsible for * invoking the APP initialization dispatcher routine - DAVE_Init() and hosting the place-holder for user application * code. */ void Time_Handler(){         DIGITAL_IO_ToggleOutput(&LED_0); } void NMI_Handler(){         XMC_RTC_ALARM_t alarm_time;         DIGITAL_IO_ToggleOutput(&LED_1);         XMC_SCU_INTERRUPT_ClearEventStatus((XMC_SCU_INTERRUPT_EVENT_t)XMC_SCU_INTERRUPT_EVENT_RTC_ALARM);         RTC_GetAlarmTime(&alarm_time);         if(++alarm_time.minutes>59) {                 alarm_time.minutes=0;                 alarm_time.hours++;         }         RTC_Stop();         RTC_SetAlarmTime(&alarm_time);         RTC_Start(); } int main(void) {   RTC_Stop();   DAVE_STATUS_t status;   status = DAVE_Init();           /* Initialization of DAVE APPs  */   if(status != DAVE_STATUS_SUCCESS)   {     /* Placeholder for error handler code. The while loop below can be replaced with an user error handler. */     XMC_DEBUG("DAVE APPs initialization failed\n");     while(1U)     {     }   }   /* Placeholder for user application code. The while loop below can be replaced with user application code. */   while(1U)   {   } } 复制代码 六、     编译后下载运行,可以看到1个led灯会每秒翻转1次,而另1个LED灯会在1分钟时翻转1次,而后每分钟都会翻转,但是我没有发现该LED灯再次翻转,因此怀疑有bug,希望可以反馈给英飞凌的技术人员,确认一下问题。七、     具体运行图片如下:

  • 发表了主题帖: 【 XMC4800 Relax EtherCAT Kit测评】+上手DAVE,PWM模块应用

    今天继续分享,使用PWM模块。今天利用PWM模块,做一个呼吸灯的应用,并从串口上打印出来相关的设置数值。具体步骤如下:一,       添加PWM、INTERRUPT(添加2个)、UART模块。二,       对PWM模块进行设置,注意红色方框设定的值。频率设置是PWM信号的频率设置,DUTY占空比是一个周期内的高电平周期,这里设置为50%。选择事件设定,这里选择2个事件,compare 是用于匹配波形占空比设置的,period是用于匹配周期时间的。具体的事件解释如下图:三,       设置PWM模块的HW信号连接。具体截图如下:四,       配置UART的设置。设置为非中断模式的发送模式,9600-8-1-n。五,       编写main程序。分别添加compare_match_handler()和period_match_handler()中断处理函数。六、   具体代码如下,这里实现了占空比连续增加,到达最大值后再减小。另外实现另一个LED周期性翻转,用来检验是否执行了period_match_handler()函数。/* * main.c * * Created on: 2019 Jan 29 21:23:36 * Author: ???? */ #include //Declarations from DAVE Code Generation (includes SFR declaration) /** * [url=home.php?mod=space&uid=159083]@brief[/url] main() - Application entry point * * Details of function * This routine is the application entry point. It is invoked by the device startup code. It is responsible for * invoking the APP initialization dispatcher routine - DAVE_Init() and hosting the place-holder for user application * code. */ static uint32_t duty =100; uint8_t value[10]; int main(void) { DAVE_STATUS_t status; status = DAVE_Init(); /* Initialization of DAVE APPs */ if(status != DAVE_STATUS_SUCCESS) { /* Placeholder for error handler code. The while loop below can be replaced with an user error handler. */ XMC_DEBUG("DAVE APPs initialization failed\n"); while(1U) { } } PWM_Start(&PWM_0); /* Placeholder for user application code. The while loop below can be replaced with user application code. */ while(1U) { sprintf(value,"%d",duty); UART_Transmit(&UART_0,"Duty Set Value:",15); UART_Transmit(&UART_0,value,sizeof(value)); UART_Transmit(&UART_0,"\r\n",2); } } void compare_match_handler() { static bool decrement_duty =(bool)false; if(decrement_duty != false) { duty =duty-100; if (duty = 10000) { decrement_duty = true; } } PWM_SetDutyCycle(&PWM_0,duty); PWM_ClearEvent(&PWM_0,PWM_INTERRUPT_COMPAREMATCH ); } void period_match_handler(){ DIGITAL_IO_ToggleOutput(&LED_1); PWM_ClearEvent(&PWM_0,PWM_INTERRUPT_PERIODMATCH ); } 复制代码七、   编译下载运行程序,结果如下。两个led灯一个灯会呼吸,一个led灯会闪烁。程序运行也录好了视频,网络问题无法上传,后续会更新相关的视频。 另外使用DAVE的APP模式编程时需要注意,只要对APP模块的应用做了修改,就必须重新产生代码,必须重新产生代码,必须重新产生代码。好了,今天分享结束。 下次继续分享,同时之前也按照其他网友的帖子跑了跑lwip和http服务器,我会将具体操作过程细化,后面再跟大家分享一下。

  • 回复了主题帖: 【 XMC4800 Relax EtherCAT Kit测评】基于XMC4800平台的Ethercat从站机器人扩展模块

    tdatd 发表于 2019-1-30 07:49 我下载的是5.11,在启动的时候提醒能更新,好像是更新协议栈,我也没更新。
    我也用的11版本,没有提示我更新,可能是网络问题吧。

  • 2019-01-29
  • 发表了主题帖: 【 XMC4800 Relax EtherCAT Kit测评】+上手DAVE,DAC_LUT模块应用

    接着上一篇帖子,今天继续上手DAVE,使用DAC_LUT模块,这个是使用查表法生成波形的。操作步骤与之前一样,建立程序后,添加DAC_LUT模块,并依次对DAC_LUT模块进行设置。一、     使用正弦波、余弦波、三角波非常简单,配置即可。                              这里选用的refill模式,采用自动中断模式。另外可以设置波形的频率。DAVE人性化的设计,如果数据选择不对,就会出现提示色。 之后选择波形的样式,分为有符号和无符号两种,可以看下图,无符号是0—4095,有符号是-2048—2047. 另外需要注意在中断设置中选择使能service request。 二、     关于LUT表的定义。这里需要注意的是波形定义在dac_lut_conf.c文件里的DAC_LUT_0_array[]数组里,我把正弦波和三角波的定义数据拷贝出来了,然后重新在excel里画了画,果然是正弦波和三角波。 三、      如果要使用自己定义的波形,可以选择custom模式,然后自己定义波形数据表即可。四、      另外需要注意的是自动填充中断函数已经定义在dac_lut_conf.c里了,用户不需要再定义,否则会出错!另外在该函数中如果添加自己的函数,则程序不会报错,但是会不运行。。。voidRefill_Auto_Interrupt_Handler(void){ DAC_LUT_UpdateNextPoint(&DAC_LUT_0);}好了关于DAC_LUT的应用,就介绍到这里,DAVE APP的应用 说简单也简单,但是要熟悉到精通应用的话,就必须要对APP模块全面熟悉并多应用实践。下次会分享一下PWM的相关应用学习介绍。

  • 回复了主题帖: 【 XMC4800 Relax EtherCAT Kit测评】基于XMC4800平台的Ethercat从站机器人扩展模块

    楼主用的SSC tool工具是什么版本的?5.1.11?有5.12吗?

  • 2019-01-28
  • 发表了主题帖: 【 XMC4800 Relax EtherCAT Kit测评】+上手DAVE,DAC模块使用

    本帖最后由 flyword 于 2019-1-28 05:57 编辑 昨天发帖简单使用了ADC模块,本帖开始使用DAC,一般来说DAC可以用来做波形发生器使用,通过APP模块,我们可以非常快速的使用DAC产生自己想要的波形。然而XMC4800 kit中并没设计相关的硬件用于测试,,当然也可以通过万用表测量,但是这些我目前手头都没有,因此只能简单通过led灯和串口来显示是否程序正常运行。废话不多说了,下面开始,其实使用DAC模块非常简单。步骤如下:1.添加DAC的APP模块即可!然后依次对DAC模块进行配置,具体配置如下,下图可以看出来,有PATTERN,single VALUE,RAMP, NOISE共4种模式。这里我选择第一种进行评测。2.继续配置DAC模块。这里可以设置波形的相关参数,如幅度、频率等等。3.选择使能sign输出,用于与事件探测器对接。4.这里暂停一下,说说整体这次测评所需要的模块,具体如下:要实现的功能是这样的,首先使能DAC后,DAC会自动运行,然后连接sign信号到事件探测器,用来检测该信号,同时触发事件发生器,进而触发一个中断,在中断中通过翻转LED灯和串口输出信息,来检测程序是否正常运行。5.DAC模块与事件探测器和发生器的连接。如下图:6.事件探测器的配置:用来检测探测器sign A信号的上下边沿等。7.事件发生器的设置:8.相关的配置注意事项:依次完成相关IO口的设置,设置为OUTPUT,并配置引脚到led外设上;完成UART的配置,具体可以参考之前的帖子,注意引脚的配置。9.点击产生代码,并下载运行。最终的运行结果截屏和照片如下:实物照片,白框中显示led翻转被点亮啦! 这次分享到此为止。APP模块关于DAC的,还有1个DAC_LUT模块,是一种查表法的DAC输出,下次分享。 此内容由EEWORLD论坛网友flyword原创,如需转载或用于商业用途需征得作者同意并注明出处

  • 2019-01-27
  • 发表了主题帖: 【 XMC4800 Relax EtherCAT Kit测评】+上手DAVE,ADC模块简单应用

    本帖最后由 flyword 于 2019-1-27 18:46 编辑 今天继续分享xmc4800的ADC学习应用,还是使用的DAVE APP,使用过程也非常简单,使用DAVE这个软件好多次了,对于APP模块的应用,我总结大概一般都分为3个步骤,有的可能会更少一点。娜三个步骤呢?一、             APP模块的添加以及配置。这里面配置的内容主要包括一些配置参数、中断设置、以及工作状态,例如是否在初始化后就工作等等,目前应用过的APP主要有TIMER,UART,ADC,具体来说配置都是与应用相关的,配置很简单。二、             HW 信号连接。这里主要是涉及到信号的连接,可以把事件和中断信号连接起来,如之前将timer中的定时事件和软中断连接起来的。三、             引脚配置。将具体应用的引脚配置到xmc4800芯片上。可以图示配置也可以菜单配置。综上所述,使用APP模块,始终离不开这3个步骤,熟悉各个APP模块,可以加快你的产品谁应用。好了,继续今天的分享,如何使用ADC模块。按照上面的步骤,新建DAVE CE工程以后,添加两个模块ADC和UART模块。这次简单应用是ADC模块获得数据后通过串口打印出来。相关的UART使用在这里不再描述了,可以参考之前的帖子。这里重点说说ADC的应用和配置。1.      添加相关的ADC模块。这里有2个跟ADC相关的模块,选择第1个即可。2.      配置ADC模块。采用无触发信号,使能连续转换模式,在分辨率方面选择8位的测量模式,这里一般有8bit 10bit 12bit三种模式。3.设置相关的中断配置需求。在测量结束后产生中中断,中断函数名可以自己定义。4.      引脚配置。这里选择14.0.5.      图纸里面对于ADC的定义标记有点问题,具体如下图,这里不影响使用,因为我们测试的引脚都未连接,测量值应该很小很小。6.      点击产生代码,后对main函数进行修改。具体参考代码如下:/* * main.c #include                  //Declarations from DAVE Code Generation (includes SFR declaration) /** * [url=home.php?mod=space&uid=159083]@brief[/url] main() - Application entry point * * Details of function * This routine is the application entry point. It is invoked by the device startup code. It is responsible for * invoking the APP initialization dispatcher routine - DAVE_Init() and hosting the place-holder for user application * code. */ XMC_VADC_RESULT_SIZE_t result; uint8_t value[10]; void Adc_Measurement_Handler() { #if(UC_SERIES != XMC11)     result = ADC_MEASUREMENT_GetResult(&ADC_MEASUREMENT_Channel_A);           //result=4096; #else       result = ADC_MEASUREMENT_GetGlobalResult(); #endif       sprintf(value,"%d",result);       UART_Transmit(&UART_0,"value:",6);       UART_Transmit(&UART_0, value, sizeof(value));       UART_Transmit(&UART_0,"\r\n",2); } int main(void) {   DAVE_STATUS_t status;   status = DAVE_Init();           /* Initialization of DAVE APPs  */   if(status != DAVE_STATUS_SUCCESS)   {     /* Placeholder for error handler code. The while loop below can be replaced with an user error handler. */     XMC_DEBUG("DAVE APPs initialization failed\n");     while(1U)     {     }   }   ADC_MEASUREMENT_StartConversion(&ADC_MEASUREMENT_0);   /* Placeholder for user application code. The while loop below can be replaced with user application code. */   while(1U)   {   } } 复制代码 7.      编译后运行,putty设置好后,可以看到ADC测量的结果:因为没有电压输入,所以测量的值应该很小,这里测出来的值8、6、7、14等可能是干扰噪声。好了今天的分享到此,明天计划分享DAC模块的简单应用。之所以试用ADC模块,也是为了在后面EtherCAT从站设计中,加入模拟量的测量,简单实现数字量和模拟量都能操作的从站。 此内容由EEWORLD论坛网友flyword原创,如需转载或用于商业用途需征得作者同意并注明出处

  • 2019-01-26
  • 发表了主题帖: 【 XMC4800 Relax EtherCAT Kit测评】+上手DAVE,定时中断与UART简单应用

    昨天晚上发了一个简单应用UART的例子以后,本人就在琢磨如何把定时器和中断应用进去。参考了网友定时器blinky的程序,发现其实定时器用到UART中也比较简单。分享具体的步骤如下:1.    新建工程,添加相关的模块,其中UART的相关APP模块添加和配置可以见上一个帖子。2.    在UART的基础上添加TIMER和INTERRUPT两个APP模块。3.    分别对两个模块设置。TIMER的设置如下,注意要使能定时事件,这样才能连接到中断去。4.    设置中断如下:这里需要注意中断处理句柄函数定义为UerIRQHandler(),需要在后面main程序中自行添加,定义的函数名也可以自己修改。5.    设置TIMER的HW信号连接,将定时事件与中断连接上,配置如下图。6.    然后修改main程序,需要定义全局变量和一个中断处理程序。具体代码如下:#include                   void UserIRQHandler(); UART_STATUS_t init_status; uint8_t valid_str[] = "hello world!\n"; int main(void) {   DAVE_STATUS_t status;   status = DAVE_Init();           /* Initialization of DAVE APPs  */   init_status = (UART_STATUS_t)UART_Init(&UART_0);   if(status != DAVE_STATUS_SUCCESS)   {     /* Placeholder for error handler code. The while loop below can be replaced with an user error handler. */     XMC_DEBUG("DAVE APPs initialization failed\n");     while(1U)     {     }   }   /* Placeholder for user application code. The while loop below can be replaced with user application code. */   while(1U)   {   } } void UserIRQHandler() {           if(init_status==UART_STATUS_SUCCESS){                   UART_Transmit(&UART_0, valid_str, sizeof(valid_str));                    UART_Transmit(&UART_0,"time interrupted",sizeof("time interrupted"));            } } 复制代码 7.    编译、现在运行,使用PUTTY软件,可以看到程序运行正常。总结:计时器的应用非常简单,我们只需要设定好计时数值,这里数值是按照微秒us计算的,不用像以前还需要自己算来配置各个寄存器的值,非常方便,赞一个。XMC4800的硬件资源非常丰富,接下来,我将考虑看看ADC和DAC的使用及DAVE相关操作。网上关于APP的使用教程不多,其实DAVE软件里相关的chm电子资料很多,都配有相关的资料参考,很方便,只要耐下心来,相信大家都能轻松驾驭。 此内容由EEWORLD论坛网友flyword原创,如需转载或用于商业用途需征得作者同意并注明出处

  • 2019-01-25
  • 回复了主题帖: 【 XMC4800 Relax EtherCAT Kit测评】+LWIP应用

    我看里面有个enable RTOS,lwip 与 freertos 冲突 与这个选项有关系吗?

TA暂时无记录哦~

最近访客

< 1/2 >

统计信息

已有327人来访过

  • 芯币:920
  • 好友:--
  • 主题:29
  • 回复:224
  • 课时:--
  • 资源:--

留言

你需要登录后才可以留言 登录 | 注册


现在还没有留言