完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
本帖最后由 博学而笃志 于 2015-12-26 19:11 编辑 如何用Serial_Digital_Scope V2将串口数据转化成波形 在讲怎么使用这个软件之前我想和大家讲一下我是怎么接触到这种软件的,是因为我在做平衡车。做平衡车大家都应该知道要调节滤波算法和PID的系数。如果我们不把滤波前和滤波后的数据用图像表示出来,我们是很难知道我们调节的到底合不合适。所以我就像到有没有这种将串口输出的数据转化成折线图。之前我是用过匿名四轴的地面站,那个匿名软件给我的印象是功能很强大的。可能是因为我不会用,所以用他表现出的波型很奇怪不正确。 后来我使用Serial_Digital_Scope V2这软件,他替我表示出的就正常了。 下面就有我来讲解一下这个软件的用法把。 像这种输入数据(你输给电脑的串口数据),又要输出数据(你想看到的波形)软件他是有他的协议的。下面的这两个函数就是他的协议 unsigned short CRC_CHECK(unsigned char *Buf, unsigned char CRC_CNT) { unsigned short CRC_Temp; unsigned char i,j; CRC_Temp = 0xffff; for (i=0;i CRC_Temp ^= Buf; for (j=0;j<8;j++) { if (CRC_Temp & 0x01) CRC_Temp = (CRC_Temp >>1 ) ^ 0xa001; else CRC_Temp = CRC_Temp >> 1; } } return(CRC_Temp); } void OutPut_Data(void) { int temp[4] = {0}; unsigned int temp1[4] = {0}; unsigned char databuf[10] = {0}; unsigned char i; unsigned short CRC16 = 0; for(i=0;i<4;i++) { temp = (int)OutData; temp1 = (unsigned int)temp; } for(i=0;i<4;i++) { databuf[i*2] = (unsigned char)(temp1%256); databuf[i*2+1] = (unsigned char)(temp1/256); } CRC16 = CRC_CHECK(databuf,8); databuf[8] = CRC16%256; databuf[9] = CRC16/256; for(i=0;i<10;i++) // uart_putchar(databuf); uart_putchar (UART4,(char)databuf); } 要想给这个上位机输入数据,那就少不了定义变量float OutData[4] ,需要发送的数值就要赋予该数组。 下面我就以MPU6050为例演示如何使用: 下面我贴出了完整的代码(我相信对STC12单片机有一定了解的都能看懂我就不多解释这代码了): //**************************************** // 功能: 显示加速度计和陀螺仪的10位原始数据 //**************************************** // 原件名称:大鱼电子GY521mpu-6050IIC测试程序 // 使用单片机:STC12C5A60S2 // 晶振:11.0592M // 显示:串口调试助手 // 编译环境 Keil uVision4 // 姓名:谢鑫 // 2015.12.17 //**************************************** #include #include #include typedef unsigned char uchar; typedef unsigned short ushort; typedef unsigned int uint; //**************************************** // 定义51单片机端口 //**************************************** ***it SCL=P2^0; //IIC时钟引脚定义 ***it SDA=P2^1; //IIC数据引脚定义 //**************************************** // 定义MPU6050内部地址 //**************************************** #define SMPLRT_DIV 0x19 //陀螺仪采样率,典型值:0x07(125Hz) #define CONFIG 0x1A //低通滤波频率,典型值:0x06(5Hz) #define GYRO_CONFIG 0x1B //陀螺仪自检及测量范围,典型值:0x18(不自检,2000deg/s) #define ACCEL_CONFIG 0x1C //加速计自检、测量范围及高通滤波频率,典型值:0x01(不自检,2G,5Hz) #define ACCEL_XOUT_H 0x3B #define ACCEL_XOUT_L 0x3C #define ACCEL_YOUT_H 0x3D #define ACCEL_YOUT_L 0x3E #define ACCEL_ZOUT_H 0x3F #define ACCEL_ZOUT_L 0x40 #define TEMP_OUT_H 0x41 #define TEMP_OUT_L 0x42 #define GYRO_XOUT_H 0x43 #define GYRO_XOUT_L 0x44 #define GYRO_YOUT_H 0x45 #define GYRO_YOUT_L 0x46 #define GYRO_ZOUT_H 0x47 #define GYRO_ZOUT_L 0x48 #define PWR_MGMT_1 0x6B //电源管理,典型值:0x00(正常启用) #define WHO_AM_I 0x75 //IIC地址寄存器(默认数值0x68,只读) #define SlaveAddress 0xD0 //IIC写入时的地址字节数据,+1为读取 /********使用虚拟示波器要用的参数和函数***************************/ float OutData[4] = { 0 }; void init_uart(); unsigned short CRC_CHECK(unsigned char *Buf, unsigned char CRC_CNT); void OutPut_Data(void); void uart_putchar(uchar send_data); //函数声明 //**************************************** int GetData(uchar REG_Address); //MPU6050操作函数 void InitMPU6050(); //初始化MPU6050 void Delay5us(); void I2C_Start(); void I2C_Stop(); void I2C_SendACK(bit ack); bit I2C_RecvACK(); void I2C_SendByte(uchar dat); uchar I2C_RecvByte(); uchar Single_ReadI2C(uchar REG_Address); //读取I2C数据 void Single_WriteI2C(uchar REG_Address,uchar REG_data); //向I2C写入数据 //**************************************** //************************************** //延时5微秒(STC90C52RC@12M) //不同的工作环境,需要调整此函数 //当改用1T的MCU时,请调整此延时函数 //************************************** void Delay5us() { _nop_();_nop_();_nop_();_nop_(); _nop_();_nop_();_nop_();_nop_(); _nop_();_nop_();_nop_();_nop_(); _nop_();_nop_();_nop_();_nop_(); _nop_();_nop_();_nop_();_nop_(); _nop_();_nop_();_nop_();_nop_(); } //************************************** //I2C起始信号 //************************************** void I2C_Start() { SDA = 1; //拉高数据线 SCL = 1; //拉高时钟线 Delay5us(); //延时 SDA = 0; //产生下降沿 Delay5us(); //延时 SCL = 0; //拉低时钟线 } //************************************** //I2C停止信号 //************************************** void I2C_Stop() { SDA = 0; //拉低数据线 SCL = 1; //拉高时钟线 Delay5us(); //延时 SDA = 1; //产生上升沿 Delay5us(); //延时 } //************************************** //I2C发送应答信号 //入口参数:ack (0:ACK 1:NAK) //************************************** void I2C_SendACK(bit ack) { SDA = ack; //写应答信号 SCL = 1; //拉高时钟线 Delay5us(); //延时 SCL = 0; //拉低时钟线 Delay5us(); //延时 } //************************************** //I2C接收应答信号 //************************************** bit I2C_RecvACK() { SCL = 1; //拉高时钟线 Delay5us(); //延时 CY = SDA; //读应答信号 SCL = 0; //拉低时钟线 Delay5us(); //延时 return CY; } //************************************** //向I2C总线发送一个字节数据 //************************************** void I2C_SendByte(uchar dat) { uchar i; for (i=0; i<8; i++) //8位计数器 { dat <<= 1; //移出数据的最高位 SDA = CY; //送数据口 SCL = 1; //拉高时钟线 Delay5us(); //延时 SCL = 0; //拉低时钟线 Delay5us(); //延时 } I2C_RecvACK(); } //************************************** //从I2C总线接收一个字节数据 //************************************** uchar I2C_RecvByte() { uchar i; uchar dat = 0; SDA = 1; //使能内部上拉,准备读取数据, for (i=0; i<8; i++) //8位计数器 { dat <<= 1; SCL = 1; //拉高时钟线 Delay5us(); //延时 dat |= SDA; //读数据 SCL = 0; //拉低时钟线 Delay5us(); //延时 } return dat; } //************************************** //向I2C设备写入一个字节数据 //************************************** void Single_WriteI2C(uchar REG_Address,uchar REG_data) { I2C_Start(); //起始信号 I2C_SendByte(SlaveAddress); //发送设备地址+写信号 I2C_SendByte(REG_Address); //内部寄存器地址, I2C_SendByte(REG_data); //内部寄存器数据, I2C_Stop(); //发送停止信号 } //************************************** //从I2C设备读取一个字节数据 //************************************** uchar Single_ReadI2C(uchar REG_Address) { uchar REG_data; I2C_Start(); //起始信号 I2C_SendByte(SlaveAddress); //发送设备地址+写信号 I2C_SendByte(REG_Address); //发送存储单元地址,从0开始 I2C_Start(); //起始信号 I2C_SendByte(SlaveAddress+1); //发送设备地址+读信号 REG_data=I2C_RecvByte(); //读出寄存器数据 I2C_SendACK(1); //接收应答信号 I2C_Stop(); //停止信号 return REG_data; } //********************************************************* //主程序 //********************************************************* void main() { init_uart(); InitMPU6050(); //初始化MPU6050 while(1) { // 32768.0*180先将从MPU6050中读取到的16位的数据转换10进制的角度 // printf ("good morning everyonesn"); // printf ("%.3ft",(short)GetData(ACCEL_XOUT_H)/32768.0*180); //显示X轴角度 // printf ("%.3ft",(short)GetData(ACCEL_YOUT_H)/32768.0*180); //显示Y轴角度 // printf ("%.3ftn",(short)GetData(ACCEL_ZOUT_H)/32768.0*180); //显示Z轴角度 // // printf ("%.3ft",(short)GetData(GYRO_XOUT_H)/32768.0*2000); //显示X轴角速度 // printf ("%.3ft",(short)GetData(GYRO_YOUT_H)/32768.0*2000); //显示Y轴角速度 // printf ("%.3ftn",(short)GetData(GYRO_ZOUT_H)/32768.0*2000); //显示Z轴角速度 OutData[0]=( (short)GetData(ACCEL_XOUT_H)/32768.0*180 )*1000; OutData[1]=8; OutData[2]=8; OutData[3]=8; OutPut_Data(); } } //************************************** //初始化MPU6050 //************************************** void InitMPU6050() { Single_WriteI2C(PWR_MGMT_1, 0x00); //解除休眠状态 Single_WriteI2C(SMPLRT_DIV, 0x07); Single_WriteI2C(CONFIG, 0x06); Single_WriteI2C(GYRO_CONFIG, 0x18); Single_WriteI2C(ACCEL_CONFIG, 0x01); } //************************************** //合成数据 //************************************** int GetData(uchar REG_Address) { uchar H,L; H=Single_ReadI2C(REG_Address); L=Single_ReadI2C(REG_Address+1); return (H<<8)+L; //合成数据 } void init_uart() { TMOD=0x20; TH1=0xfd; TL1=0xfd; TR1=1; SM0=0; SM1=1; REN=1; EA=1; ES=1; // ti=1; } void uart_putchar(uchar send_data) { ES=0; //关闭中断这很重要 SBUF=send_data; while(!TI); TI=0; ES=1; } unsigned short CRC_CHECK(unsigned char *Buf, unsigned char CRC_CNT) { unsigned short CRC_Temp; unsigned char i,j; CRC_Temp = 0xffff; for (i=0;i CRC_Temp ^= Buf; for (j=0;j<8;j++) { if (CRC_Temp & 0x01) CRC_Temp = (CRC_Temp >>1 ) ^ 0xa001; else CRC_Temp = CRC_Temp >> 1; } } return(CRC_Temp); } void OutPut_Data(void) { int temp[4] = {0}; unsigned int temp1[4] = {0}; unsigned char databuf[10] = {0}; unsigned char i; unsigned short CRC16 = 0; for(i=0;i<4;i++) { temp = (int)OutData; temp1 = (unsigned int)temp; } for(i=0;i<4;i++) { databuf[i*2] = (unsigned char)(temp1%256); databuf[i*2+1] = (unsigned char)(temp1/256); } CRC16 = CRC_CHECK(databuf,8); databuf[8] = CRC16%256; databuf[9] = CRC16/256; for(i=0;i<10;i++) uart_putchar(databuf); // uart_putchar (UART4,(char)databuf); } 然后你就能看到下面的图像,那就要恭喜你了你已经会使用这软件了。 |
|
相关推荐
|
|
实测程序有以下几点问题;
1,temp = (int)OutData; 改为 temp[i] = (int)OutData; temp1 = (unsigned int)temp; 改为 temp1[i] = (unsigned int)temp; 2. CRC_Temp ^= Buf 改为 CRC_Temp ^= Buf[i] 3. databuf[i*2] = (unsigned char)(temp1%256); 改为 databuf[i*2] = (unsigned char)(temp1[i]%256); databuf[i*2+1] = (unsigned char)(temp1/256); databuf[i*2+1] = (unsigned char)(temp1[i]/256); 波形如下;不知哪里有问题
|
|
|
|
|
|
可能上传的时候出了问题,我电脑里的程序不是这样的
|
|
|
|
|
|
1575 浏览 1 评论
1305 浏览 1 评论
MCU友好过渡MPU,米尔基于STM32MP135开发板裸机开发应用笔记
665 浏览 0 评论
自定义系统时钟频率后,用库函数和微带两种方式点亮LED灯,为什么灯的闪烁频率不一致?
1815 浏览 2 评论
2048 浏览 2 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-5-3 19:24 , Processed in 0.446171 second(s), Total 67, Slave 51 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号