hujj

  • 2019-07-20
  • 回复了主题帖: 基于STM32F401RE开发板的X-NUCLEO-IKS01A3传感器测试之三3D加速度LIS2DW12传感器测...

    dcexpert 发表于 2019-7-19 22:06 是通过三个轴的参数来判断姿态吧。
    测试和判断都是直接用范例的代码(参见帖子中的代码),调用IKS01A3_MOTION_SENSOR_Get_6D_Orientation_XL()函数之后,直接判断xl,xh,yl,yh,zl,zh六个变量的值。

  • 2019-07-19
  • 发表了主题帖: 基于STM32F401RE开发板的X-NUCLEO-IKS01A3传感器测试之三3D加速度LIS2DW12传感器测...

        今天测试了3D传感器的测试,使用的是LIS2DW12_6Dorientation范例,开始我还以为这个范例是测试加速度的,经过实际操作后才知道是测试传感器放置方向的,即平放(ZH)、卧放(ZL)、正立(YL)、倒立(YH)、左侧立(XL)、右侧立(XH),共6个方向。      依旧是添加LCD驱动程序,添加包含路径等“常规”做法,然后在Send_Orientation()函数中添加LCD的显示代码,代码如下: static void Send_Orientation(void) { uint8_t xl = 0; uint8_t xh = 0; uint8_t yl = 0; uint8_t yh = 0; uint8_t zl = 0; uint8_t zh = 0; if (IKS01A3_MOTION_SENSOR_Get_6D_Orientation_XL(IKS01A3_LIS2DW12_0, &xl) != BSP_ERROR_NONE) { (void)snprintf(dataOut, MAX_BUF_SIZE, "Error getting 6D orientation XL axis from LIS2DW12 - accelerometer.\r\n"); printf("%s", dataOut); LCD_clear_line(4); LCD_clear_line(5); LCD_write_BG(0,4,(uint8_t *)"XL 轴数据错误"); return; } if (IKS01A3_MOTION_SENSOR_Get_6D_Orientation_XH(IKS01A3_LIS2DW12_0, &xh) != BSP_ERROR_NONE) { (void)snprintf(dataOut, MAX_BUF_SIZE, "Error getting 6D orientation XH axis from LIS2DW12 - accelerometer.\r\n"); printf("%s", dataOut); LCD_clear_line(4); LCD_clear_line(5); LCD_write_BG(0,4,(uint8_t *)"XH 轴数据错误"); return; } if (IKS01A3_MOTION_SENSOR_Get_6D_Orientation_YL(IKS01A3_LIS2DW12_0, &yl) != BSP_ERROR_NONE) { (void)snprintf(dataOut, MAX_BUF_SIZE, "Error getting 6D orientation YL axis from LIS2DW12 - accelerometer.\r\n"); printf("%s", dataOut); LCD_clear_line(4); LCD_clear_line(5); LCD_write_BG(0,4,(uint8_t *)"YL 轴数据错误"); return; } if (IKS01A3_MOTION_SENSOR_Get_6D_Orientation_YH(IKS01A3_LIS2DW12_0, &yh) != BSP_ERROR_NONE) { (void)snprintf(dataOut, MAX_BUF_SIZE, "Error getting 6D orientation YH axis from LIS2DW12 - accelerometer.\r\n"); printf("%s", dataOut); LCD_clear_line(4); LCD_clear_line(5); LCD_write_BG(0,4,(uint8_t *)"YH 轴数据错误"); return; } if (IKS01A3_MOTION_SENSOR_Get_6D_Orientation_ZL(IKS01A3_LIS2DW12_0, &zl) != BSP_ERROR_NONE) { (void)snprintf(dataOut, MAX_BUF_SIZE, "Error getting 6D orientation ZL axis from LIS2DW12 - accelerometer.\r\n"); printf("%s", dataOut); LCD_clear_line(4); LCD_clear_line(5); LCD_write_BG(0,4,(uint8_t *)"ZL 轴数据错误"); return; } if (IKS01A3_MOTION_SENSOR_Get_6D_Orientation_ZH(IKS01A3_LIS2DW12_0, &zh) != BSP_ERROR_NONE) { (void)snprintf(dataOut, MAX_BUF_SIZE, "Error getting 6D orientation ZH axis from LIS2DW12 - accelerometer.\r\n"); printf("%s", dataOut); LCD_clear_line(4); LCD_clear_line(5); LCD_write_BG(0,4,(uint8_t *)"ZH 轴数据错误"); return; } if (xl == 1U && yl == 0U && zl == 0U && xh == 0U && yh == 0U && zh == 0U) { (void)snprintf(dataOut, MAX_BUF_SIZE, "\r\n ________________ " \ "\r\n | | " \ "\r\n | * | " \ "\r\n | | " \ "\r\n | | " \ "\r\n | | " \ "\r\n | | " \ "\r\n |________________| \r\n"); LCD_clear_line(4); LCD_clear_line(5); LCD_write_BG(0,4,(uint8_t *)"运动方向: XL"); } else if (xl == 0U && yl == 1U && zl == 0U && xh == 0U && yh == 0U && zh == 0U) { (void)snprintf(dataOut, MAX_BUF_SIZE, "\r\n ________________ " \ "\r\n | | " \ "\r\n | * | " \ "\r\n | | " \ "\r\n | | " \ "\r\n | | " \ "\r\n | | " \ "\r\n |________________| \r\n"); LCD_clear_line(4); LCD_clear_line(5); LCD_write_BG(0,4,(uint8_t *)"运动方向: YL"); } else if (xl == 0U && yl == 0U && zl == 0U && xh == 0U && yh == 1U && zh == 0U) { (void)snprintf(dataOut, MAX_BUF_SIZE, "\r\n ________________ " \ "\r\n | | " \ "\r\n | | " \ "\r\n | | " \ "\r\n | | " \ "\r\n | | " \ "\r\n | * | " \ "\r\n |________________| \r\n"); LCD_clear_line(4); LCD_clear_line(5); LCD_write_BG(0,4,(uint8_t *)"运动方向: YH"); } else if (xl == 0U && yl == 0U && zl == 0U && xh == 1U && yh == 0U && zh == 0U) { (void)snprintf(dataOut, MAX_BUF_SIZE, "\r\n ________________ " \ "\r\n | | " \ "\r\n | | " \ "\r\n | | " \ "\r\n | | " \ "\r\n | | " \ "\r\n | * | " \ "\r\n |________________| \r\n"); LCD_clear_line(4); LCD_clear_line(5); LCD_write_BG(0,4,(uint8_t *)"运动方向: XH"); } else if (xl == 0U && yl == 0U && zl == 0U && xh == 0U && yh == 0U && zh == 1U) { (void)snprintf(dataOut, MAX_BUF_SIZE, "\r\n __*_____________ " \ "\r\n |________________| \r\n"); LCD_clear_line(4); LCD_clear_line(5); LCD_write_BG(0,4,(uint8_t *)"运动方向: ZH"); } else if (xl == 0U && yl == 0U && zl == 1U && xh == 0U && yh == 0U && zh == 0U) { (void)snprintf(dataOut, MAX_BUF_SIZE, "\r\n ________________ " \ "\r\n |________________| " \ "\r\n * \r\n"); LCD_clear_line(4); LCD_clear_line(5); LCD_write_BG(0,4,(uint8_t *)"运动方向: ZL"); } else { (void)snprintf(dataOut, MAX_BUF_SIZE, "None of the 6D orientation axes is set in LIS2DW12 - accelerometer.\r\n"); LCD_clear_line(4); LCD_clear_line(5); LCD_write_BG(0,4,(uint8_t *)"无运动"); } printf("%s", dataOut); }     编译下载后的测试情况如下:     1、测试时的照片:     2、串口助手接收到的数据:       3、平放(ZH)传感器:     4、卧放(ZL)传感器:     5、正立(YL)传感器:     6、倒立(YH)传感器:     7、左侧立(XL)传感器:     8、右侧立(XH)传感器:     注:LCD显示屏中显示的“运动方向”实际上应该为放置方向。 此内容由EEWORLD论坛网友hujj原创,如需转载或用于商业用途需征得作者同意并注明出处

  • 2019-07-18
  • 发表了主题帖: 基于STM32F401RE开发板的X-NUCLEO-IKS01A3传感器测试之二LPS22HH气压传感器

        继昨天完成了STTS751温度传感器测试之后,今天选择了气压传感器进行测试。这次驾轻就熟,打开示例的项目文件,添加好路径及LCD5110的驱动文件,编译下载测试,一气呵成,下面是串口助手收到的气压和温度数据:     在查找变量名时遇到一点小麻烦,最后在int32_t LPS22HH_Read_All_FIFO_Data()函数中找到相应的变量,然后正确地显示在LCD屏幕中(见下图):     下图是屏幕显示的气压及温度: :   此内容由EEWORLD论坛网友hujj原创,如需转载或用于商业用途需征得作者同意并注明出处

  • 回复了主题帖: 基于STM32F401RE开发板的X-NUCLEO-IKS01A3传感器测试之一 STTS751温度传感器测试

    LCD5110的驱动代码:   STTS751的测试代码:  

  • 回复了主题帖: 基于STM32F411RE的ST MEMS传感器板(IKS01A3) 开箱体验!

    本帖最后由 hujj 于 2019-7-19 08:49 编辑
    nmg 发表于 2019-7-18 08:52 哈哈,分享论坛一份
    Unicleo-GUI_Setup.exe文件已经上传到下载中心的【应用技术】栏目,等待审核。   已经审核通过,下载链接: http://download.eeworld.com.cn/detail/hujj/603974

  • 回复了主题帖: 基于STM32F411RE的ST MEMS传感器板(IKS01A3) 开箱体验!

    zjxieyanjun 发表于 2019-7-18 09:40 请问这个是申请的样板还是购买的?哪里可以?
    这是申请的。

  • 上传了资料: Unicleo_GUI_Setup

  • 回复了主题帖: 基于STM32F411RE的ST MEMS传感器板(IKS01A3) 开箱体验!

    nmg 发表于 2019-7-18 08:52 哈哈,分享论坛一份
    行啊!不过文件太大,有近24M,超过15M的限制,要上传到下载中心。  

  • 加入了学习《基于STM32F401RE开发板的X-NUCLEO-IKS01A3传感器测试之一 》,观看 基于STM32F401RE开发板的X-NUCLEO-IKS01A3传感器测试之一STTS751温度传感器测试

  • 回复了主题帖: 基于STM32F401RE开发板的X-NUCLEO-IKS01A3传感器测试之一 STTS751温度传感器测试

    这是测试的视频:  

  • 回复了主题帖: 基于STM32F411RE的ST MEMS传感器板(IKS01A3) 开箱体验!

    DavidZH 发表于 2019-7-18 00:07 我是直接在ST官网下载的,去官网找下,不行的话,再告诉我;
    今天早上5点就起床,终于成功登录了网站,下载到了Unicleo_GUI的安装程序。谢谢了!

  • 2019-07-17
  • 回复了主题帖: 基于STM32F411RE的ST MEMS传感器板(IKS01A3) 开箱体验!

        请问楼主使用的是这个网页打开图形操作界面吗?我每次点击最后都是打不开页面,最长的时间等了近一个小时。

  • 发表了主题帖: 基于STM32F401RE开发板的X-NUCLEO-IKS01A3传感器测试之一 STTS751温度传感器测试

        收到X-NUCLEO-IKS01A3套件后,一直都在查找、下载资料,阅读相关的手册和分析代码。我使用的是STM32F401RE开发板,在Keil V5.28平台下测试,经过几天的反复测试,STTS751温度传感器终于测试通过了。为了测试时更直观,我还添加了LCD5110作为显示用。下面详细介绍测试过程。   一、硬件连接     开始测试之前,首先是考虑如何接线。起初我按照习惯,在下载的资料中查找传感器板上的接线定义,以便用杜邦线与开发板连接。后来才知道两块板子引脚都是遵循了Arduino UNO R3规范,只要直接插上就行。难怪传感器板子上面有个凹口,正好是留给操作开发板上按钮和观察LED灯的,起初拿到传感器板子时我还纳闷为何要做成如此不规则的形状呢。     插上传感器板子之后,凹口正对着开发板上的按钮和LED灯:      二、软件及开发平台     硬件连接解决之后,紧接着就是软件及开发平台。在下载解压和查看了多个软件包之后,发现STM32CubeExpansion_MEMS_V6.20这个软件包是最新的版本。     在这个软件包的projects子文件夹下有四种STM32的开发板资料,其中就包括了STM32F401RE-Nucleo开发板,这对于我这个初学者来说无疑是一个好消息,可以让我少走不少弯路。     点击进入后又有Applictions和Examples两个子文件夹,我的英文差,于是分别将这两个文件夹截图并标注上中文,以方便使用。     我从“ST_Open_MEMS教程”中看到首先要在线接受软件许可使用协议后,取得开发板密钥后方能解锁使用(如下图所示),弄得我到处去找在线接受许可的界面,好不容易找到一个界面,可点击之后老半天没有反映。然后又看到需要一个“Sensor Fusion GUI”软件来配合调试,可找了许久也没有下载到此软件。最后还是决定自己添加一块LCD5110显示屏来作测试过程的显示用。      三、添加LCD5110显示屏     这个添加对我来说不算难事,选定了驱动LCD的引脚之后,用杜邦线连接好LCD,然后再将相应的代码移植过来就行了。     我是将LCD驱动及显示文件和字库文件全部放在mydrive文件夹里,只需要将这个文件夹复制过来,再设置好搜索路径,在主程序里写上下面的代码:     LCD_init();         //初始化LCD5110     display_main();       下图是准备添加的LCD显示屏:     下图是测试的照片:     下图是初始屏幕上显示的内容:        四、STTS751温度传感器测试     首次使用,我理所当然地先打开了“示例”文件夹,选择“IKS01A3”子文件夹后,然后在打开了STTS751的工程示例。为了能在LCD显示屏上显示当前温度,在main()函数的主循环里,顺藤摸瓜找到MX_MEMS_Process()函数,然后再找到Send_Temperature()函数,从而得到温度的变量名,弄清楚了系统是用out_value.sign变量来表示温度值的正负(0为正数,大于0为负数),然后out_value.int变量表示温度值的整数部分,out_value.dec变量表示小数部分,至此,显示在LCD屏幕上就容易了,下面是显示的代码:   if(out_value.sign > 0)          LCD_write_ASCII(0,5,(uint8_t *)"TEMP:-");   else          LCD_write_ASCII(0,5,(uint8_t *)"TEMP:+");     LCD_write_ASCII(54,5,(uint8_t *)".");   LCD_write_value(36,5,3,0,0,(int)out_value.out_int);     LCD_write_value(59,5,2,0,1,(int)out_value.out_dec);     这是测试过程:     下图是动态显示的实时温度:     下图是屏幕显示与串口通讯的数据对比:

  • 2019-07-16
  • 回复了主题帖: 获奖名单【TI AMIC110 多协议通信芯片工业应用优化解决方案】

    确认个人信息无误,谢谢EEWORLD!

  • 2019-07-15
  • 回复了主题帖: X-NUCLEO-IKS01A3 官方技术资料

    谢谢版主分享!正在查找这些资料呢。

  • 2019-07-13
  • 回复了主题帖: 收到X-NUCLEO-IKS01A3传感器套件了

    哦,我说怎么我的快递中没有这玩艺呢。

  • 发表了主题帖: 收到X-NUCLEO-IKS01A3传感器套件

        昨天傍晚收到短信,晚饭后立即前往代收点取回了快递。打开外包装,露出了传感器套件(见下图)。     拆开吹塑盒,取出套件。这是正面:     这是反面,引脚为排针。     这次使用的开发平台是STM32F401,这块开发板是不久前在STM32社区参加答题活动获得的,正好派上用场。     这是合影:     来个裸照:     今天开始搭建开发平台,打开之前下载的STM32F401范例,Keil自动下载升级包,由于网速慢,花了近两个小时,仍有不少放弃下载的升级包,等以后再更新吧。     到发帖为止,Keil仍在下载解压中,慢慢等吧。  

  • 2019-07-10
  • 回复了主题帖: “沁恒评估板诚芯送”活动答疑帖

    SuiBianLiuLiu 发表于 2019-7-10 17:06 你看看是不是T1的定时时钟被你改了,有3种模式,Fsys, Fsys/4,Fsys/12.
    仅仅是在mInitSTDIO()函数里进行了修改,其他未作变动,具体情况还待排查。

  • 回复了主题帖: CH549EVT开发板测试——评测总结

    我芯永恒 发表于 2019-7-10 13:49 测评很棒!祝后期的产品生产顺利,期待您的分享。
    谢谢夸奖!我会努力的。

  • 发表了主题帖: CH549EVT开发板测试——评测总结

        首先感谢沁恒电子和EEWORLD共同举办这次“沁恒评估板诚芯送”活动,让我有机会了解了CH549单片机。这是一款兼容MCS51指令集的增强型E8051内核单片机,从它身上可以看到51单片机的影子,但运算速度和片上资源又比传统的51单片机强多了。它继承了51特有的位操作指令,在我看来这比操作STM32单片机引脚要更方便些。经过半个多月的实验,我认为这是比较适合初学者上手而且功能比较丰富的单片机之一,值得花时间去了解和掌握,并应用到自己的项目中。     我这次的项目是准备做一个超声波水位仪,用于需要探测水位高低的场合(如小水电站的前池),项目方案是通过超声波传感器检测仪器到水面的距离,然后推算水位的高低,并通过无线模块将数据传输到机房。到目前为止,实验已经基本完成,SR04超声波模块、LCD5110显示、nRF24L01无线模块都已正常驱动和调试完成,仅仅是机房接收模块尚未完成,仍在调试过程中。     在此次评测过程中,我首先进行了LED流水灯的实验,这个非常简单的实验很轻松就完成了。然后尝试了触摸按键的操作,还曾想延伸应用到防盗报警场合中,但将触摸按键连接到门窗等物体后,电容变化太大了,按键失灵不成功。之后还测试了串口0通讯及SPI通讯,在电脑上通过串口调试助手与开发板建立起了通讯,通过逻辑分析仪检测SPI引脚,也得到了正确的数据时序。鉴于时间关系和本次评测计划,其他的硬件功能没有去测试,电容触摸按键也未作深入学习。     下面是本次评测情况:   一、项目组成简图 二、评测过程 1、驱动LCD5110显示屏     这是一款经典的用于诺基亚手机的LCD显示屏,分辨率为64*84点阵,因为基本上都是从手机上拆下再配上PCB板的二手货,所以物美价廉。显示屏的驱动是非常成熟的,定义好引脚就OK了,只是软字库定义出了点小状况,由于隔久了未接触51单片机,忘记了用code来将字库定义在代码区,反复用static和const来定义字库文件,编译总出错,提示数据太大,后来在沁恒的工程师提醒下才回忆起应该用code来定义。下图是LCD5110的显示情况:     下面是LCD5110的代码: #include ".\Public\CH549.H" #include ".\Public\DEBUG.H" #include ".\mydrive\lcd_5110.h" #include ".\mydrive\ascii5x8.h" //5x8ASCII????? #include ".\mydrive\charcode.h" //12x16(14)??????? #include ".\mydrive\asciicode.h" //5x8(8)ASCII??? /********************************************* * ?????????Delay * ???????????????? * ????????xms?? ????:?????? * ??????????? * ????? *********************************************/ void Delay(UINT8 xms) { UINT8 x,y; for(x=xms;x>0;x--) for(y=10;y>0;y--); //for(y=110;y>0;y--) } /********************************************* * ?????????LCD_write_byte * ????????????SPI??????д????/????LCD * ????????data??????:д???????? * dc :д????1/????0??? * ??????????? * ????????D/C(LCD_DC)???????д????????D/C=0)?????????D/C=1) *********************************************/ void LCD_write_byte(UINT8 dat,UINT8 dc) { UINT8 i; LCD_CLK = 0; //?????????CLK LCD_CE = 0; //???5110 LCD_DC = dc; //dc=0????,dc=1???? for(i=0; i<8; i++) //????8λ { if (dat & 0x80){ LCD_DIN = 1; } else{ LCD_DIN = 0; } LCD_CLK = 1; Delay(1); dat = dat << 1; //??λ????????????λ LCD_CLK = 0; //?????????? } LCD_CE = 1; //???5110 } /********************************************* * ?????????LCD_set_XY * ?????????????LCD?????? * ????????X ??????:0-83?? * Y :0-5 * ??????????? * ????? *********************************************/ void LCD_set_XY(UINT8 X,UINT8 Y) { LCD_write_byte(0x40 | Y,0); //column? LCD_write_byte(0x80 | X,0); //row? } /********************************************* * ?????????LCD_clear * ?????????5110??????????д??????? * ?????????? * ??????????? * ??????? *********************************************/ void LCD_clear(void) { UINT8 i,j; LCD_set_XY(0,0); //??λ????? for (i=0; i<6; i++) { for (j=0; j<84; j++) { LCD_write_byte(0x00,1); } } } /********************************************* * ?????????LCD_init * ?????????5110????? * ?????????? * ??????????? * ???????????????????RES???????帴λ????VDD?????????? * ???100ms,RST?????????<0.3VDD?? *********************************************/ void LCD_init(void) { // LCD_Config(); //????LCD???? LCD_RST = 0; //??λLCD5110 Delay(2); LCD_RST = 1; LCD_CE = 0; //???LCD Delay(2); LCD_CE = 0; //???LCD LCD_write_byte(0x21,0); //??????LCD??????LCD?? LCD_write_byte(0xc8,0); //???????????? LCD_write_byte(0x06,0); //???У??????????2?? LCD_write_byte(0x13,0); //1:48 LCD_write_byte(0x20,0); //??????????V=0?????? LCD_write_byte(0x0c,0); //?趨?????????????? LCD_clear(); //???? LCD_CE = 0; //???LCD } /********************************************* * ?????????LCD_write_ASCII * ?????????????????5*7(8) * ????????x,y,cid ??:???ASCII??? * ??????????? ?????к??32~127 * ?????ASCII????????ASC_5[95][8]???? *********************************************/ void LCD_write_ASCII(UINT8 X,UINT8 Y,UINT8 *stru) { UINT8 i; // j = cid - 32; LCD_set_XY(X,Y); //??λ???????? while (1) { for ( i=0; i<5; i++) //??????5*7??? { LCD_write_byte(ASC_5[*stru-32],1); } stru++; if(*stru == '\0') break; //??????????????????????'\0' LCD_write_byte(0x00,1); //??????? } } /********************************************* * ?????????LCD_write_ASCII * ???????????????????5*7(8) * ????????x,y,cid ??:???ASCII??? * ??????????? ?????к??32~127 * ?????ASCII????????ASC_5[95][8]???? *********************************************/ void LCD_write_ASC_SIN(UINT8 X,UINT8 Y,UINT8 cid) { UINT8 i; LCD_set_XY(X,Y); //??λ???????? for ( i=0; i<5; i++) //??????5*7??? { LCD_write_byte(ASC_5[cid-32],1); } } /********************************************* * ?????????LCD_write_ASC7x12 * ????????????????????7*12(16) * ????????x,y,cid ??:???????? 0 1 2 3 4 5 6 7 8 9 = m s * ??????????? ?????к??0,1,2,3,4,5,6,7,8,9,10,11,12 * ?????ASCII????????ASC_7[13][14]???? *********************************************/ void LCD_write_ASC7x12(UINT8 X,UINT8 Y,UINT8 cid) { UINT8 i; LCD_set_XY(X,Y); //??λ???????? for (i=0; i<7; i++) //??????????????7?У? { LCD_write_byte(ASC_7[cid],1); } LCD_set_XY(X,Y+1); //?????????°??? for (i=7; i<14; i++) { LCD_write_byte(ASC_7[cid],1); } } /********************************************* * ?????????LCD_write_CHAR * ????????????????????12*14(16) * ????????x,y,cid ??:???????? ??????????????? * ??????????? ?????к??0,1,2,3,4,5,6,7,8,9,10 * ?????CHAR????????CHAR_12[11][24]???? ***********************************************/ void LCD_write_char(UINT8 x,UINT8 y,UINT8 cid) { UINT8 i; LCD_set_XY(x,y); //??λ???????? for (i=0; i<12; i++) //д???????????12?У? { LCD_write_byte(CHAR_12[cid],1); } LCD_set_XY(x,y+1); //д??????°??? for (i=12; i<24; i++) { LCD_write_byte(CHAR_12[cid],1); } } /********************************************* * ?????????LCD_write_string * ????????????????????? * ????????x,y,*stru ??:?????????? * ??????????? * ???????????????????????cid_12?????????е??к?????????????? ***********************************************/ void LCD_write_string(UINT8 x,UINT8 y,UINT8 *stru) { UINT8 j,n; while(1) { // for (j = 0; j < 38; j++) //??????????????к? j = 0; while(1) { n = 0; //?????????????????? if((stru[0] == cid_12[j][0]) && (stru[1] == cid_12[j][1])) { n = j; //????к?????????? break; } j++; if(*cid_12 == '\0') break; } LCD_write_char(x, y, n); x += 12; stru += 2; if(*stru == '\0') break; //??????????????????????'\0' LCD_write_byte(0x00,1); //??????? } } /********************************************* * ?????????LCD_write_value * ???????????????????5*7(8)??7*12??16?? * ????????x,y,L,val :?????????С?????????1??? 0????????????? * ??????????? ?????к?? * ?????ASCII????????ASC_5[95][8]???? *********************************************/ void LCD_write_value(UINT8 X,UINT8 Y,UINT8 L,UINT8 D,UINT8 Z,UINT16 val) { UINT8 i,j,f = 0; //???????????????????? UINT16 t,cid; //???????????????? UINT32 n; //??????? t = val; n = 1; if(Z == 1) f = 16; //???=0????0??=16 for (j = 0; j < L; j++) n = n * 10; LCD_set_XY(X,Y); //??λ???????? for (j = L; j > 0; j--) //????????? { n = j < 2 ? 1: n / 10; //?????????? cid = t / n; //???λ???? t = t - (cid * n); if ((cid > 0)|(j-1 == D)) //??????0 f = 16; for ( i=0; i<5; i++) //д???5*7??? { LCD_write_byte(ASC_5[cid + f],1); } if ( D > 0 & D == (j - 1)) { for ( i=0; i<5; i++) //дС???? { LCD_write_byte(ASC_5[14],1); } } else if(j>1) LCD_write_byte(0x00,1);//??????? } }       2、SR04超声波模块的驱动     这也是非常普及的超声波测距传感器,探测距离通常在2~450厘米范围。通过向模块的Trig引脚发送不少于10毫秒的高电平信号,稍等片刻便可从Echo引脚得到返回的高电平信号,信号持续时间与超声波探测距离成正比。我们知道声波的速度是340米/秒,超声波来回则是170米/秒,合17厘米/毫秒,约58.8微秒/厘米。 我借用了范例中已经开启的定时器1来作测量计数,定时器的中断周期为100微秒,按此计算理论上的测量误差约为2厘米,对于本应用项目来说已经是精度足够了,因为流动时水波也会有几厘米变化。下面是测试时的照片:     在屏幕左边安排了一个模拟水位高低的柱状图,可以动态显示当前水位,左上部分是检测设备安装的高度值,检测的水位高度在0M与设备安装的高度之间。右边最上一行数值是计算出来的水位高度,第二行是超声波实际测量的距离,第三行是预备显示时间用的,最底行是显示设备安装高度和检测数据响应的偏差范围。     为了方便定时器1做其他事情我在其中断代码里判断Echo引脚,高电平时即对count变量计数,代码如下: /**************************************************************************** * Function Name  : mTimer1Interrupt() * Description    : CH549定时计数器1定时计数器中断处理函数 100us中断 ****************************************************************************/ void mTimer1Interrupt( void ) interrupt INT_NO_TMR1 using 2  //timer1中断服务程序,使用寄存器组2 {     //方式2时,Timer1自动重装     static UINT16 tmr1 = 0;     tmr1++;     if(tmr1 == 2000)                                //100us*2000 = 200ms     {         tmr1 = 0;         SCK = ~SCK;        LED0 = ~LED0;     }    ms++;    if(SR04_Echo==1)                          //收到返回信息        count++; }       传统的检测代码是当Echo为高电平时则一直循环计数,这样当超声波模块出故障时,由于该引脚电平一直不降低,程序便进入了死循环。而我则试用了延时100毫秒后主动结束检测的方法,避免了这个问题,下面是超声波检测、距离计算及显示部分的代码: void level_handler(void)         //检测水位 {    UINT16 levs;    UINT8 c,d,i,l,m,n;    /* 超声波测距 */    levs = 0;    for(i=0;i<5;i++){        SR04_Trig = 1;        mDelaymS(1);        count = 0;        SR04_Trig = 0; //     while(1==SR04_Echo);   //通常采用循环法等待信号结束        mDelaymS(100);          //我用延时法主动完成检测        levs = levs +count;    }    levs = levs * 17 / 10;      //计算检测距离(仪器到水面)200/80/5       if(levs > 500){        LCD_write_ASCII(43,3," ERROR");        data_buf[10] = 'E';    }    else{        LCD_write_value(45,3,5,2,0,levs);        data_buf[10] = 'C';    }    levs = height - levs;         //计算水位高度(安装高度-检测距离)    if(levs<=500){        if(ABS(level,levs)>devia){//水位变化超过范围,更新数据            level = levs;               }    }    LCD_write_value(51,2,4,1,0,level/10);      下面是动态显示水位柱状图的代码:    //动态显示当前水位    LCD_write_ASCII(6,1,"    ");    LCD_write_ASCII(6,2,"    ");    LCD_write_ASCII(6,3,"    ");    LCD_write_ASCII(6,4,"    ");      l = 4 - (level / (height / 4));    LCD_write_value(6,l,3,1,0,level/10);       d = level *48 / height;   //计算需要显示模拟高度的点        m = d / 8;                //取模    n = d % 8;                //取余    for (i=0; i<6; i++)    {        for (c=1; c<3; c++)         {           if (i < m)           {               LCD_set_XY(c,5-i);                LCD_write_byte(0xFF,1);  //显示全部点             }           else if (i == m)           {               LCD_set_XY(c,5-i);                LCD_write_byte(map[n],1);//显示部分点           }            else           {               LCD_set_XY(c,5-i);                LCD_write_byte(0x00,1);  //不显示点           }         }    }       最后是发送水位信息的代码:    /* 发送水位信息 */    data_buf[6] = level / 1000 + '0';    data_buf[7] = level % 1000 / 100 + '0';    data_buf[8] = level % 1000 % 100 / 10 + '0';    data_buf[9] = level % 1000 % 100 % 10 + '0'; //printf("ch %d up,value:%d\n",(UINT16)ch, value);    LED_Control(3,1);        //发出开始信号(P2^5 = 0)    for(i=0;i<12;i++){         CH549SPIMasterWrite(data_buf);//发送到nRF24L01无线模块    }    printf("\n%s",data_buf);    SPI_Write_Buf(WRITE_REG+STATUS, data_buf, 12);  //要发送的数据data_buf,长度12字节    LED_Control(3,0);        //发出结束信号(P2^5 = 1) }          3、nRF24L01无线模块的驱动     这款无线模块我是初次使用,代码是从51的示例中移植过来的,编译及运行没有发现问题。接收部分使用的是GD32F350开发板,代码也是刚移植的,目前在GD32F350上调试没有成功,接收不到发送的信息。由于缺乏检测设备,目前还不清楚原因何在,还需要继续排查。下图为接收装置:     以下是nRF24L01的驱动代码(CH549开发板): #include "nrf24l01.h" extern UINT8 data_buf[]; void nrf24l01_Init(void) //nrf24l01????? { NRF_CE = 0; // chip enable NRF_CSN = 1; // Spi disable SPI_SCK = 0; // Spi clock line init high } void power_off() //???????? { NRF_CE=0; SPI_RW_Reg(WRITE_REG + CONFIG, 0x0D); NRF_CE=1; mDelayuS(20); } /************************************************** Function: SPI_RW_Reg(); Description: Writes value 'value' to register 'reg' /**************************************************/ UINT8 SPI_RW_Reg(UINT8 reg, UINT8 value) //д????? { UINT8 status; NRF_CSN = 0; //???????????????CSN status = SPI_RW(reg); //??????? SPI_RW(value); //д????? NRF_CSN = 1; //????CSN return(status); //????nRF24L01???? } /************************************************** Function: SPI_RW(); ????????д??NRF24L01???????????????? ????SPIЭ?飬??д?????????NRF24L01 **************************************************/ uchar SPI_RW(uchar byte) { uchar bit_ctr; for(bit_ctr=0;bit_ctr<8;bit_ctr++) // д8-bit { SPI_MOSI = (byte & 0x80); // д???λ??MOSI byte = (byte << 1); // ??λ SPI_SCK = 1; // ????SCK SPI_MISO = 1; // ??????? byte |= SPI_MISO; // ?????misoλ SPI_SCK = 0; // ????SCK????????? } return(byte); // ????0 } /************************************************** Function: SPI_Read(); ??NRF24L01?????????????? /**************************************************/ BYTE SPI_Read(BYTE reg) { BYTE reg_val; NRF_CSN = 0; // ????NRF_CSN?????????? SPI_RW(reg); // ????????????? reg_val = SPI_RW(0); // ?????? NRF_CSN = 1; // ????CSN?????????? return(reg_val); // ??????????? } /************************************************** Function: SPI_Read_Buf(); ????????reg????????????????? ?????????Rx??Ч?????Rx/Tx??? **************************************************/ uchar SPI_Read_Buf(BYTE reg, BYTE *pBuf, BYTE bytes) { uchar status,byte_ctr; NRF_CSN = 0; // ????NRF_CSN?????????? status = SPI_RW(reg); // ????д??????????????? for(byte_ctr=0;byte_ctr<bytes;byte_ctr++) pBuf[byte_ctr] = SPI_RW(0); // ???SPI_rw??NRF24L01?????? NRF_CSN = 1; // ????NEF_CSN?????????? return(status); // ????nRF24L01???? } /************************************************** Function: SPI_Write_Buf(); ??????????*pbuf????????д??nrf24l01 ???????д??Tx??Ч?????Rx/Tx??? ????????? reg ????? pBuf ????????? bytes ??????????? **************************************************/ uchar SPI_Write_Buf(BYTE reg, BYTE *pBuf, BYTE bytes) { uchar status,byte_ctr; NRF_CSN = 0; // ????NRF_CSN??????? status = SPI_RW(reg); // ????д??????????????? for(byte_ctr=0; byte_ctr<bytes; byte_ctr++) // ?????????д????????*pbuf?? SPI_RW(*pBuf++); NRF_CSN = 1; // ????NRF_CSN?????????? return(status); // ????nRF24L01???? } /************************************************** Function: RX_Mode(); ?????????NRF24L01?豸??????RX???? ????RX?????д??RX??Ч??????? ???????????????????????????LNA HCURR???? ???????ce???л?????λ??????ζ????豸????????????????? **************************************************/ void ifnnrf_rx_mode(void) { power_off(); NRF_CE=0; //????? // SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); // ??????豸??????????豸??????? SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDR, TX_ADR_WIDTH); SPI_RW_Reg(WRITE_REG + EN_AA, 0x01); // ???????????pipe0 SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01); // ????Pipe0 SPI_RW_Reg(WRITE_REG + RF_CH, 30); // ???RF???40 SPI_RW_Reg(WRITE_REG + RX_PW_P0, TX_PLOAD_WIDTH); // ?????Tx??Ч???????????Rx??Ч?????? SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07); // tx_pwr:0dbm???????????2Mbps??lna:hcurr SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f); // ????pwr_upλ??????crc??2????&amp;prim:rx??Rx_Dr?????á? NRF_CE = 1; // ???????? // ???豸???????????????????Tx?豸???????16?????Ч???????????? // '3443101001',??????????????????????10????????40??????????=2Mbps?? } /************************************************** Function: TX_Mode(); ?????????NRF24L01?豸??????Tx????????Tx??????auto.ack????Rx????? ???Tx??Ч????????????????????????Tx PWR?? ??????pwr_????????crc??2??????prim:tx?? TODO:CE???????????壨>10us??????????????????????????豸?е??????? **************************************************/ void ifnnrf_tx_mode(void) { power_off(); NRF_CE=0; // SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH); // ??Tx???д??NRF24L01 SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDR, TX_ADR_WIDTH); // SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); // rx_addr0?????????tx_adr??? SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDR, TX_ADR_WIDTH); SPI_Write_Buf(WR_TX_PLOAD, data_buf, TX_PLOAD_WIDTH); // ??????д??Tx???? SPI_RW_Reg(WRITE_REG + EN_AA, 0x01); // ??????????:Pipe0 SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01); // ????Pipe0 SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x1a); // 500us + 86us, 10 retrans... SPI_RW_Reg(WRITE_REG + RF_CH, 30); // ???RF???40 SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07); // TX_PWR:0dBm, Datarate:2Mbps, LNA:HCURR SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e); // Set PWR_UP bit, enable CRC(2 bytes) & Prim:TX. MAX_RT & TX_DS enabled.. NRF_CE=1; } void SPI_CLR_Reg(BYTE R_T) { NRF_CSN = 0; // ????NRF_CSN??????? if(R_T==1) SPI_RW(FLUSH_TX); // ????FLASH_TX????? else SPI_RW(FLUSH_RX); // ????FLASH_RX????? NRF_CSN = 1; // ????NEF_CSN?????????? } void ifnnrf_CLERN_ALL() { SPI_CLR_Reg(0); SPI_CLR_Reg(1); SPI_RW_Reg(WRITE_REG+STATUS,0xff); NRF_RQ=1; }       三、总结     如前所述,通过参加这次评测活动,我对CH549单片机有了初步的了解,项目也基本完成。待接收部分调试完成后,准备使用赠送的芯片按自己的需要设计PCB板,制作工业化测试的产品,以便到现场测试和改进,争取最终形成产品。有关后续进展,我会在EEWORLD论坛发帖的。下面是评测过程中的部分照片:       最后是项目压文件的缩包: 此内容由EEWORLD论坛网友hujj原创,如需转载或用于商业用途需征得作者同意并注明出处

最近访客

< 1/6 >

统计信息

已有202人来访过

  • 芯币:968
  • 好友:2
  • 主题:69
  • 回复:452
  • 课时:5
  • 资源:3

留言

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


现在还没有留言