分享一下AS5145的代码,希望大家用到这片子的时候少走一些弯路,采用51单片机来进行操作,下面是最简单的读写0~4095的值,清0的话在一下函数,自己读懂调用就可以了
- #include <STC12C5630AD.H>
- sbit CSN = P3^7;
- sbit CLK = P1^0;
- sbit DO = P1^1;
- sbit PROG = P1^2;
- //Definitions: Macro
- #define CLEAR_CSN() do { CSN = 0; } while(0)
- #define SET_CSN() do { CSN = 1; } while(0)
- #define CLEAR_CLK() do { CLK = 0; } while(0)
- #define SET_CLK() do { CLK = 1; } while(0)
- #define CLEAR_PROG() do { PROG = 0; } while(0)
- #define SET_PROG() do { PROG = 1; } while(0)
- #define PROG_HIGH_IMPED() do { PROG = 1;} while(0) // Pushpull disabled, Hi-Z
- #define PROG_LOW_IMPED() do { } while(0) // Pushpull enabled
- uint32 RD_as5311_data(void)
- {
- uint32 Data=0;
- uint8 i=0;
- bit flags=0;
- //start
- CLK=1;
- CSN=1;
- delay_500ns();
- CSN=0;
- delay_500ns();
- delay_500ns();
- //read D0-D17
- for(i=0;i<17;i++)
- {
- CLK=0;
- delay_500ns();
- CLK=1;
- delay_500ns();
- Data=(Data<<1)|DO;
- if(flags==DO) flags=0;
- else flags=1;
- }
- CLK=0;
- delay_500ns();
- CLK=1;
- delay_500ns();
-
- if(DO!=flags)
- Data=0x10000000;
- //stop
- CSN=1;
- delay_500ns();
- return (Data);
- }
- uint16 ssi_read(void)
- {
- uint32 rd_data=0;
- rd_data=RD_as5311_data();
- return((rd_data%0x20000)/0x20);
- }
- void main(void)
- {
- uchar digit[10] = {'0','1','2','3','4','5','6','7','8','9'};
- uchar buf[4]=0,i=0;
- UART_Init();
- while(1)
- {
- P1 &= ~(1 << 2);
- P0 &= ~(1 << 1);
- angle = ssi_read();//读取0~4096的值
-
- buf[0] = angle / 1000;
- buf[1] = angle % 1000 / 100;
- buf[2] = angle % 1000 % 100 / 10;
- buf[3] = angle % 10;
-
- for(i=0;i<4;i++)
- {
- SBUF = digit[buf[i]];
- while(TI==0);TI=0;
- }
- }
- }
复制代码
以下的函数可以实现清0,OTP编程,读懂调用就可以了
- void delay_500ns(void)
- {
- uint8 x=15;
- while(x--);
- }
- uint32 RD_as5311_data(void)
- {
- uint32 Data=0;
- uint8 i=0;
- bit flags=0;
- //start
- CLK=1;
- CSN=1;
- delay_500ns();
- CSN=0;
- delay_500ns();
- delay_500ns();
- //read D0-D17
- for(i=0;i<17;i++)
- {
- CLK=0;
- delay_500ns();
- CLK=1;
- delay_500ns();
- Data=(Data<<1)|DO;
- if(flags==DO) flags=0;
- else flags=1;
- }
- CLK=0;
- delay_500ns();
- CLK=1;
- delay_500ns();
-
- if(DO!=flags)
- Data=0x10000000;
- //stop
- CSN=1;
- delay_500ns();
- return (Data);
- }
- // Utility functions
- void pptrimDelay(volatile unsigned int value)
- {
- for(value; value>0; value--);
- {
- unsigned char foo = 30;
- while(foo--);
- }
- }
- static void clkPulses(unsigned char num)
- {
- unsigned char i;
- for(i = 0; i < num; i++)
- {
- SET_CLK(); pptrimDelay(PPTRIMDelay);
- CLEAR_CLK(); pptrimDelay(PPTRIMDelay);
- }
- }
- unsigned char reversebits(unsigned char value) // Endian switch
- {
- unsigned char i=0, result=0;
- while (i<8)
- {
- result += (value<<i)&0x80;
- if (i<7) result = result >> 1;
- i++;
- }
- return result;
- }
- //Setup and exit conditions
- static void setupCondition()
- {
- CLEAR_CSN();
- pptrimDelay(PPTRIMDelay);
- CLEAR_CLK();
- pptrimDelay(PPTRIMDelay);
- SET_PROG();
- pptrimDelay(PPTRIMDelay);
- SET_CSN();
- pptrimDelay(PPTRIMDelay);
- CLEAR_CSN();
- pptrimDelay(PPTRIMDelay);
- SET_CLK();
- pptrimDelay(PPTRIMDelay);
- CLEAR_CLK();
- pptrimDelay(PPTRIMDelay);
- }
- static void exitCondition()
- {
- PROG_LOW_IMPED();
- pptrimDelay(PPTRIMDelay);
- CLEAR_CSN();
- pptrimDelay(PPTRIMDelay);
- SET_CLK();
- pptrimDelay(PPTRIMDelay);
- CLEAR_CLK();
- pptrimDelay(PPTRIMDelay);
- SET_CLK();
- pptrimDelay(PPTRIMDelay);
- SET_CSN();
- pptrimDelay(PPTRIMDelay);
- CLEAR_PROG();
- pptrimDelay(PPTRIMDelay);
- }
- static void operationModeRead()
- {
- CLEAR_PROG();
- pptrimDelay(PPTRIMDelay);
- SET_CLK();
- pptrimDelay(PPTRIMDelay);
- SET_CSN();
- pptrimDelay(PPTRIMDelay);
- CLEAR_CLK();
- pptrimDelay(PPTRIMDelay);
- clkPulses(1);
- PROG_HIGH_IMPED();
- }
- static void operationModeWrite()
- {
- SET_CSN();
- pptrimDelay(PPTRIMDelay);
- clkPulses(3);
- }
-
- void pptrimRead(unsigned char *buffer, unsigned char num_bits)
- {
- xdata unsigned char current_byte = 0;
- xdata unsigned char current_bit = 0;
- xdata unsigned char temp = 0;
- if(!num_bits) return;
- current_byte = num_bits >> 3;
- current_bit = num_bits & ~0x07;
- setupCondition();
- operationModeRead();
- clkPulses(1); // position the first bit to read
- //-- read OTP Data --
- temp = 0;
- temp += (PROG) ? 1 : 0;
- for(current_bit = num_bits; current_bit; current_bit--)
- {
- if(((current_bit - 1) & 0x07) == 0)
- {
- buffer[current_bit >> 3] = temp;
- temp = 0;
- }
- if (current_bit)
- {
- temp <<= 1;
- SET_CLK();
- pptrimDelay(200);
- temp += (PROG) ? 1 : 0;
- CLEAR_CLK();
- pptrimDelay(200);
- }
- }
- exitCondition();
- }
- void pptrimWrite(unsigned char *buffer, unsigned char num_bits)
- {
- xdata unsigned char *current_byte;
- xdata unsigned char current_bit = 0;
- xdata unsigned char temp = 0;
- current_byte = buffer + ((num_bits-1)>>3);
- temp = *current_byte;
- if(num_bits % 8)
- temp <<= 8 - (num_bits % 8);
- setupCondition();
- operationModeWrite();
- //-- send OTP Data
- for(current_bit = num_bits; current_bit; current_bit--)
- {
- if(temp & 0x80)
- SET_PROG();
- else
- CLEAR_PROG();
- pptrimDelay(100);
- SET_CLK();
- pptrimDelay(300);// delay, tzapp=2us(typ.)
- CLEAR_CLK();
- pptrimDelay(PPTRIMDelay);
- temp <<= 1;
- if(((current_bit-1) & 0x07) == 0)
- {
- temp = *(--current_byte);
- }
- }
- SET_PROG();
- pptrimDelay(100);
- clkPulses(1); // data latched
- // END OTP-Write
- exitCondition();
- }
- uint16 ssi_read(void)
- {
- uint32 rd_data=0;
- rd_data=RD_as5311_data();
- return((rd_data%0x20000)/0x20);
- }
- void AS5145set_zero_last(void)
- {
- unsigned char PPTrimBuffer[7];
- EEPROM_read_n(EepromDataAddr,EepromData,3);
- pptrimRead(PPTrimBuffer, 54);
- PPTrimBuffer[4]=EepromData[0];
- PPTrimBuffer[5]=EepromData[1];
- pptrimDelay(100);
- // if(((PPTrimBuffer[4]&0x03)==0) && ((PPTrimBuffer[5]&0x80)==0))
- pptrimWrite(PPTrimBuffer, 54);
- }
- void AS5145set_zero(void)
- {
- unsigned char PPTrimBuffer[7];
- unsigned char ZeroTemp;
- unsigned short angle;
- uint32 rd_data=0;
- EEPROM_SectorErase(EepromDataAddr);//擦除Eeprom
- pptrimRead(PPTrimBuffer, 54);
- PPTrimBuffer[4]=0;
- PPTrimBuffer[5]=0;
- EepromData[0] = PPTrimBuffer[4];//保存在写入Eeprom的数据当中
- EepromData[1] = PPTrimBuffer[5];
- pptrimWrite(PPTrimBuffer, 54);
- pptrimDelay(100);
- // Step 1: Read the 18 bit SSI value from the AS5145 (AS5140 uses 16 bit)
- rd_data=RD_SSI_data();//ssiRead(SSIBuffer, 18);
- angle =(rd_data%0x20000)/0x20;
- // angle =0x0c00;
- pptrimDelay(100);
- // Step 2: Read the 54 PPTRIM OTP bits from the AS5145
- // Step 3: Write the actual angle to the zero position field of the OTP bits
- ZeroTemp=(angle/0x100)%0x10; //GET 4 MSB
- ZeroTemp = reversebits(ZeroTemp);
- PPTrimBuffer[4] = ZeroTemp;
- // Byte_Program(0X0001, PPTrimBuffer[4]);
- pptrimDelay(100);
- ZeroTemp=angle%0x100; //GET 8 LSB
- ZeroTemp = reversebits(ZeroTemp);
- PPTrimBuffer[5] = ZeroTemp;
- // Byte_Program(0X0002, PPTrimBuffer[5]);
- EepromData[0] = PPTrimBuffer[4];//保存在写入Eeprom的数据当中
- EepromData[1] = PPTrimBuffer[5];//保存在写入Eeprom的数据当中
- EEPROM_SectorErase(EepromDataAddr);//擦除Eeprom
- EEPROM_write_n(EepromDataAddr,EepromData,3);//写入Eeprom的数据当中
- pptrimDelay(100);
- // Step 4: Write back the 54 PPTRIM OTP bits containing the Zero position (which is the actual angle) to the AS5145
- pptrimWrite(PPTrimBuffer, 54);
- }
复制代码
|