专家
公告
财富商城
电子网
旗下网站
首页
问题库
专栏
标签库
话题
专家
NEW
门户
发布
提问题
发文章
STM32
关于f407编码器模式测量角度
2019-07-21 00:20
发布
×
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮
站内问答
/
STM32/STM8
4427
6
1332
最近在做防摇控制系统,类似于倒立摆,需要测量摇摆角度,看了许多编码器测速的,但是好像没有测角度的,最大的难点是方向时刻改变,不知道计数值会不会跟着减少,还有就是当减到0时继续减小是变成负的还是从2000线开始减少。希望用编码器测角度的大神们给点建议。谢谢啦。。。。
友情提示:
此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
6条回答
dalianlwd
2019-07-21 01:36
2楼已经给你答案了。必须是绝对值编码器。有一种SPI接口的绝对值编码器比较适合。以下代码是我去年测试用的。
void GetSSI_Y(void)
{
u8 i = 0; //
u8 State = 0; //状态位数据
u8 Crc = 0; // 奇数或偶数标志位
int Y_DATA=0 ;//当前的角度数据( 0-1023 )
int ire_y=0 ; //增量数据,表示上次正确读的数据,和这次正确读的位置差
HN3806_Ycs = 0;//选中X编码器
__nop();__nop();
HN3806_Yclk = 0;//
delay_us(1);
HN3806_Yclk = 1;//CLK
delay_us(1);
for(i = 0; i < 12;i++)//读12次 前10位数据(12位绝对值编码器;ix < 10改成ix < 12即可)
{
HN3806_Yclk = 0;//CLK
Y_DATA <<= 1;//前10位的数据1024
if(HN3806_Ydata)//DO数据
{
Crc = !Crc;//标置位取反,数位中“1”的个数是奇数或偶数来进行校验 (初值=0)
Y_DATA |= 1;//最后位置1
}
HN3806_Yclk = 1;
delay_us(1);
}
delay_us(1);
for(i = 0; i < 5;i++)//读5次状态位标志!
{
HN3806_Yclk = 0;
State <<= 1; //后五位的数据状态位
if(HN3806_Ydata)
{
Crc = !Crc;//数位中“1”的个数是奇数或偶数来进行校验
State |= 1;//数据等于1置1
}
HN3806_Yclk = 1;
delay_us(1);
}
delay_us(1);
if(HN3806_Ydata == Crc)//最后一位校验一下,要是奇偶通不过,就认为CRC错误 ,就当这次无效
{
HN3806_Ycs = 1;//使能CSN置高,为下次准备
if((State == 16)||(State == 19))//;///&&(uState == uPrvState)) //16=10000;19=10011 表示状态位(5位uState) 都可以理解为数据正常
{
if((Y_DATA < 1024)&&(Y_PrvSSI > 3072)) // iSSI(0-1023)是这次读出的数据 m_iPrvSSI(0-1023)上一次读出的数据
{
ire_y = Y_DATA - Y_PrvSSI + 4096; // 第一种情况
printf("1 = %d, ", ire_y);
}else
if((Y_PrvSSI < 1024)&&(Y_DATA > 3072))
{
ire_y = Y_DATA - Y_PrvSSI - 4096; // 第二种情况
printf("2 = %d, ", ire_y);
}else
{
ire_y = Y_DATA - Y_PrvSSI;// 第三种情况 新数据减去老数据
printf("3 = %d, ", ire_y);
}
//------
// 计米方案:分成三种情况处理!其中256和768是自己假设的,前提条件是刷新速度每圈要5次以上
//当新数据,在0-256 老数据在768-1023时,我们就可以肯定的认为是反转 且变化值是?re = iSSI - m_iPrvSSI + 1024;
//当老数据 在0-256, 新数据在768-1023时,我们就可以肯定的认为是正转,且变化值是 ire = iSSI - m_iPrvSSI - 1024;
//其它的全部认为是 ire = iSSI - m_iPrvSSI
//ire 的正负决定方向!
Y_PrvSSI = Y_DATA;// 刷新数据,新数据替换老数据 ,为下一次做好准备
inc_y=ire_y;//保存增量数值正负决定方向
printf("增量数值 = %d, ",inc_y);
printf("状态位 = %d, ", State);
printf("数据 = %d, ", Y_DATA);
//printf("数据 = %d, ", X_DATA);
// printf("增量数值 = %d, ",inc_data);
}
}
HN3806_Ycs = 1;//使能CSN置高,为下次准备
delay_ms(200);
}
加载中...
查看其它6个回答
一周热门
更多
>
相关问题
STM32F4上I2C(在PROTEUS中模拟)调试不通的问题
6 个回答
芯片供应紧张,准备换个MCU,MM32L系列替换STM32L系列的怎么样?
7 个回答
STM32同时使用两个串口进行数据收发时数据丢包的问题
5 个回答
STM32F103串口通信死机问题
4 个回答
STM32WLE5CC连接SX1268在LoRa模式下能与 SX1278互通吗?
2 个回答
相关文章
ST公司第一款无线低功耗单片机模块有效提高物联网设计生产效率
0个评论
如何实现对单片机寄存器的访问
0个评论
通过USB用STM32片内自带Bootloader下载程序及注意事项
0个评论
欲练此功必先自宫之STM32汇编启动,放慢是为了更好的前行
0个评论
×
关闭
采纳回答
向帮助了您的知道网友说句感谢的话吧!
非常感谢!
确 认
×
关闭
编辑标签
最多设置5个标签!
STM32
保存
关闭
×
关闭
举报内容
检举类型
检举内容
检举用户
检举原因
广告推广
恶意灌水
回答内容与提问无关
抄袭答案
其他
检举说明(必填)
提交
关闭
×
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮
×
付费偷看金额在0.1-10元之间
确定
×
关闭
您已邀请
0
人回答
查看邀请
擅长该话题的人
回答过该话题的人
我关注的人
void GetSSI_Y(void)
{
u8 i = 0; //
u8 State = 0; //状态位数据
u8 Crc = 0; // 奇数或偶数标志位
int Y_DATA=0 ;//当前的角度数据( 0-1023 )
int ire_y=0 ; //增量数据,表示上次正确读的数据,和这次正确读的位置差
HN3806_Ycs = 0;//选中X编码器
__nop();__nop();
HN3806_Yclk = 0;//
delay_us(1);
HN3806_Yclk = 1;//CLK
delay_us(1);
for(i = 0; i < 12;i++)//读12次 前10位数据(12位绝对值编码器;ix < 10改成ix < 12即可)
{
HN3806_Yclk = 0;//CLK
Y_DATA <<= 1;//前10位的数据1024
if(HN3806_Ydata)//DO数据
{
Crc = !Crc;//标置位取反,数位中“1”的个数是奇数或偶数来进行校验 (初值=0)
Y_DATA |= 1;//最后位置1
}
HN3806_Yclk = 1;
delay_us(1);
}
delay_us(1);
for(i = 0; i < 5;i++)//读5次状态位标志!
{
HN3806_Yclk = 0;
State <<= 1; //后五位的数据状态位
if(HN3806_Ydata)
{
Crc = !Crc;//数位中“1”的个数是奇数或偶数来进行校验
State |= 1;//数据等于1置1
}
HN3806_Yclk = 1;
delay_us(1);
}
delay_us(1);
if(HN3806_Ydata == Crc)//最后一位校验一下,要是奇偶通不过,就认为CRC错误 ,就当这次无效
{
HN3806_Ycs = 1;//使能CSN置高,为下次准备
if((State == 16)||(State == 19))//;///&&(uState == uPrvState)) //16=10000;19=10011 表示状态位(5位uState) 都可以理解为数据正常
{
if((Y_DATA < 1024)&&(Y_PrvSSI > 3072)) // iSSI(0-1023)是这次读出的数据 m_iPrvSSI(0-1023)上一次读出的数据
{
ire_y = Y_DATA - Y_PrvSSI + 4096; // 第一种情况
printf("1 = %d, ", ire_y);
}else
if((Y_PrvSSI < 1024)&&(Y_DATA > 3072))
{
ire_y = Y_DATA - Y_PrvSSI - 4096; // 第二种情况
printf("2 = %d, ", ire_y);
}else
{
ire_y = Y_DATA - Y_PrvSSI;// 第三种情况 新数据减去老数据
printf("3 = %d, ", ire_y);
}
//------
// 计米方案:分成三种情况处理!其中256和768是自己假设的,前提条件是刷新速度每圈要5次以上
//当新数据,在0-256 老数据在768-1023时,我们就可以肯定的认为是反转 且变化值是?re = iSSI - m_iPrvSSI + 1024;
//当老数据 在0-256, 新数据在768-1023时,我们就可以肯定的认为是正转,且变化值是 ire = iSSI - m_iPrvSSI - 1024;
//其它的全部认为是 ire = iSSI - m_iPrvSSI
//ire 的正负决定方向!
Y_PrvSSI = Y_DATA;// 刷新数据,新数据替换老数据 ,为下一次做好准备
inc_y=ire_y;//保存增量数值正负决定方向
printf("增量数值 = %d, ",inc_y);
printf("状态位 = %d, ", State);
printf("数据 = %d, ", Y_DATA);
//printf("数据 = %d, ", X_DATA);
// printf("增量数值 = %d, ",inc_data);
}
}
HN3806_Ycs = 1;//使能CSN置高,为下次准备
delay_ms(200);
}
一周热门 更多>