最近拿到一个绝对式编码器基于SSI协议的,需求是把它反馈的位置信息读取出来做误差分析.
查了下学习了各位前辈的经验,比较了 spi\iic\ssi的区别.
SSI的时序图如下:
方法一. 模拟io口的方式,进行读取
硬件接线:
编码器一共6跟线,VCC和GND外部5V供电,关于D+、D-和C+、C-属于差分IO,由于单片机属于TTL电平,差分信号是485电平,然后淘宝买了两个电平互转模块(这个模块是单通道的,时钟和数据各需要一个,所以买了两个),由于硬件控制流向的,所以使用很简单基本不用找说明文件,切记RX连接DATA路模块、TX要连接CLK路模块,数据传输过程中,时钟太快,指示灯几乎看不出来。
示波器看下信号:
T=6.8us, t1=2.96us, t2=720ns,MSB=0.72us, t3=15.3us
软件代码:
void PIN_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* Enable GPIOC clock */
__HAL_RCC_GPIOA_CLK_ENABLE();
//PA6 CLK
GPIO_InitStructure.Pin = GPIO_PIN_6;
GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;//推挽输出
GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;//高速
GPIO_InitStructure.Pull = GPIO_PULLUP;//wue clk拉高
HAL_GPIO_Init(GPIOA, &GPIO_InitStructure);
//PA5 DATA
GPIO_InitStructure.Pin = GPIO_PIN_5;
GPIO_InitStructure.Mode = GPIO_MODE_INPUT;
GPIO_InitStructure.Pull = GPIO_PULLUP;
HAL_GPIO_Init(GPIOA, &GPIO_InitStructure);
}
//寤舵椂鍑芥暟
void Delay(unsigned int time)
{
unsigned int i;
i = time*4;
while(i--);
}
#define CLC PAout(6)
#define DAT PAin(5)
//璇绘暟鎹?
unsigned int ReadAngleValue(void)
{
unsigned int suc=0,suc1=0,suc2=0;
unsigned char i,j;
int8_t SES[]={0};
CLC=0;
delay_us(2);
for(i=0;i<36;i++)
{
CLC=1;
delay_us(5);
if(DAT)
SES[i]=1;
else
SES[i]=0;
CLC=0;
delay_us(5);
}
CLC=1;
delay_us(15);
// for(j=0;j<26;j++)
for(j=0;j<32;j++)//26 28个 32个
{
suc+=SES[j]<<(25-j);//编码器数据是高位在前,需要移下位
//suc+=SES[j]<<(31-j);
}
suc = (suc>>8)0x0FFFFF;
suc1=(float)suc*360/262144;
suc=0;
return suc1;
}
int main(void)
{
GPIO_InitTypeDef GPIO_Initure;
HAL_Init(); //初始化HAL库
Stm32_Clock_Init(RCC_PLL_MUL9); //设置时钟,72M
PIN_Init();
while(1)
{
temp = ReadAngleValue();
Delay1(0x7FFFFF);
}
}
得到角度值: