北方

  • 2019-10-10
  • 回复了主题帖: 任选下载有礼|《新概念模拟电路》全五册合集/《ADI 参考电路合集 (第4册) 》

    5合1下载,确实实用。 晒单如下

  • 2019-10-08
  • 回复了主题帖: 【DFRobot电机驱动】+直流电机驱动arduino范例程序分析

    hujj 发表于 2019-10-1 20:32 只能用Arduino吗?用GPIO该如何做呢?
    参照芯片手册,只是用数字0/1控制方向,模拟输出控制转速。任何MCU都可以的。

  • 2019-09-30
  • 回复了主题帖: “赞一赞我的国”:集合啦,侃侃好用的国产单片机

    侃侃好用的国产单片机 ——敲黑板,往这里看,沁源单片机 1、国产单片机其实比大家想象得要多得多,尤其是最近在半导体大基金的助推下,至少不下40种。ARM也趁机推出了designSpark服务,对初创企业免费提供M0的IP,因此做ARM单片机的门槛其实已经降得足够低了。 DesignSpark是提供免费IP,只需要自己购买一套对应的FPGA模拟开发板就可以入坑了。 2、但是,需要敲黑板的是,沁源却坚持自己的道路,在8051的一条路走到黑。扩展了自己的代码和开发库,大家看到的支持USB接口,后面其实有数不清的日夜,开发者的奋战。 对于码农来说,读代码如读人,看似简单的一挥手,都是不断把发际线往后推的过程。 其实,并不容易,对标国产的单片机,包括日本的瑞萨其实也有杀招,就是把自己的RL系列也推出1.99元人民币甚至1元的特价,就是要打压对手。 只用一个产品线和瑞萨的全系列产品线扛着,其实不易。没有包括STC的低端艰难求存,就没有瑞萨和ST的低价芯片。从这个角度,其实大家确实应该力所能及支持国产的产品。 3、沁源也是有拓展行动的。参加过2次沁源的开发板活动,也持续关注其发展,知晓也要在蓝牙芯片上开发新的系列。因为从扩展8051代码的过程看,应该具有这样的实力把事情做好。前面汇顶科技也推出自己的蓝牙芯片,但作为小厂,沁源更值得期待。如果出来样板,我会自购一套尝鲜的。估计,就想乐鑫的ESP一样,也会成为市场上的旋风。 4、做完硬推,就还是吐槽一下沁源。首先,产品的开发库还是要持续完善,现有的产品完成简单任务确实可以了,但是如果能增加精简rtos就能够更多的应用场景,完全没必要跳到ARM-M0的16位机去。在Keil-Tiny-RTX最多只有几kB就可以了,而且是开源的,完全可以移植到8051的8位机上。只是,因为时间有限,按照手册移植不成功就没有继续debugg弄下去。还有,如果有号召力的产品,应该在官网上开一个开源社区,让大家一起去贡献代码,有些和硬件有关系的地方,开发者自己啃就太费劲了,在社区求助一下,厂家一对一提供一下资料就可以搞定(提供内部资料前可以签保密协议)。这样也能更好滴发展啊。 5、赞一赞我的国,更要赞一赞这些默默刷代码的码农们和硬创客,另外也谢谢众多无偿分享热量的版主们。祝大家国庆快乐,不怕推特,不怕非死不可,努力砸盘,希望过节了股市也红一个。  

  • 2019-09-26
  • 发表了主题帖: 【DFRobot电机驱动】+直流电机驱动arduino范例程序分析

    本帖最后由 北方 于 2019-9-27 15:49 编辑 1、官网提供了一个如下arduino范例 *! * @file QuadMotorDriverShield.ino * @brief QuadMotorDriverShield.ino Motor control program * * Every 2 seconds to control motor positive inversion * * @author linfeng(490289303@qq.com) * @version V1.0 * @date 2016-4-5 */ const int E1 = 3; ///<Motor1 Speed const int E2 = 11;///<Motor2 Speed const int E3 = 5; ///<Motor3 Speed const int E4 = 6; ///<Motor4 Speed const int M1 = 4; ///<Motor1 Direction const int M2 = 12;///<Motor2 Direction const int M3 = 8; ///<Motor3 Direction const int M4 = 7; ///<Motor4 Direction void M1_advance(char Speed) ///<Motor1 Advance { digitalWrite(M1,LOW); analogWrite(E1,Speed); } void M2_advance(char Speed) ///<Motor2 Advance { digitalWrite(M2,HIGH); analogWrite(E2,Speed); } void M3_advance(char Speed) ///<Motor3 Advance { digitalWrite(M3,LOW); analogWrite(E3,Speed); } void M4_advance(char Speed) ///<Motor4 Advance { digitalWrite(M4,HIGH); analogWrite(E4,Speed); } void M1_back(char Speed) ///<Motor1 Back off { digitalWrite(M1,HIGH); analogWrite(E1,Speed); } void M2_back(char Speed) ///<Motor2 Back off { digitalWrite(M2,LOW); analogWrite(E2,Speed); } void M3_back(char Speed) ///<Motor3 Back off { digitalWrite(M3,HIGH); analogWrite(E3,Speed); } void M4_back(char Speed) ///<Motor4 Back off { digitalWrite(M4,LOW); analogWrite(E4,Speed); } void setup() { for(int i=3;i<9;i++) pinMode(i,OUTPUT); for(int i=11;i<13;i++) pinMode(i,OUTPUT); } void loop() { M1_advance(100); M2_advance(100); M3_advance(100); M4_advance(100); delay(2000); ///<Delay 2S M1_back(100);'g1、官网提供了一个如下arduino范例   *! * @file QuuadMotorDriverShield.ino * @brief QuadaMotorDriverShield.ino Motor control pnrogram * * Every 2 seconds to control m M2_back(100); M3_back(100); M4_back(100); delay(2000); ///<Delay 2S }   2、连接后测试结果 2.1 本次测试连接了M1,使用5V电源转接,如下图。其中,首先用发光二极管代替电机测试连接状态,测试成功后再换电机连接。   2.2 更改源代码,只留下和M1相关的代码,如下, 2.3 连接后显示视频结果如下。 使用发光二极管的测试结果 使用5V直流电机的效果如下。 这样的结果说明硬件运行良好,同时可以看到,使用这个扩展板,不需要再程序中使用扩展库,直接使用GPIO的模拟数字输出就可以。直接适用用于各种创客开发。 其中扩展板和主板之间电源接口是共用5V和GND地的。对于扩展板其实是2路供电,一路是控制电源,一路是驱动电机的电源,两者之间是不同用的。 此内容由EEWORLD论坛网友北方原创,如需转载或用于商业用途需征得作者同意并注明出处  

  • 发表了主题帖: 【DFRobot电机驱动】+开箱及测试

    1、感谢EEWorld评测活动所提供的,DFRobot(http://www.dfrobot.com.cn/goods-1317.html?tdsourcetag=s_pcqq_aiomsg  )。 本次评测通过这款经典arduino电机驱动板的试用,展现多种控制方式效果。 2、产品概述 2.1 Arduino四路电机驱动板是DFRobot推出四路直流电机驱动扩展板,兼容5V/3.3V Arduino主控器,具有4个电机双路输出控制,共8个管脚,既可以同时控制四个直流电机,支持PWM调速和正反转控制。主要技术参数为, VM电机供电:2.5V-13.5V VCC逻辑供电:2.7~5.5V 输出电流:1.2A 单通道连续驱动电流 启动/峰值电流:2A(连续脉冲)/ 3.2A(单脉冲) Arduino控制端口:数字口3,4,5,6,7,8,11,12 2.2 驱动板核心是两块TB6612FNG电机驱动芯片,是传统L298N的升级版本,最高可输出1.2A持续电流,并且内置低压检测电路与热停机保护电路,安全可靠。数据输出采用Arduino接口的控制,根据控制输出对应的四对输出口为3-4,11-12,5-8,6-7。分别对应4个接口对,控制直流电机。 TB6612FNG是东芝公司的直流电机驱动模块,最高工作电压15V,逻辑图如下, 典型应用如下, 核心的工作原理是一个H桥, 最大的PWM频率是100kHz,超过这个范围就会发热增大,烧掉片子。 2.3 典型的应用需要参考下面的配置图。 3 后面的测试,试用Arduino测试,不过,使用的是Nucleo-STM32L496RG开发板。 3.1 电机扩展板 3.2 和Nucleo开发板连接在一起如下, 此内容由EEWORLD论坛网友北方原创,如需转载或用于商业用途需征得作者同意并注明出处

  • 2019-09-24
  • 回复了主题帖: 【入选名单公布】DFRobot Arduino四路电机驱动板测评

    确认信息。信息。

  • 2019-09-11
  • 回复了主题帖: 有奖话题#三人行必有我师#,说一说,那些在论坛生活中给予你指导,给予你帮助的网...

    @dcexpert,@okhxyyo,@soso 以及各位版主,祝大家节日快乐。 谢谢这些网友的帮助。

  • 2019-09-06
  • 回复了主题帖: 获奖名单:直播|贝能国际新型玻璃破碎检测方案

    确认个人信息无误。 如果可以,换E金币吧,谢谢。

  • 2019-08-15
  • 回复了主题帖: 《Python编程:从入门到实践》

    zan

  • 2019-08-14
  • 回复了主题帖: 获奖名单|TTI 和 Molex 直播【更小型、高速、可靠的连接器推动物联网应用的新发展】

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

  • 2019-08-12
  • 发表了主题帖: 【DFRobot无线通信模块】+ DFRobot Gravity: UART A6 GSM & GPRS 无线通信模块评测

    1 DFRobot Gravity: UART A6 GSM & GPRS 无线通信模块是一个非常精巧的扩展板,主要是基于GSM无线通信模块的快速开发. 2. 这个模块是安可信A9,和A9G兼容管脚的开发板,对于开发板的连接和控制是用UART串行接口实现的.    具体的参数参照WIKI,这里展示了具体的使用方法. 3. 按照手册上的使用方法连接arduino开发板的11和10引脚,使用9600的波特率连接,下载如下测试程序.   #include <SoftwareSerial.h> SoftwareSerial mySerial(11, 10); // TX-Pin11, RX-Pin10 void updateSerial() { delay(2000); while (Serial.available()) { mySerial.write(Serial.read());//如果Serial收到数据则通过mySerial输出 } while(mySerial.available()) { Serial.write(mySerial.read());//如果mySerial收到数据则通过Serial输出 } } void setup() { Serial.begin(9600); mySerial.begin(9600); } void loop() { mySerial.println("AT"); //握手测试,成功则返回OK updateSerial(); mySerial.println("AT+CSQ"); //信号质量测试,值为0-31,31表示最好 updateSerial(); mySerial.println("AT+CCID"); //读取SIM,可以检测是否有SIM卡或者是否接触良好 updateSerial(); mySerial.println("AT+CREG?"); //检测是否注册网络 updateSerial(); mySerial.println("AT+SNFS=0"); //调整为耳机模式(AT+SNFS=1 表示扬声器模式) updateSerial(); mySerial.println("AT+CRSL=2"); //调整音量,值为0-15,15表示音量最大 updateSerial(); while(1) { if(mySerial.available()) { Serial.write(mySerial.read());//如果mySerial收到数据则通过Serial输出 } if(Serial.available()) { mySerial.write(Serial.read());//如果Serial收到数据则通过mySerial输出 } } } 连接图片 4. 上电后,GSM模块启动,间断蓝灯闪烁,应该是模块正常工作的状态,不过在串口没有反馈信号. 经过测试,应该是波特率配置不成功. 需要进一步调试. 需要注意的是这个模块只能用5V电压驱动,在3.3V的时候,模块供电不足,不能正常启动.蓝色LED灯也不闪烁. 按照A9的手册,这个波特率是采用自协调和同步的方式,出现这样子,还是需要重新分析. 出厂的标准波特率其实是115200,不过配合arduino的正常读取,用9600也应该是可以的. 此内容由EEWORLD论坛网友北方原创,如需转载或用于商业用途需征得作者同意并注明出处

  • 回复了主题帖: 不小心把lis25ba的一个焊盘弄掉了,飞了一根线

    qwqwqw2088 发表于 2019-8-12 10:14 烙铁不能停留时间太长,温度要适当的高些
    焊接OK,但是实在要很使用要很温柔才行  

  • 回复了主题帖: 不小心把lis25ba的一个焊盘弄掉了,飞了一根线

    littleshrimp 发表于 2019-8-10 07:30 你准备使用什么单片机?可以把单片机电压降下来试试,或者使用IKS01A3板子上的电压转换芯片,在DIL24 Sock ...
    我也把这个板子的Vcc给弄掉了。没法再弄下去了。 因为焊接的过程很正常,但是使用的过程中不知什么时候就掉了。 研究后发现,焊盘接触时间过长,然后引脚稍微受力大一些就game over了。 没有找到好的解决办法前不敢再测试了。焊盘其实只有一层铜箔。

  • 2019-07-24
  • 发表了主题帖: 【沁恒试用】 使用触摸按键和GPIO完成拨号和挂断的功能 #3

    本帖最后由 北方 于 2019-7-24 16:47 编辑 1、经过对基本功能的测试,进入了触摸手机的软件开发工作 2、首先选择CH549L的使用的引脚 参照下图, 对照扩展引脚的接口, CH549 16通道触摸按键对用通道和引用,目前把CH4~CH7预留,直接跳到CH12~CH15,板载 *                      CH0~CH15 分别对应引脚 P1.0~P1.7  P0.0~P0.7         其中 硬件SPI接口预留          CH549          P1.4        =       SCS          P1.5        =       MOSI          P1.6        =       MISO          P1.7        =       SCK 引用GPIO点亮LED灯,板载LED为P22~P25 *                         LED 输出接口                          LED 0~12 分别对应引脚 P2.0~P2.7 P4.2~P4.5    *                         UART0 接口预留                         P3.0 = RXD                           P3.1 = TXD   3. 代码说明如下 3.1 程序初始化后,扫描ADC口,读取touch的按键,对照用LED显示按键的位置 其中使用chneo变量来确定1-12个按键和对应的LED灯。 3.2 然后读取最后按下的按键,以离开为准,用switch~case来给uart0输出AT命令,按键11用ATD+号码拨出电话号码,用12号按键挂掉电话,用ATH命令。 3.3 在确定了按键读取后,就可以使用更丰富的按键组合来实现按键和电话拨打功能。   3.4 代码如下: #include ".\Public\CH549.H" #include ".\Public\DEBUG.H" #include ".\TouchKey\TouchKey.H" #include ".\SPI\SPI.H" #pragma NOAREGS #define COLORED 0 #define UNCOLORED 1 UINT16 PowerValue[16]; UINT8 PressedKey; //保存触摸按键上电未触摸值 volatile UINT16 Press_Flag = 0; //按下标志位 UINT8C CPW_Table[16] = { 30,30,30,30, 30,30,30,30, //与板间电容有关的参数,分别对应每个按键 30,30,30,30, 30,30,30,30, }; /******************************************************************************* * Function Name : ABS * Description : 求两个数差值的绝对值 * Input : a,b * Output : None * Return : 差值绝对值 *******************************************************************************/ UINT16 ABS(UINT16 a,UINT16 b) { if(a>b) { return (a-b); } else { return (b-a); } } /******************************************************************************* * Function Name : LED_Port_Init * Description : LED引脚初始化,推挽输出 * P22~P25 * Input : None * Output : None * Return : None *******************************************************************************/ void LED_Port_Init(void) { P2 |= (0xFF); //默认熄灭 P2_MOD_OC &= ~(0xFF); P2_DIR_PU |= (0xFF); P4 |= (0xF<<2); //默认熄灭 P4_MOD_OC &= ~(0xF<<2); P4_DIR_PU |= (0xF<<2); } /******************************************************************************* * Function Name : LED_Control * Description : 点灯控制 * Input : LEDx: 0~3 分别对应P22~P25四个LED灯(低驱) // Revised. * status: 0:灭 1:亮 * Output : None * Return : None *******************************************************************************/ void LED_Control(UINT8 LEDx,UINT8 status) { if(LEDx>=8) { LEDx = LEDx - 8; if(status) //点亮 { P4 &= ~(1<<(2+LEDx)); } else //熄灭 { P4 |= (1<<(2+LEDx)); } return; } if(LEDx>=0) // (LEDx<8) { if(status) //点亮 { P2 &= ~(1<<(LEDx)); } else //熄灭 { P2 |= (1<<(LEDx)); } return; } } //主函数 void main() { UINT8 ch; UINT8 chneo; UINT16 value; UINT16 err; UINT16 i=0; //触摸模拟变化差值 CfgFsys( ); //CH549时钟选择配置 mDelaymS(20); mInitSTDIO( ); //串口0初始化 //printf("BitPhone start ...\n"); LED_Port_Init(); TouchKey_Init(); Press_Flag = 0; //无按键按下 /* 获取按键初值 */ for(chneo = 1; chneo!=12; chneo++) { if(chneo>4) { ch = chneo + 4; } if(chneo<=4) { ch = chneo; } PowerValue[ch] = TouchKeySelect( ch,CPW_Table[ch] ); //printf("%d ",PowerValue[ch] ); } printf("\n"); //SPI setting //SPIMasterModeSet(3); //SPI_CK_SET(12); //SCS = 0; //SPI主机发送数据 //CH549SPIMasterWrite(i); //mDelaymS(5); while(1) { //CH549SPIMasterWrite(i); mDelaymS(5); /* 按键检测 */ for(chneo = 1; chneo!=12; chneo++) { if(chneo>4) { ch = chneo + 4; } if(chneo<=4) { ch = chneo; } value = TouchKeySelect( ch,CPW_Table[ch] ); err = ABS(PowerValue[ch],value); if( err > DOWM_THRESHOLD_VALUE ) //差值大于阈值,认为按下 { if((Press_Flag & (1<<ch)) == 0) //说明是第一次按下 { //printf("ch %d pressed,value:%d\n",(UINT16)ch, value); /* 点灯处理 */ LED_Control(chneo,1); //LED_Control(chneo-6,1); } Press_Flag |= (1<<ch); } else if( err < UP_THRESHOLD_VALUE ) //说明抬起或者未按下 { if(Press_Flag & (1<<ch)) //刚抬起 { Press_Flag &= ~(1<<ch); //printf("ch %d up,value:%d\n",(UINT16)ch, value); /* 灭灯处理 */ LED_Control(chneo,0); //LED_Control(chneo-6,0); PressedKey= chneo; } } } switch (PressedKey) { case 1: PressedKey=0; printf("0"); break; case 2: PressedKey=0; printf("1"); break; case 3: PressedKey=0; printf("2"); break; case 4: PressedKey=0; printf("3"); break; case 5: PressedKey=0; printf("4"); break; case 6: PressedKey=0; printf("5"); break; case 7: PressedKey=0; printf("6"); break; case 8: PressedKey=0; printf("7"); break; case 9: PressedKey=0; printf("8"); break; case 10: PressedKey=0; printf("9"); break; case 11: //Call PressedKey=0; printf("ATD"); break; case 12: PressedKey=0; printf("\n"); break; case 0: // Hand Off PressedKey=0; printf("ATH"); break; } } } 4. 最后编译的结果有20个警告,是定义了变量空间没有访问,需要后续优化。 总共24+2个引脚被定义和使用,占了44个引脚的60%,仍然有扩展功能的空间,所有CH549L具有足够丰富的功能。 编译的二进制文档如下: 此内容由EEWORLD论坛网友北方原创,如需转载或用于商业用途需征得作者同意并注明出处

  • 2019-07-22
  • 发表了主题帖: 【沁恒试用】增加SPI的引用 #2

    1、在完成基本框架构成设计之后,逐步增加系统增加系统资源的调用,这次增加SPI。 2、SPI需要4个引脚,这里使用的是SPI0,占用了          CH549          P1.4        =       SCS          P1.5        =       MOSI          P1.6        =       MISO          P1.7        =       SCK 3、软件调用前需要引用spi.h头文件,并加载spi.c这样就可以调用spi,使用起来就很简单。 程序启动设定spi,     SPIMasterModeSet(3);      SPI_CK_SET(12); 然后直接加载 SCS = 0;                                                               //SPI主机发送数据     CH549SPIMasterWrite(i);  就可以写入SPI数据了。 4、代码扩展如下。 #include ".\Public\CH549.H" #include ".\Public\DEBUG.H" #include ".\TouchKey\TouchKey.H" #include ".\SPI\SPI.H" /****************************************************************************** 使用CH549 硬件SPI接口 CH549 P1.4 = SCS P1.5 = MOSI P1.6 = MISO P1.7 = SCK *******************************************************************************/ #pragma NOAREGS UINT16 PowerValue[16]; //保存触摸按键上电未触摸值 volatile UINT16 Press_Flag = 0; //按下标志位 UINT8C CPW_Table[16] = { 30,30,30,30, 30,30,30,30, //与板间电容有关的参数,分别对应每个按键 30,30,30,30, 30,30,30,30, }; UINT16 ABS(UINT16 a,UINT16 b) { if(a>b) { return (a-b); } else { return (b-a); } } void LED_Port_Init(void) { P2 |= (0xF<<2); //默认熄灭 P2_MOD_OC &= ~(0xF<<2); P2_DIR_PU |= (0xF<<2); } void LED_Control(UINT8 LEDx,UINT8 status) { if(LEDx>3) { return; } if(status) //点亮 { P2 &= ~(1<<(2+LEDx)); } else //熄灭 { P2 |= (1<<(2+LEDx)); } } //主函数 void main() { UINT8 ch; UINT16 value; UINT16 err; UINT16 i=0; //触摸模拟变化差值 CfgFsys( ); //CH549时钟选择配置 mDelaymS(20); mInitSTDIO( ); //串口0初始化 printf("TouchKey demo start ...\n"); LED_Port_Init(); TouchKey_Init(); Press_Flag = 0; //无按键按下 /* 获取按键初值 */ for(ch = 8; ch!=12; ch++) { PowerValue[ch] = TouchKeySelect( ch,CPW_Table[ch] ); printf("%d ",PowerValue[ch] ); } printf("\n"); //SPI setting SPIMasterModeSet(3); SPI_CK_SET(12); SCS = 0; //SPI主机发送数据 CH549SPIMasterWrite(i); mDelaymS(5); while(1) { CH549SPIMasterWrite(i); mDelaymS(5); } } 此内容由EEWORLD论坛网友北方原创,如需转载或用于商业用途需征得作者同意并注明出处

  • 2019-07-17
  • 发表了主题帖: 3、基于Nucleo-L476L的健康运动助手项目开发

    本帖最后由 北方 于 2019-7-17 16:57 编辑 1、简述-基于Nucleo-L476L的健康运动助手    基于Nucleo-L476L的健康运动助手是一个基于STM32L476L的便携运动健康电子助手的原型设计。实现以下功能:    启动后不读取传感器数据,降低功耗。当检测到运动数据后,启动计步器,开始计算运动步数,同时读取运动环境的温度和湿度,同时读取大气压,折算运动位置的海拔。在中止运动一段时间后,停止计数,并输出运动量。   2、采用的硬件     采用Nucleo-STM32L476和X-NUCLEO-IKS01A3。其中应用到的四种传感器有: LSM6DSO 用于计步器计数, LIS2DW12 用于从休眠中唤醒,进入传感器读取和计步器计数 LPS22HH   用于读取大气压数据 STTS751   用于读取环境温度   3、开发环境和工具 3.1 开发环境使用Arduino1.8.9 3.2 开发需要先安装以上4种传感器的arduino驱动程序,然后直接在程序中引用库就可以了。   4、实现代码 这个代码使用了2个标志位mems_event = 0 和 ped_event=0,分别启动中断,上升沿启动内部置位的变化。 同时设定了一个IDLEPERIOD,演示设置位10000ms,即10秒,之后就退出计数。   /** ****************************************************************************** * @brief Arduino test application for the STMicrolectronics X-NUCLEO-IKS01A3 ****************************************************************************** */ // Includes #include <LSM6DSOSensor.h> #include <LIS2DW12Sensor.h> #include <LPS22HHSensor.h> #include <STTS751Sensor.h> #ifdef ARDUINO_SAM_DUE #define DEV_I2C Wire1 #elif defined(ARDUINO_ARCH_STM32) #define DEV_I2C Wire #elif defined(ARDUINO_ARCH_AVR) #define DEV_I2C Wire #else #define DEV_I2C Wire #endif #define SerialPort Serial #define INT_1 4 #define IDLEPERIOD 10000 // Components LSM6DSOSensor *AccGyr; LIS2DW12Sensor *Acc2; LPS22HHSensor *Press; STTS751Sensor *Temp; //Interrupts. volatile int mems_event = 0; volatile int ped_event = 0; uint16_t step_count = 0; char report[256]; uint32_t previous_tick; void INT0Event_cb(); void INT1Event_cb(); void runningmode(); void setup() { // Led. pinMode(LED_BUILTIN, OUTPUT); // Initialize serial for output. SerialPort.begin(115200); // Initialize I2C bus. DEV_I2C.begin(); //Interrupts. attachInterrupt(A3, INT0Event_cb, RISING); attachInterrupt(INT_1, INT1Event_cb, RISING); //1. Using LSM6DSOSensor for Pedometer AccGyr = new LSM6DSOSensor (&DEV_I2C); AccGyr->Enable_X(); AccGyr->Enable_G(); AccGyr->Enable_Pedometer(); previous_tick = millis(); //2. Using LIS2DW12Sensor for wakeup detection Acc2 = new LIS2DW12Sensor (&DEV_I2C); Acc2->Enable_X(); Acc2->Enable_Wake_Up_Detection(); //3. Using LPS22HHSensor Press = new LPS22HHSensor(&DEV_I2C); Press->Enable(); //4. Using STTS751Sensor Temp = new STTS751Sensor (&DEV_I2C); Temp->Enable(); } void loop() { if (mems_event) { mems_event=0; LIS2DW12_Event_Status_t status; Acc2->Get_Event_Status(&status); if (status.WakeUpStatus) { // Output data. SerialPort.println("Wake up Detected!"); runningmode(); } } } void runningmode() { bool idel=1; while (idel){ if (ped_event) { ped_event=0; LSM6DSO_Event_Status_t status; AccGyr->Get_X_Event_Status(&status); if (status.StepStatus) { // New step detected, so print the step counter AccGyr->Get_Step_Count(&step_count); //snprintf(report, sizeof(report), "Step counter: %d", step_count); //SerialPort.println(report); } } // Print the step counter in any case every 3000 ms uint32_t current_tick = millis(); if((current_tick - previous_tick) >= IDLEPERIOD) { AccGyr->Get_Step_Count(&step_count); snprintf(report, sizeof(report), "Step counter: %d", step_count); SerialPort.println(report); previous_tick = millis(); // Read pressure and temperature. float pressure = 0, temperature2 = 0; Press->GetPressure(&pressure); //Read temperature float temperature = 0; Temp->GetTemperature(&temperature); SerialPort.print("| Pres[hPa]: "); SerialPort.print(pressure, 2); SerialPort.print(" | Temp[C]: "); SerialPort.print(temperature, 2); SerialPort.print("\n "); // Quit the while loop, idel=0; } } } void INT1Event_cb() { ped_event = 1; } void INT0Event_cb() { mems_event = 1; } 5、结果演示 5.1 初步显示计步器功能 5.2 综合计步器和环境温度和气压显示功能 显示唤醒后,开始计算运动步数,这里用手的摇动来显示结果,同时显示出环境温度和大气压。   6. 基于Nucleo-L476L的传感器数据读取的几点说明和建议 演示视频: 此内容由EEWORLD论坛网友北方原创,如需转载或用于商业用途需征得作者同意并注明出处

  • 2019-07-16
  • 发表了主题帖: 2、基于Nucleo-L476L的全部传感器数据读取和演示

    本帖最后由 北方 于 2019-7-16 15:52 编辑 1、基于Nucleo-L476L的全部传感器数据读取和演示主要是演示评测计划中全部传感器数据的读取和输出。 根据分析传感器的数据表,可以看出,这些传感器全部是 通过I2C总线读取和访问的。每个传感器具有一个唯一的地址码,再I2C读取的时候,指定地址码就可以唯一的访问这个传感器。传感器的地址码再开发板的反面完整地列出,详见上一帖的照片。 再这样的情况下,对于传感器数据的读取就变为对I2C的访问和读取,这样简化了设计,而且具有快速移植的特点。 2、开发环境和IDE 2.1 原计划中采用的arduino平台是一个快速开发和评测的工具,但是代码编译同样具有高效特点,因为,调用的编译器是GCC。对于代码的效率,重要的是代码逻辑的优化,那么同样具有复杂程序开发的能力。编译的hex可执行文件,可以直接写入flash,即使是工业化开发也没有问题。 2.2 再完成了arduino平台的开发后,其实同样的开发板移植到mbed平台也是非常迅速的,可以发现,很多代码都可以直接使用,适当调整一下格式就可以了。但是因为本次活动的先发先评的积分规则,如果同时进行评测mbed的平台会影响其他评测的计分,毕竟还有没有收到快递的。 2.3 使用Arduino-uno和使用Nucleo-Arduino开发的最大区别是标准arduino使用原生I2C库wire.h,使用更简单。而Nucleo-arduino重写了I2C的驱动,使用的是TwoWire类,用一个指针传递DEVICE_I2C,这样和STM的HAL等开发库的代码保持一致。所以,如果使用arduino-uno等均需要再wire部分进行调整。 3. 综合全部传感器数据读取的程序helloworld代码如下。因为是arduino代码,所以非常直观。 // Includes #include <LSM6DSOSensor.h> #include <LIS2DW12Sensor.h> #include <LIS2MDLSensor.h> #include <LPS22HHSensor.h> #include <STTS751Sensor.h> #include <HTS221Sensor.h> #ifdef ARDUINO_SAM_DUE #define DEV_I2C Wire1 #elif defined(ARDUINO_ARCH_STM32) #define DEV_I2C Wire #elif defined(ARDUINO_ARCH_AVR) #define DEV_I2C Wire #else #define DEV_I2C Wire #endif #define SerialPort Serial // Components LSM6DSOSensor *AccGyr; LIS2DW12Sensor *Acc2; LIS2MDLSensor *Mag; LPS22HHSensor *PressTemp; HTS221Sensor *HumTemp; STTS751Sensor *Temp3; void setup() { // Led. pinMode(LED_BUILTIN, OUTPUT); // Initialize serial for output. SerialPort.begin(115200); // Initialize I2C bus. DEV_I2C.begin(); AccGyr = new LSM6DSOSensor (&DEV_I2C); AccGyr->Enable_X(); AccGyr->Enable_G(); Acc2 = new LIS2DW12Sensor (&DEV_I2C); Acc2->Enable_X(); Mag = new LIS2MDLSensor (&DEV_I2C); Mag->Enable(); PressTemp = new LPS22HHSensor(&DEV_I2C); PressTemp->Enable(); HumTemp = new HTS221Sensor (&DEV_I2C); HumTemp->Enable(); Temp3 = new STTS751Sensor (&DEV_I2C); Temp3->Enable(); } void loop() { // Led blinking. digitalWrite(LED_BUILTIN, HIGH); delay(250); digitalWrite(LED_BUILTIN, LOW); delay(250); // Read humidity and temperature. float humidity = 0, temperature = 0; HumTemp->GetHumidity(&humidity); HumTemp->GetTemperature(&temperature); // Read pressure and temperature. float pressure = 0, temperature2 = 0; PressTemp->GetPressure(&pressure); PressTemp->GetTemperature(&temperature2); //Read temperature float temperature3 = 0; Temp3->GetTemperature(&temperature3); // Read accelerometer and gyroscope. int32_t accelerometer[3]; int32_t gyroscope[3]; memset(accelerometer, 0, 3); memset(gyroscope, 0, 3); AccGyr->Get_X_Axes(accelerometer); AccGyr->Get_G_Axes(gyroscope); //Read accelerometer int32_t accelerometer2[3]; memset(accelerometer2, 0, 3); Acc2->Get_X_Axes(accelerometer2); //Read magnetometer int32_t magnetometer[3]; memset(magnetometer, 0, 3); Mag->GetAxes(magnetometer); // Output data. SerialPort.print("| Hum[%]: "); SerialPort.print(humidity, 2); SerialPort.print(" | Temp[C]: "); SerialPort.print(temperature, 2); SerialPort.print(" | Pres[hPa]: "); SerialPort.print(pressure, 2); SerialPort.print(" | Temp2[C]: "); SerialPort.print(temperature2, 2); SerialPort.print(" | Temp3[C]: "); SerialPort.print(temperature3, 2); SerialPort.print(" | Acc[mg]: "); SerialPort.print(accelerometer[0]); SerialPort.print(" "); SerialPort.print(accelerometer[1]); SerialPort.print(" "); SerialPort.print(accelerometer[2]); SerialPort.print(" | Gyr[mdps]: "); SerialPort.print(gyroscope[0]); SerialPort.print(" "); SerialPort.print(gyroscope[1]); SerialPort.print(" "); SerialPort.print(gyroscope[2]); SerialPort.print(" | Acc2[mg]: "); SerialPort.print(accelerometer2[0]); SerialPort.print(" "); SerialPort.print(accelerometer2[1]); SerialPort.print(" "); SerialPort.print(accelerometer2[2]); SerialPort.print(" | Mag[mGauss]: "); SerialPort.print(magnetometer[0]); SerialPort.print(" "); SerialPort.print(magnetometer[1]); SerialPort.print(" "); SerialPort.print(magnetometer[2]); SerialPort.println(" |"); } 程序编译并上传到开发板,占用了38.180k内存(3%代码空间) 同时串口输出了全部的传感器数据,如下 4、演示视频 这个视频中,显示了变化的传感器数据读数,其中在转动和冲击时,x-y-z传感器和加速度传感器的数据都在实时地变化。 5、第一步基本数据读取和显示的评测任务完成。包括了以下的全部传感器。后续在一个演示程序中使用。 LSM6DSOSensor ; LIS2DW12Sensor ; LIS2MDLSensor ; LPS22HHSensor ; HTS221Sensor ; STTS751Sensor ; 参考的流程包括以下步骤, 导入传感器驱动, #include <LSM6DSOSensor.h> #include <LIS2DW12Sensor.h> #include <LIS2MDLSensor.h> #include <LPS22HHSensor.h> #include <STTS751Sensor.h> #include <HTS221Sensor.h>   创建传感器实例 LSM6DSOSensor *AccGyr; LIS2DW12Sensor *Acc2; LIS2MDLSensor *Mag; LPS22HHSensor *PressTemp; HTS221Sensor *HumTemp; STTS751Sensor *Temp3; // new instance   AccGyr = new LSM6DSOSensor (&DEV_I2C);   AccGyr->Enable_X();   AccGyr->Enable_G();   Acc2 = new LIS2DW12Sensor (&DEV_I2C);   Acc2->Enable_X();   Mag = new LIS2MDLSensor (&DEV_I2C);   Mag->Enable();   PressTemp = new LPS22HHSensor(&DEV_I2C);   PressTemp->Enable();   HumTemp = new HTS221Sensor (&DEV_I2C);   HumTemp->Enable();   Temp3 = new STTS751Sensor (&DEV_I2C);   Temp3->Enable(); 初始化I2C端口 #define DEV_I2C Wire   DEV_I2C.begin(); 逐个读取传感器数据并用串口以115200的波特率输出 float humidity = 0, temperature = 0;   HumTemp->GetHumidity(&humidity);   HumTemp->GetTemperature(&temperature);   // Read pressure and temperature.   float pressure = 0, temperature2 = 0;   PressTemp->GetPressure(&pressure);   PressTemp->GetTemperature(&temperature2);   //Read temperature   float temperature3 = 0;   Temp3->GetTemperature(&temperature3);   // Read accelerometer and gyroscope.   int32_t accelerometer[3];   int32_t gyroscope[3];   memset(accelerometer, 0, 3);   memset(gyroscope, 0, 3);   AccGyr->Get_X_Axes(accelerometer);   AccGyr->Get_G_Axes(gyroscope);   //Read accelerometer   int32_t accelerometer2[3];   memset(accelerometer2, 0, 3);   Acc2->Get_X_Axes(accelerometer2);   //Read magnetometer   int32_t magnetometer[3];   memset(magnetometer, 0, 3);   Mag->GetAxes(magnetometer);   此内容由EEWORLD论坛网友北方原创,如需转载或用于商业用途需征得作者同意并注明出处

  • 2019-07-15
  • 发表了主题帖: 1、基于Nucleo-L476L的HTS221等全部传感器的驱动

    本帖最后由 北方 于 2019-7-16 14:51 编辑 1、基于Nucleo-STM32L476L的Arduino实现NUCLEO-IKS01A3的全部传感器驱动实现。     初始计划是采用MKR1000,但是在使用和下载的过程中,这个开发板给变砖了。 所以只好先拿出吃灰的Nucleo-STM32L476L先实现以下基本的arduino驱动。在完成这个基本评测后再移植到其他arduino开发板上使用。 针对不同的传感器,参照以下具体代码逐个说明和实现。       这个过程中首先需要使用开发板管理器安装arduino开发板, 这样就可以设置开发板了, 然后安装NUCLEO-IKS01A3的传感器驱动, 这样就可以再程序中直接使用驱动库了。 驱动和安装说明可以从如下链接获得,https://github.com/stm32duino/Arduino_Core_STM32 这个是官方的arduino驱动。 2、传感器驱动代码和说明 2.1 首先导入HTS221Sensor.h,这个是HTS221的驱动,设定I2C的引脚后就可以直接访问HTS221传感器,程序读取传感器的数据,转换后通过串口输出。 代码如下: #include <HTS221Sensor.h> #define I2C2_SCL PB10 #define I2C2_SDA PB11 // Components. HTS221Sensor *HumTemp; TwoWire *dev_i2c; void setup() { // Led. pinMode(LED_BUILTIN, OUTPUT); // Initialize serial for output. Serial.begin(9600); // Initialize I2C bus. dev_i2c = new TwoWire(I2C2_SDA, I2C2_SCL); dev_i2c->begin(); // Initlialize components. HumTemp = new HTS221Sensor (dev_i2c); HumTemp->Enable(); } void loop() { // Led blinking. digitalWrite(LED_BUILTIN, HIGH); delay(250); digitalWrite(LED_BUILTIN, LOW); delay(250); // Read humidity and temperature. float humidity, temperature; HumTemp->GetHumidity(&humidity); HumTemp->GetTemperature(&temperature); // Output data. Serial.print("Hum[%]: "); Serial.print(humidity, 2); Serial.print(" | Temp[C]: "); Serial.println(temperature, 2); } 输出结果如下, 因为本传感器只检查温度和湿度,所以使用照片显示结果,   2.2  3D加速度+3D陀螺仪    LSM6DS +Nucleo-STM32L476L读取传感器数据 首先导入驱动程序 #include <LSM6DSOSensor.h> 同上,先设定I2C的接口,然后把变化传感器数据输出到串口 代码如下: #include <LSM6DSOSensor.h> #ifdef ARDUINO_SAM_DUE #define DEV_I2C Wire1 #elif defined(ARDUINO_ARCH_STM32) #define DEV_I2C Wire #elif defined(ARDUINO_ARCH_AVR) #define DEV_I2C Wire #else #define DEV_I2C Wire #endif #define SerialPort Serial #define INT_1 4 LSM6DSOSensor *accGyr; //Interrupts. volatile int mems_event = 0; char report[256]; void INT1Event_cb(); void sendOrientation(); void setup() { // Led. pinMode(LED_BUILTIN, OUTPUT); // Initialize serial for output. SerialPort.begin(115200); // Initialize I2C bus. DEV_I2C.begin(); //Interrupts. attachInterrupt(INT_1, INT1Event_cb, RISING); accGyr = new LSM6DSOSensor (&DEV_I2C); accGyr->Enable_X(); accGyr->Enable_6D_Orientation(LSM6DSO_INT1_PIN); } void loop() { if (mems_event) { mems_event=0; LSM6DSO_Event_Status_t status; accGyr->Get_X_Event_Status(&status); if (status.D6DOrientationStatus) { sendOrientation(); // Led blinking. digitalWrite(LED_BUILTIN, HIGH); delay(100); digitalWrite(LED_BUILTIN, LOW); } } } void INT1Event_cb() { mems_event = 1; } void sendOrientation() { uint8_t xl = 0; uint8_t xh = 0; uint8_t yl = 0; uint8_t yh = 0; uint8_t zl = 0; uint8_t zh = 0; accGyr->Get_6D_Orientation_XL(&xl); accGyr->Get_6D_Orientation_XH(&xh); accGyr->Get_6D_Orientation_YL(&yl); accGyr->Get_6D_Orientation_YH(&yh); accGyr->Get_6D_Orientation_ZL(&zl); accGyr->Get_6D_Orientation_ZH(&zh); if ( xl == 0 && yl == 0 && zl == 0 && xh == 0 && yh == 1 && zh == 0 ) { sprintf( report, "\r\n ________________ " \ "\r\n | | " \ "\r\n | * | " \ "\r\n | | " \ "\r\n | | " \ "\r\n | | " \ "\r\n | | " \ "\r\n |________________| \r\n" ); } else if ( xl == 1 && yl == 0 && zl == 0 && xh == 0 && yh == 0 && zh == 0 ) { sprintf( report, "\r\n ________________ " \ "\r\n | | " \ "\r\n | * | " \ "\r\n | | " \ "\r\n | | " \ "\r\n | | " \ "\r\n | | " \ "\r\n |________________| \r\n" ); } else if ( xl == 0 && yl == 0 && zl == 0 && xh == 1 && yh == 0 && zh == 0 ) { sprintf( report, "\r\n ________________ " \ "\r\n | | " \ "\r\n | | " \ "\r\n | | " \ "\r\n | | " \ "\r\n | | " \ "\r\n | * | " \ "\r\n |________________| \r\n" ); } else if ( xl == 0 && yl == 1 && zl == 0 && xh == 0 && yh == 0 && zh == 0 ) { sprintf( report, "\r\n ________________ " \ "\r\n | | " \ "\r\n | | " \ "\r\n | | " \ "\r\n | | " \ "\r\n | | " \ "\r\n | * | " \ "\r\n |________________| \r\n" ); } else if ( xl == 0 && yl == 0 && zl == 0 && xh == 0 && yh == 0 && zh == 1 ) { sprintf( report, "\r\n __*_____________ " \ "\r\n |________________| \r\n" ); } else if ( xl == 0 && yl == 0 && zl == 1 && xh == 0 && yh == 0 && zh == 0 ) { sprintf( report, "\r\n ________________ " \ "\r\n |________________| " \ "\r\n * \r\n" ); } else { sprintf( report, "None of the 6D orientation axes is set in LSM6DSO - accelerometer.\r\n" ); } SerialPort.print(report); } 通过串口演示读取加速度计的变化位置, 主要代码 sprintf( report, "\r\n ________________ " \ "\r\n |________________| " \ "\r\n * \r\n" ); 2.3 3D磁力计    LIS2MD + Nucleo-STM32L476L 读取传感器数据 首先导入驱动程序 #include <LIS2DW12Sensor.h> 同上,先设定I2C的接口,然后把变化传感器数据输出到串口 代码类似上面,具体读取再后面的综合数据输出中展示。 2.4 3D加速度    LIS2DW12+Nucleo-STM32L476L 读取传感器数据 首先导入驱动程序 同上,先设定I2C的接口,然后把变化传感器数据输出到串口 代码如下: #include <LIS2DW12Sensor.h> #ifdef ARDUINO_SAM_DUE #define DEV_I2C Wire1 #elif defined(ARDUINO_ARCH_STM32) #define DEV_I2C Wire #elif defined(ARDUINO_ARCH_AVR) #define DEV_I2C Wire #else #define DEV_I2C Wire #endif #define SerialPort Serial // Components. LIS2DW12Sensor *accelero; //Interrupts. volatile int mems_event = 0; char report[256]; void INT1Event_cb(); void sendOrientation(); void setup() { // Led. pinMode(LED_BUILTIN, OUTPUT); // Initialize serial for output. SerialPort.begin(115200); // Initialize I2C bus. DEV_I2C.begin(); //Interrupts. attachInterrupt(A3, INT1Event_cb, RISING); // Initlialize components. accelero = new LIS2DW12Sensor(&DEV_I2C); accelero->Enable_X(); // Enable 6D Orientation. accelero->Enable_6D_Orientation(); } void loop() { if (mems_event) { mems_event = 0; LIS2DW12_Event_Status_t status; accelero->Get_Event_Status(&status); if (status.D6DOrientationStatus) { // Send 6D Orientation sendOrientation(); // Led blinking. digitalWrite(LED_BUILTIN, HIGH); delay(100); digitalWrite(LED_BUILTIN, LOW); } } } void INT1Event_cb() { mems_event = 1; } void sendOrientation() { uint8_t xl = 0; uint8_t xh = 0; uint8_t yl = 0; uint8_t yh = 0; uint8_t zl = 0; uint8_t zh = 0; accelero->Get_6D_Orientation_XL(&xl); accelero->Get_6D_Orientation_XH(&xh); accelero->Get_6D_Orientation_YL(&yl); accelero->Get_6D_Orientation_YH(&yh); accelero->Get_6D_Orientation_ZL(&zl); accelero->Get_6D_Orientation_ZH(&zh); if ( xl == 1 && yl == 0 && zl == 0 && xh == 0 && yh == 0 && zh == 0 ) { sprintf( report, "\r\n ________________ " \ "\r\n | | " \ "\r\n | * | " \ "\r\n | | " \ "\r\n | | " \ "\r\n | | " \ "\r\n | | " \ "\r\n |________________| \r\n" ); } else if ( xl == 0 && yl == 1 && zl == 0 && xh == 0 && yh == 0 && zh == 0 ) { sprintf( report, "\r\n ________________ " \ "\r\n | | " \ "\r\n | * | " \ "\r\n | | " \ "\r\n | | " \ "\r\n | | " \ "\r\n | | " \ "\r\n |________________| \r\n" ); } else if ( xl == 0 && yl == 0 && zl == 0 && xh == 0 && yh == 1 && zh == 0 ) { sprintf( report, "\r\n ________________ " \ "\r\n | | " \ "\r\n | | " \ "\r\n | | " \ "\r\n | | " \ "\r\n | | " \ "\r\n | * | " \ "\r\n |________________| \r\n" ); } else if ( xl == 0 && yl == 0 && zl == 0 && xh == 1 && yh == 0 && zh == 0 ) { sprintf( report, "\r\n ________________ " \ "\r\n | | " \ "\r\n | | " \ "\r\n | | " \ "\r\n | | " \ "\r\n | | " \ "\r\n | * | " \ "\r\n |________________| \r\n" ); } else if ( xl == 0 && yl == 0 && zl == 0 && xh == 0 && yh == 0 && zh == 1 ) { sprintf( report, "\r\n __*_____________ " \ "\r\n |________________| \r\n" ); } else if ( xl == 0 && yl == 0 && zl == 1 && xh == 0 && yh == 0 && zh == 0 ) { sprintf( report, "\r\n ________________ " \ "\r\n |________________| " \ "\r\n * \r\n" ); } else { sprintf( report, "None of the 6D orientation axes is set in LIS2DW12 - accelerometer.\r\n" ); } SerialPort.print(report); } 用图形的符号表示地磁的方向, 参见代码 sprintf( report, "\r\n ________________ " \ "\r\n | | " \ "\r\n | | " \ "\r\n | | " \ "\r\n | | " \ "\r\n | | " \ "\r\n | * | " \ "\r\n |________________| \r\n" );   2.5 气压传感器    LPS22HH   + Nucleo-STM32L476L读取传感器数据 首先导入驱动程序 同上,先设定I2C的接口,然后把变化传感器数据输出到串口 代码类似,具体参见下一贴。 2.6 温度传感器    STTS751+  Nucleo-STM32L476L读取传感器数据 首先导入驱动程序#include <STTS751Sensor.h> 在程序中,首先定义i2c的引脚和接线,然后读取传感器数据,并输出到串口。   实现代码如下, #include <STTS751Sensor.h> #ifdef ARDUINO_SAM_DUE #define DEV_I2C Wire1 #elif defined(ARDUINO_ARCH_STM32) #define DEV_I2C Wire #elif defined(ARDUINO_ARCH_AVR) #define DEV_I2C Wire #else #define DEV_I2C Wire #endif #define SerialPort Serial #define INT_1 A4 //Interrupts. volatile int mems_event = 0; uint8_t high = 0, low = 0; uint32_t previous_tick; float temperature = 0; STTS751Sensor *Temp; void INT1Event_cb() { mems_event = 1; } void setup() { // Led. pinMode(LED_BUILTIN, OUTPUT); // Initialize serial for output. SerialPort.begin(115200); // Initialize I2C bus. DEV_I2C.begin(); //Interrupts. attachInterrupt(INT_1, INT1Event_cb, FALLING); Temp = new STTS751Sensor(&DEV_I2C); Temp->Enable(); Temp->SetOutputDataRate(4.0f); Temp->SetLowTemperatureThreshold(22.0f); Temp->SetHighTemperatureThreshold(28.0f); Temp->SetEventPin(1); Temp->GetTemperatureLimitStatus(NULL, NULL, NULL); previous_tick=millis(); } void loop() { if (mems_event) { mems_event=0; uint8_t highTemp = 0, lowTemp = 0; Temp->GetTemperatureLimitStatus(&highTemp, &lowTemp, NULL); if (highTemp){ high = 1; low = 0; } if (lowTemp){ low = 1; high = 0; } Temp->GetTemperature(&temperature); // Led blinking. digitalWrite(LED_BUILTIN, HIGH); delay(100); digitalWrite(LED_BUILTIN, LOW); } uint32_t current_tick = millis(); if ((current_tick - previous_tick) >= 2000){ if (!high && !low){ Temp->GetTemperature(&temperature); } SerialPort.print("Temp[C]: "); SerialPort.print(temperature, 2); if (high){ SerialPort.println(" High temperature detected!(>28C) "); high = 0; } else if (low) { SerialPort.println(" Low temperature detected!(<22C) "); low = 0; } else { SerialPort.println(); } previous_tick = millis(); } } 程序下载和串口输出如下, 3、实现视频不单独演示,详见下一帖综合展示。       此内容由EEWORLD论坛网友北方原创,如需转载或用于商业用途需征得作者同意并注明出处

  • 2019-07-11
  • 回复了主题帖: 【奖品发送完毕】:从终端到架构,TE Connectivity(TE)助你连接5G高速未来

    确认个人信息无误 ,兑换成E金币,谢谢

  • 2019-07-10
  • 发表了主题帖: 【沁恒试用】精简手机系统设计 #1

    本帖最后由 北方 于 2019-7-10 13:55 编辑 精简手机系统设计 1、概述 精简手机系统设计是基于8051单片机沁恒CH549L和安可信A9G数据通讯模块开放的精简手机。 2、实现的功能 能够实现精简通讯和实时位置追踪功能。   3、实现的逻辑和原理 3.1 采用CH549和安可信A9G数据通讯模块通过UART口进行数据通讯和连接,连接采用的是标准的AT命令。 在CH549的开发中,使用了touchKey,ADC, GPIO,UART等多个资源,经过选择和调试,项目能够完整运行。其中CH549提供了UART0,UART1,UART2和UART3均测试,其中UART2和ouchkey的ADC有冲突,UART1在touchkey init中也有冲突,需要调整。 开发板连接如下图   本项目选择了UART0,可以在一个端口同时被板载USB-ttl转换,从desktop上也可以获取at通讯的信号,如下图   3.2 项目初步调试的代码如下,大部分是touchkey范例的参照。 #include ".\Public\CH549.H" #include ".\Public\DEBUG.H" #include ".\TouchKey\TouchKey.H" #pragma NOAREGS UINT16 PowerValue[16]; volatile UINT16 Press_Flag = 0; UINT8C CPW_Table[16] = { 30,30,30,30, 30,30,30,30, 30,30,30,30, 30,30,30,30, }; UINT16 ABS(UINT16 a,UINT16 b) { if(a>b) { return (a-b); } else { return (b-a); } } void LED_Port_Init(void) { P2 |= (0xF<<2); //默认熄灭 P2_MOD_OC &= ~(0xF<<2); P2_DIR_PU |= (0xF<<2); } void LED_Control(UINT8 LEDx,UINT8 status) { if(LEDx>3) { return; } if(status) //点亮 { P2 &= ~(1<<(2+LEDx)); } else //熄灭 { P2 |= (1<<(2+LEDx)); } } //主函数 void main() { UINT8 ch; UINT16 value; UINT16 err; //触摸模拟变化差值 CfgFsys( ); //CH549时钟选择配置 mDelaymS(20); mInitSTDIO( ); //串口0初始化 printf("TouchKey demo start ...\n"); LED_Port_Init(); TouchKey_Init(); Press_Flag = 0; for(ch = 8; ch!=12; ch++) { PowerValue[ch] = TouchKeySelect( ch,CPW_Table[ch] ); printf("%d ",PowerValue[ch] ); } printf("\n"); while(1) { /* 按键检测 */ for(ch = 8; ch!=12; ch++) { value = TouchKeySelect( ch,CPW_Table[ch] ); err = ABS(PowerValue[ch],value); if( err > DOWM_THRESHOLD_VALUE ) { if((Press_Flag & (1<<ch)) == 0) { printf("ch %d pressed,value:%d\n",(UINT16)ch, value); /* 点灯处理 */ LED_Control(ch-8,1); } Press_Flag |= (1<<ch); } else if( err < UP_THRESHOLD_VALUE ) { if(Press_Flag & (1<<ch)) { Press_Flag &= ~(1<<ch); printf("ch %d up,value:%d\n",(UINT16)ch, value); LED_Control(ch-8,0); } } } } }   其中,这里对于GPIO的访问是直接调用ch549.h中对于sbit P2的定义访问寄存器的方法,效率很高。   3.3 预留三维运动传感器的连接接口继续开发。 4. 补充说明 4.1 开发工具,推荐的开发需要keil C51,这样可以按照手册的方法添加芯片库。用开源SDCC也可以,不过只能使用标准MCS51的外设,不推荐。 4.2 程序下载比上一次的CH554评测增加了一个板载开关ON/OFF,非常方便,避免了反复插拔USB线的可能,同时USB下载速度有了明显提高,这样从keil直接下载也没有很大区别了。这个WCHISPtools可以开放接口,作为第三方程序在keil中直接调用,进一步提高效率。   4.3 实时操作系统,采用FREERTOS需要8k左右的内存,更重要的是data数据区只有256字节,在运行中受限更明显,不宜采用。RTX tiny小于1k可以使用,不过调试使用需要更熟悉时钟,不如用轮询的polling方式更简单直接。自己直接算时钟周期,其实也效果不错。 4.4 引用范例的head文件要仔细对代码,尤其是复用的引脚和中断的配置,需要列表后使用,避免冲突。 4.5 安可信的A9G资料在参见https://wiki.ai-thinker.com/gprs/a9g/boards,CH549L的芯片原理连接如下图。 引脚配置使用时需要对照使用。   5、小结 本设计可以实现一个便携手机的功能。这个设计过程中, - 完整测试了多个适合8051的实时操作系统如RTX tiny, FreeRTOS,经测试均不适合本项目,也就没有采用。 - 在多个端口的同时使用中,多次发生重复定义和接口重复的过程,加深了对CH549L的了解。   此内容由EEWORLD论坛网友北方原创,如需转载或用于商业用途需征得作者同意并注明出处

最近访客

< 1/6 >

统计信息

已有132人来访过

  • 芯币:482
  • 好友:1
  • 主题:79
  • 回复:88
  • 课时:--
  • 资源:--

留言

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


现在还没有留言