完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
你好:
我用这个加速度计做了几个月的战斗,现在我必须让它运转起来。 我正在使用它与STM32F405控制器。我把它设置为中断模式。当我得到一个中断时,我会读取并处理X,Y,Z寄存器但值总是(或差不多)相同:-20,-3,-6。 我完全不知道发生了什么。有人可以帮我这个吗?以下是中断后处理数据的代码。紧接着是对处理程序使用的SPI读取的调用 uint8_t SPI_read(uint8_t地址) { GPIO_SetPinLow(GPIOD,ACCHI_CS); 地址= 0x80 |地址; // 0b10 - 读取和清除状态 while(SPI_I2S_GetFlagStatus(SPI3,SPI_I2S_FLAG_TXE)== RESET); SPI_I2S_SendData(SPI3,地址); while(SPI_I2S_GetFlagStatus(SPI3,SPI_I2S_FLAG_RXNE)== RESET); SPI_I2S_ReceiveData(SPI3); while(SPI_I2S_GetFlagStatus(SPI3,SPI_I2S_FLAG_TXE)== RESET); SPI_I2S_SendData(SPI3,0x00); while(SPI_I2S_GetFlagStatus(SPI3,SPI_I2S_FLAG_RXNE)== RESET); GPIO_SetPinHigh(GPIOD,ACCHI_CS); 返回SPI_I2S_ReceiveData(SPI3); } / * EXT1的中断处理程序* / void EXti1_IRQHandler(void) { volatile uint8_t x = 0,y = 0,z = 0,reg; volatile float32_t cX = 0,cY = 0,cZ = 0; volatile int8_t accVal,xF,yF,zF; if(EXTI_GetITStatus(EXTI_Line1)!= RESET) { EXTI_ClearITPendingBit(EXTI_Line1); //谁是dunnit? reg = SPI_read(LIS200DL_INT1SRC); if(reg& 0x40) { x = SPI_read(LIS200DL_OUT_X); y = SPI_read(LIS200DL_OUT_Y); z = SPI_read(LIS200DL_OUT_Z); } if(x& 0x80) { //它是否定的,反转结果 accVal = x ^ 1; accVal + = 0x1; cX =(accVal * 0.780); // printf(' - X acc value =%。1f n',cX); } 其他 { cX =(x * 0.780)* -1.0; // printf('+ X acc value =%。1f n',cX); } if(y& 0x80) { //反转结果 accVal = y ^ 1; accVal + = 0x1; cY =(accVal * 0.780); // printf('+ Y acc value =%。1f n',cY); } 其他 { cY =(y * 0.780)* -1.0; // printf(' - Y acc value =%。1f n',cY); } if(z& 0x80) { //反转结果 accVal = z ^ 1; accVal + = 0x1; cZ =(accVal * 0.780); // printf('+ Z acc value =%。1f n',cZ); } 其他 { cZ =(z * 0.780)* -1.0; // printf(' - Z acc value =%。1f n',cZ); } xF =(int8_t)cX; yF =(int8_t)cY; zF =(int8_t)cZ; if((abs(xF)> 3)||(abs(yF)> 3)||(abs(zF)> 3)) { myDataX = xF; myDataY = yF; myDataZ = zF; } }} 请告知我在哪里犯了错误。如果此论坛上没有人可以提供帮助,我如何获得官方ST支持?这个设备将在很多系统上使用,现在,它正在举行项目。] 罗杰 以上来自于谷歌翻译 以下为原文 Hello: I have been fighting with this accelerometer for a couple of months and it has now become imperative that I get it functioning. I am using it with an STM32F405 controller. I have it set up in interrupt mode. When I get an interrupt, I read and process the X,Y,Z registers but the values are always (or almost nearly) the same: -20, -3, -6. I have absolutely not a clue what is going on. Can anyone please help me with this? Here is the code to process the data after the interrupt. Directly below is the call to SPI read that the handler uses uint8_t SPI_read(uint8_t address) { GPIO_SetPinLow(GPIOD, ACCHI_CS); address = 0x80 | address; // 0b10 - reading and clearing status while(SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_TXE) == RESET); SPI_I2S_SendData(SPI3, address); while(SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_RXNE) == RESET); SPI_I2S_ReceiveData(SPI3); while(SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_TXE) == RESET); SPI_I2S_SendData(SPI3, 0x00); while(SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_RXNE) == RESET); GPIO_SetPinHigh(GPIOD, ACCHI_CS); return SPI_I2S_ReceiveData(SPI3); } /* Interrupt handler for EXT1 */ void EXTI1_IRQHandler(void) { volatile uint8_t x = 0, y = 0, z = 0, reg; volatile float32_t cX = 0, cY = 0, cZ = 0; volatile int8_t accVal, xF,yF,zF; if (EXTI_GetITStatus(EXTI_Line1) != RESET ) { EXTI_ClearITPendingBit(EXTI_Line1); // who dunnit? reg = SPI_read( LIS200DL_INT1SRC ); if( reg & 0x40 ) { x = SPI_read( LIS200DL_OUT_X ); y = SPI_read( LIS200DL_OUT_Y ); z = SPI_read( LIS200DL_OUT_Z ); } if( x & 0x80 ) { //it's negative, invert result accVal = x ^ 1; accVal += 0x1; cX = (accVal * 0.780); //printf('-X acc value = %.1fn', cX); } else { cX = (x * 0.780) * -1.0; //printf('+X acc value = %.1fn', cX); } if( y & 0x80 ) { //invert result accVal = y ^ 1; accVal += 0x1; cY = (accVal * 0.780); //printf('+Y acc value = %.1fn', cY); } else { cY = (y * 0.780) * -1.0; //printf('-Y acc value = %.1fn', cY); } if( z & 0x80 ) { //invert result accVal = z ^ 1; accVal += 0x1; cZ = (accVal * 0.780); //printf('+Z acc value = %.1fn', cZ); } else { cZ = (z * 0.780) * -1.0; //printf('-Z acc value = %.1fn', cZ); } xF = (int8_t)cX; yF = (int8_t)cY; zF = (int8_t)cZ; if( (abs(xF) > 3) || (abs(yF) > 3) || (abs(zF) > 3) ) { myDataX = xF; myDataY = yF; myDataZ = zF; } }} Please advise as to where I am making a mistake. If no one on this forum can help, how can I get official ST support? This device will be used on quite a few systems and right now, it is holding the project up.] Roger |
|
相关推荐
10个回答
|
|
您能否提供您的传感器配置(注册设置)?
以上来自于谷歌翻译 以下为原文 Can you please provide your sensor configuration (register settings)? |
|
|
|
这是包含SPI和寄存器的设置。下面是寄存器定义。
uint8_t configH3LIS200DL(void) { uint8_t rtnValue; GPIO_InitTypeDef GPIO_InitStructure; SPI_InitTypeDef SPI_InitStructure; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC,ENABLE); RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD,ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI3,ENABLE); SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; SPI_InitStructure.SPI_Mode = SPI_Mode_Master; SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; SPI_InitStructure.SPI_CPOL = SPI_CPOL_High; SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; SPI_InitStructure.SPI_NSS = SPI_NSS_Soft | SPI_NSSInternalSoft_Set; SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_32; SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; SPI_Init(SPI3,& SPI_InitStructure); //初始化SPI功能的引脚 GPIO_InitStructure.GPIO_Pin = ACCHI_SCK | ACCHI_MISO | ACCHI_MOSI; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOC,& GPIO_InitStructure); //初始化芯片选择引脚 GPIO_InitStructure.GPIO_Pin = ACCHI_CS; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOD,& GPIO_InitStructure); //在下面的void Configure_PD1_EXTI(void)中配置的中断1 ... GPIO_PinAFConfig(GPIOC,GPIO_PinSource10,GPIO_AF_SPI3); GPIO_PinAFConfig(GPIOC,GPIO_PinSource11,GPIO_AF_SPI3); GPIO_PinAFConfig(GPIOC,GPIO_PinSource12,GPIO_AF_SPI3); //最初设置为HIGH GPIO_SetPinHigh(GPIOD,ACCHI_CS); //启用SPI3 SPI_Cmd(SPI3,ENABLE); SPI_send(LIS200DL_WHO_AM_I,0x0); rtnValue = SPI_read(LIS200DL_WHO_AM_I); // printf('ID2 =%x n',rtnValue); SPI_send(LIS200DL_CTRL_REG1,0x2F); rtnValue = SPI_read(LIS200DL_CTRL_REG1); // printf('ctl1 =%x n',rtnValue); SPI_send(LIS200DL_CTRL_REG3,0x0); rtnValue = SPI_read(LIS200DL_CTRL_REG3); // printf('ctl1 =%x n',rtnValue); SPI_send(LIS200DL_CTRL_REG4,0x0); //配置中断寄存器 SPI_send(LIS200DL_INT1CFG,0x2A); rtnValue = SPI_read(LIS200DL_INT1CFG); // printf('int1 reg =%x n',rtnValue); //设置阈值寄存器= 3 SPI_send(LIS200DL_INT1THS,0x3); rtnValue = SPI_read(LIS200DL_INT1THS); // printf('thr reg =%x n',rtnValue); return rtnValue; 注册DEFS: #define LIS200DL_WHO_AM_I 0x0F #define LIS200DL_CTRL_REG1 0x20 #define LIS200DL_CTRL_REG2 0x21 #define LIS200DL_CTRL_REG3 0x22 #define LIS200DL_CTRL_REG4 0x23 #define LIS200DL_CTRL_REG5 0x24 #define LIS200DL_HP_RESET 0x25 #define LIS200DL_STATUS_REG 0x27 #define LIS200DL_OUT_X 0x29 #define LIS200DL_OUT_Y 0x2B #define LIS200DL_OUT_Z 0x2D #define LIS200DL_INT1CFG 0x30 #define LIS200DL_INT1SRC 0x31 #define LIS200DL_INT1THS 0x32 #define LIS200DL_INT1DUR 0x33 #define LIS200DL_INT2CFG 0x34 #define LIS200DL_INT2SRC 0x35 #define LIS200DL_INT2THS 0x36 #define LIS200DL_INT2DUR 0x37 // CTRL_REG1 #define LIS200DL_XEN 0x01 #define LIS200DL_YEN 0x02 #define LIS200DL_ZEN 0x04 #define LIS200DL_XYZ_NEW 0x08 #define LIS200DL_XOR 0x10 #define LIS200DL_YOR 0x20 #define LIS200DL_ZOR 0x40 #define LIS200DL_XYZOR 0x80 // CTRL_REG2 #define LIS200DL_HP_COEFF1 0x01 #define LIS200DL_HP_COEFF2 0x02 #define LIS200DL_HP_FF_WU1 0x04 #define LIS200DL_HP_FF_WU2 0x08 #define LIS200DL_FDS 0x10 #define LIS200DL_BOOT 0x40 #define LIS200DL_SIM 0x80谢谢, 罗杰 以上来自于谷歌翻译 以下为原文 Here is the setup that includes the SPI and registers. Below that is the register definitions. uint8_t configH3LIS200DL( void ) { uint8_t rtnValue; GPIO_InitTypeDef GPIO_InitStructure; SPI_InitTypeDef SPI_InitStructure; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE); RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI3, ENABLE); SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; SPI_InitStructure.SPI_Mode = SPI_Mode_Master; SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; SPI_InitStructure.SPI_CPOL = SPI_CPOL_High; SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; SPI_InitStructure.SPI_NSS = SPI_NSS_Soft | SPI_NSSInternalSoft_Set; SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_32; SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; SPI_Init(SPI3, &SPI_InitStructure); //Initialize pins for SPI functionality GPIO_InitStructure.GPIO_Pin = ACCHI_SCK | ACCHI_MISO | ACCHI_MOSI; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOC, &GPIO_InitStructure); //Initialize Chip Select pin GPIO_InitStructure.GPIO_Pin = ACCHI_CS; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOD, &GPIO_InitStructure); //interrupt 1 configured in void Configure_PD1_EXTI(void) below... GPIO_PinAFConfig(GPIOC, GPIO_PinSource10, GPIO_AF_SPI3); GPIO_PinAFConfig(GPIOC, GPIO_PinSource11, GPIO_AF_SPI3); GPIO_PinAFConfig(GPIOC, GPIO_PinSource12, GPIO_AF_SPI3); // set initially HIGH GPIO_SetPinHigh(GPIOD, ACCHI_CS); // enable SPI3 SPI_Cmd(SPI3, ENABLE); SPI_send( LIS200DL_WHO_AM_I, 0x0 ); rtnValue = SPI_read( LIS200DL_WHO_AM_I ); //printf('ID2 = %xn', rtnValue); SPI_send( LIS200DL_CTRL_REG1, 0x2F ); rtnValue = SPI_read( LIS200DL_CTRL_REG1 ); //printf('ctl1 = %xn', rtnValue); SPI_send( LIS200DL_CTRL_REG3, 0x0 ); rtnValue = SPI_read( LIS200DL_CTRL_REG3 ); //printf('ctl1 = %xn', rtnValue); SPI_send( LIS200DL_CTRL_REG4, 0x0 ); //configure interrupt register SPI_send( LIS200DL_INT1CFG, 0x2A ); rtnValue = SPI_read( LIS200DL_INT1CFG ); //printf('int1 reg = %xn', rtnValue); //set threshold register = 3 SPI_send( LIS200DL_INT1THS, 0x3 ); rtnValue = SPI_read( LIS200DL_INT1THS ); //printf('thr reg = %xn', rtnValue); return rtnValue; }REGISTER DEFS: #define LIS200DL_WHO_AM_I 0x0F #define LIS200DL_CTRL_REG1 0x20 #define LIS200DL_CTRL_REG2 0x21 #define LIS200DL_CTRL_REG3 0x22 #define LIS200DL_CTRL_REG4 0x23 #define LIS200DL_CTRL_REG5 0x24 #define LIS200DL_HP_RESET 0x25 #define LIS200DL_STATUS_REG 0x27 #define LIS200DL_OUT_X 0x29 #define LIS200DL_OUT_Y 0x2B #define LIS200DL_OUT_Z 0x2D #define LIS200DL_INT1CFG 0x30 #define LIS200DL_INT1SRC 0x31 #define LIS200DL_INT1THS 0x32 #define LIS200DL_INT1DUR 0x33 #define LIS200DL_INT2CFG 0x34 #define LIS200DL_INT2SRC 0x35 #define LIS200DL_INT2THS 0x36 #define LIS200DL_INT2DUR 0x37 // CTRL_REG1 #define LIS200DL_XEN 0x01 #define LIS200DL_YEN 0x02 #define LIS200DL_ZEN 0x04 #define LIS200DL_XYZ_NEW 0x08 #define LIS200DL_XOR 0x10 #define LIS200DL_YOR 0x20 #define LIS200DL_ZOR 0x40 #define LIS200DL_XYZOR 0x80// CTRL_REG2 #define LIS200DL_HP_COEFF1 0x01 #define LIS200DL_HP_COEFF2 0x02 #define LIS200DL_HP_FF_WU1 0x04 #define LIS200DL_HP_FF_WU2 0x08 #define LIS200DL_FDS 0x10 #define LIS200DL_BOOT 0x40 #define LIS200DL_SIM 0x80Thanks, Roger |
|
|
|
配置似乎对我来说,它按预期工作。如果任何轴的加速度超过2.3g,则将传感器配置为生成中断。
你如何刺激中断? 如果你说:'我读取并处理X,Y,Z寄存器但值总是(或差不多)相同:-20,-3,-6。 LSB或g中的值是多少? 你想达到什么目的?你的目标应用是什么? 以上来自于谷歌翻译 以下为原文 The configuration seems OK to me, it works as expected. You configured the sensor to generate the interrupt if acceleration in any axis is above 2.3g. How do you stimulate the interrupt? If you say: 'I read and process the X,Y,Z registers but the values are always (or almost nearly) the same: -20, -3, -6.' are the values in LSB or in g? What do you want to achieve? What is your target application? |
|
|
|
嗨,
感谢您抽出时间来查看并回复。首先也是最重要的是,您能否告知从原始数据到值的转换是否正确?它们应该从原始值转换为“g”值。 (关于你关于LSB或g值的问题) 关于你的另一个问题 - 如果价值几乎总是' -20,-3,-6。' 那对你来说不是很可疑吗?我感兴趣的是+/- 3g到+/- 100g的值。该应用程序位于工业机器的PCB上,其中存在各种可能达到100g的振动值。那么为什么总会产生这些价值?问候...... 以上来自于谷歌翻译 以下为原文 Hi, Thanks for taking the time to look at this and reply. First and most importantly, can you please advise if the conversions from raw data to values look correct? They should be converting from raw values to 'g' values. (in reference to your question about LSB or g values) With respect to your other question - if the values were almost always ' -20, -3, -6.' , wouldn't that look suspicious to you? I am interested in those values from +/-3g to +/-100g. The application is on a PCB in an industrial machine and there are all kinds of shake values in there that could potentially go to 100g. So why would it always produce these values?Regards... |
|
|
|
好的,如果您可以检查并验证这一点,我将不胜感激 - 它可能是某些问题所在。
此外,值xF,yF和zF已经声明为int8_t。这是你所指的变量('你可以简单地将类型从uint8_t改为int8_t ......')或者你的意思是什么不同? 以上来自于谷歌翻译 以下为原文 Ok, if you could check and verify this, I would be grateful - it may be where some of the problem is. Also, values xF, yF and zF are declared as int8_t already. Is that the variables you were referring to ('you can simply change the type from uint8_t to int8_t ...') or did you mean something different? |
|
|
|
乍一看,我认为这是不正确的,但我明天会模拟你的代码。
您不必通过如此复杂的函数转换原始值,您只需将类型从uint8_t更改为int8_t并乘以灵敏度即可。 xF =(int_8)x * 0.780f; 以上来自于谷歌翻译 以下为原文 At the first glance, I think it is not correct, but I will simulate exactly your code tomorrow. You don't have to convert the raw value by so complex function, you can simply change the type from uint8_t to int8_t and multiply by sensitivity. xF = (int_8)x * 0.780f; |
|
|
|
这个:
x =(x ^ 0xFF)+ 1; //两个补码 修复。这是胡说八道! 谢谢 以上来自于谷歌翻译 以下为原文 This: x = (x ^ 0xFF) + 1; // Two's complement Fixed it. It was nonsense! Thanks |
|
|
|
if(x& 0x80)
{ //它是否定的,反转结果 accVal = x ^ 1; accVal + = 0x1; cX =(accVal * 0.780); // printf(' - X acc value =%。1f n',cX); } 什么是XOR ONE废话? if(x& 0x80) x =(x ^ 0xFF)+ 1; //两个补码 或者它是符号幅度格式? 以上来自于谷歌翻译 以下为原文 if( x & 0x80 ) { //it's negative, invert result accVal = x ^ 1; accVal += 0x1; cX = (accVal * 0.780); //printf('-X acc value = %.1fn', cX); } What's the XOR ONE nonsense? if (x & 0x80) x = (x ^ 0xFF) + 1; // Two's complement Or is it in sign-magnitude format? |
|
|
|
我有几个笔记:
- 是的,XOR操作不正确 - 如果您修复XOR操作,转换将是正确的,除了符号。您正在反转该值。如果加速度计输出为正,则得到负值,反之亦然。但也许你是故意这样做的。 - 由于从float转换为int(在此命令中),您正在失去一些精度 xF =(int8_t)cX;) - 由于C对有符号变量使用二进制补码,您只需用一个命令替换整个if结构:xF =(int8_t)x * 0.780f; 以上来自于谷歌翻译 以下为原文 I have several notes: - yes, the XOR operation was not correct - if you fix the XOR operation the conversion will be correct except the sign. You are inverting the value. If the accelerometer output is positive you get negative value and vice versa. But maybe you are doing this intentionally. - you are loosing some precision due to conversion from float to int (in this command xF = (int8_t)cX;) - As C use two's complement for signed variables you can simply replace the whole if structure by one command: xF = (int8_t)x * 0.780f; |
|
|
|
米罗斯拉夫,
一切都很好,更新了我的代码,结果很好。非常感谢你的帮助! 以上来自于谷歌翻译 以下为原文 Miroslav, All is well, updated my code and the results are good. Thanks so much for your help! |
|
|
|
只有小组成员才能发言,加入小组>>
请教:在使用UDE STK时,单片机使用SPC560D30L1,在配置文件怎么设置或选择?里面只有SPC560D40的选项
2742 浏览 1 评论
3244 浏览 1 评论
请问是否有通过UART连接的两个微处理器之间实现双向值交换的方法?
1813 浏览 1 评论
3653 浏览 6 评论
6044 浏览 21 评论
1342浏览 4评论
203浏览 3评论
对H747I-DISCO写程序时将CN2的st-link复用为usart1,再次烧录时无法检测到stlink怎么解决?
356浏览 2评论
STM32G474RE芯片只是串口发个数据就发烫严重是怎么回事?
446浏览 2评论
STM32处理增量式编码器Z信号如何判断中断是正转的还是反向转的?
275浏览 2评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-27 17:19 , Processed in 1.107955 second(s), Total 60, Slave 54 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号