我正在尝试让我的 STM32 板使用 SPI 控制步进电机(使用 AMIS-30543 驱动器、26M024B2B 步进电机)。我正在使用 Keil uVision 5 并在 C 中采用裸机方法。我的问题是电机没有旋转,我不确定错误隐藏在哪里。我将不胜感激输入指出我在这方面出了什么问题,以及如何解决它。感谢您的时间!
我将它连接在一起,如下所示。
STM AMIS
3.3v IOREF
GND GND
PB3 NXT
PB5 DIR
PA7 DO
PA6 DI
PA5 CLK
PA4 CS
AMIS 9v Battery
VMOT + terminal (also tried with STM 5V)
GND - terminal (also tried with STM GND)
AMIS 26M024B2B
MXP + coil 1
MXN - coil 1
MYP + coil 2
MYN - coil 2
我写的代码如下。代码尝试写入驱动器的控制寄存器,然后切换 NXT 引脚,以便电机根据其控制寄存器在每次切换时递增。为了您的方便,我已通读驱动程序的数据表并将其链接到这篇文章。
数据表上相关的部分是 SPI 接口部分(第 31 页)以及表 11 和 12 以及图 19。我的解释是,可以通过向驱动程序发送一个 8 位消息来写入驱动程序,该消息指定什么命令的类型和数据的去向,然后是 8 位数据,这些数据将填充控制寄存器。我使用以下逻辑组装了第一个数据包...
writing to CR0 -> 1000 0001 -> 0x81
writing to CR1 -> 1000 0010 -> 0x82
writing to CR2 -> 1000 0011 -> 0x83
#include "stm32f0xx.h"
#include <stdio.h>
#include <string.h>
// GPIO -> PB5 -> direction
// GPIO -> PB3 -> next
// USART2 TX -> PA2, AF1 -> transmit
// USART2 RX -> PA3, AF1 -> receive
// SPI1 NSS -> PA4 -> slave select
// SPI1 SCK -> PA5, AF0 -> clock
// SPI1 MISO -> PA6, AF0 -> master in slave out
// SPI1 MOSI -> PA7, AF0 -> master out slave in
void Clock_Init(void);
void GPIO_Init(void);
void USART2_Init(void);
void SPI1_Init(void);
void SPI1_Write(uint8_t data);
void DelayMS(int n);
int main(void)
{
Clock_Init();
GPIO_Init();
USART2_Init();
SPI1_Init();
// char str[100];
// set stepper rotation direction
GPIOB->ODR |= 0x00000020;
// apply settings to the stepper motor driver
uint8_t packet0;
uint8_t packet1;
GPIOA->ODR = 0x00000010; // write NSS high
packet0 = 0x81; // write to CR0
packet1 = 0x20; // set rotation amount
SPI1_Write(packet0); // send WRITE command & register address
SPI1_Write(packet1); // send register data
GPIOA->ODR = 0x00000000; // write NSS low
GPIOA->ODR = 0x00000010; // write NSS high
packet0 = 0x82; // write to CR1
packet1 = 0x80; // set rotation amount
SPI1_Write(packet0); // send WRITE command & register address
SPI1_Write(packet1); // send register data
GPIOA->ODR = 0x00000000; // write NSS low
GPIOA->ODR = 0x00000010; // write NSS high
packet0 = 0x83; // write to CR2
packet1 = 0x80; // set motor enable
SPI1_Write(packet0); // send WRITE command & register address
SPI1_Write(packet1); // send register data
GPIOA->ODR = 0x00000000; // write NSS low
printf("\r\nTest Interface\r\n");
while (1)
{
// printf("Command: ");
// gets(str);
// printf("\r\n");
// printf("Your command is: ");
// puts(str);
// printf("\r\n");
GPIOB->ODR ^= 0x00000008; // toggle the step signal
DelayMS(50);
}
}
// initialize device clock
void Clock_Init(void)
{
// enable port A -> bit 17, AHB
// enable port B -> bit 18, AHB
RCC->AHBENR |= 0x00060000;
// enable USART2 -> bit 17, APB1
RCC->APB1ENR |= 0x00020000;
// enable SPI1 -> bit 12, APB2
RCC->APB2ENR |= 0x00001000;
}
// initialize GPIO pins
void GPIO_Init(void)
{
// set GPIO to general purpose -> PB3, bit 6:7
// -> PB5, bit 10:11
GPIOB->MODER |= 0x00000440;
}
// initialize USART2
void USART2_Init(void)
{
// set GPIO to alternate function -> PA2, bit 4:5
// -> PA3, bit 6:7
GPIOA->MODER |= 0x000000A0;
// define alternate function -> PA2, AF1
// -> PA3, AF1
GPIOA->AFR[0] |= 0x00001100;
// set the baud rate -> 8000000 / 9600 to HEX, 9600 @ 8MHz
USART2->BRR = 0x00000341;
// enable transmit -> bit 3
// enable receive -> bit 2
USART2->CR1 = 0x0000000C;
// enable usart enable -> bit 0
USART2->CR1 |= 0x00000001;
}
// initialize SPI1
void SPI1_Init(void)
{
// clear GPIO pin -> PA5, bit 10:11
// -> PA6, bit 12:13
// -> PA7, bit 14:15
GPIOA->MODER &=~ 0x0000FC00;
// set GPIO to alternate function -> PA5, bit 10:11
// -> PA6, bit 12:13
// -> PA7, bit 14:15
GPIOA->MODER |= 0x0000A800;
// clear alternate function -> PA5, AF0
// -> PA6, AF0
// -> PA7, AF0
GPIOA->AFR[0] &=~ 0xFFF00000;
// define alternate function -> PA5, AF0
// -> PA6, AF0
// -> PA7, AF0
GPIOA->AFR[0] |= 0x00000000;
// clear GPIO pin -> PA4, bit 8:9
GPIOA->MODER &=~ 0x00000300;
// set GPIO to output -> PA4, bit 8:9
GPIOA->MODER |= 0x00000100;
// set the baud rate -> f_PCLK / 16
// set the data frame -> 8 bit
SPI1->CR1 = 0x0000031C;
SPI1->CR2 = 0x00000000;
SPI1->CR1 |= 0x00000040;
}
// delay for a given ms limit
void DelayMS(int n)
{
SysTick->LOAD = 8000 - 1;
SysTick->VAL = 0;
SysTick->CTRL = 0x00000005;
for (int i = 0; i < n; i++)
{
while ((SysTick->CTRL & 0x00010000) == 0);
}
SysTick->CTRL = 0x00000000;
}
// write 8 bits via SPI1
void SPI1_Write(uint8_t data)
{
while (!(SPI1->SR & 0x00000002)); // wait for the transfer buffer to be empty
GPIOA->BSRR = 0x00100000; // assert slave select
SPI1->DR = data; // write data
while (SPI1->SR & 0x00000080); // wait for transmission to be complete
GPIOA->BSRR = 0x00000010; // de-assert slave select
}
// write character to PC
int USART2_Write(int ch)
{
while (!(USART2->ISR & 0x00000080));
USART2->TDR = (ch & 0xFF);
return ch;
}
// read character from PC
int USART2_Read(void)
{
while (!(USART2->ISR & 0x00000020));
return USART2->RDR;
}
// implement stdin/stdout/stderr functionality
struct __FILE{int handle;};
FILE __stdin = {0};
FILE __stdout = {1};
FILE __stderr = {2};
int fgetc(FILE *f)
{
int c;
c = USART2_Read();
if (c == '\r')
{
USART2_Write(c);
c = '\n';
}
USART2_Write(c);
return c;
}
int fputc(int c, FILE *f)
{
return USART2_Write(c);
}
更新:
这是我尝试的第二次迭代。我浏览了更多文档和示例,并试图从驱动程序那里得到响应,以证明我正确地写入了驱动程序的寄存器。到目前为止,我没有得到回应。在这个时候,尝试翻译这些库对我来说太困难和困惑了(也许我遗漏了一些明显的东西?),所以我仍然采用简单的方法。
非常感谢您迄今为止的帮助,@ralf htp。
更新:
我已经根据此处和此处设置的说明使用上述库设置了 Arduino Uno 。步进电机不旋转。我换了另一个驱动器,步进电机仍然没有旋转。我可以有两个有问题的驱动程序吗?
#include "stm32f0xx.h"
#include <stdio.h>
#include <string.h>
void setDirection(int cw);
void Step(void);
void ssHigh(void);
void ssLow(void);
void SPI1_Reset(void);
void SPI1_Write(uint8_t address, uint8_t data);
uint8_t SPI1_Read(uint8_t address);
void SPI1_Send(uint8_t packet);
uint8_t SPI1_Receive(void);
void DelayMS(int n);
void Clock_Init(void);
void GPIO_Init(void);
void USART2_Init(void);
void SPI1_Init(void);
void printHex(uint8_t data);
int main(void)
{
// initialize
Clock_Init();
GPIO_Init();
USART2_Init();
SPI1_Init();
// set NXT and DIR pins low
GPIOB->ODR = 0x00000000;
// short delay
DelayMS(100);
// reset driver settings
SPI1_Reset();
// set current value (mA)
SPI1_Write(0x11, 0x11);
// set step mode
SPI1_Write(0x19, 0x02);
// enable motor outputs(?)
SPI1_Write(0x13, 0x80);
// check register
uint8_t response = SPI1_Read(0x09);
printHex(response);
// inifinite loop
while (1)
{
// step cw(?) 20 times
setDirection(0);
for (unsigned int i = 0; i < 20; i++)
{
Step();
//printf("spin cw\r\n");
}
DelayMS(300);
// step ccw(?) 20 times
setDirection(1);
for (unsigned int i = 0; i < 20; i++)
{
Step();
//printf("spin ccw\r\n");
}
DelayMS(300);
}
}
void setDirection(int cw)
{
if (cw == 0)
{
GPIOB->BSRR |= 0x00000020;
}
else if (cw == 1)
{
GPIOB->BSRR |= 0x00200000;
}
}
void Step(void)
{
GPIOB->BSRR |= 0x00000008;
DelayMS(3);
GPIOB->BSRR |= 0x00080000;
DelayMS(3);
DelayMS(500);
}
void ssHigh(void)
{
GPIOA->BSRR |= 0x00000010;
}
void ssLow(void)
{
GPIOA->BSRR |= 0x00100000;
}
void SPI1_Reset(void)
{
uint8_t addressWR = 0x10;
uint8_t addressCR0 = 0x11;
uint8_t addressCR1 = 0x12;
uint8_t addressCR2 = 0x13;
uint8_t addressCR3 = 0x19;
uint8_t dataWR = 0xF8;
uint8_t dataCR0 = 0x06;
uint8_t dataCR1 = 0xC2;
uint8_t dataCR2 = 0x00;
uint8_t dataCR3 = 0x00;
SPI1_Write(addressWR, dataWR);
SPI1_Write(addressCR0, dataCR0);
SPI1_Write(addressCR1, dataCR1);
SPI1_Write(addressCR2, dataCR2);
SPI1_Write(addressCR3, dataCR3);
}
void SPI1_Write(uint8_t address, uint8_t data)
{
ssHigh(); // set CS high
ssLow(); // set CS low
SPI1_Send(address); // send the register address
SPI1_Send(data); // send the register data
ssHigh(); // set CS high
ssLow(); // set CS low
}
uint8_t SPI1_Read(uint8_t address)
{
ssHigh(); // set CS high
ssLow(); // set CS low
SPI1_Send(address);
uint8_t output = SPI1_Receive();
ssHigh(); // set CS high
ssLow(); // set CS low
return output;
}
void SPI1_Send(uint8_t packet)
{
while (!(SPI1->SR & 0x00000002)); // wait for TX buffer to be empty
SPI1->DR = packet;
while (SPI1->SR & 0x00000080); // wait for TX to be complete
}
uint8_t SPI1_Receive(void)
{
while (SPI1->SR & 0x00000001); // wait for RX buffer to be empty
return SPI1->DR;
}
int USART2_Write(int ch)
{
while (!(USART2->ISR & 0x00000080));
USART2->TDR = (ch & 0xFF);
return ch;
}
int USART2_Read(void)
{
while (!(USART2->ISR & 0x00000020));
return USART2->RDR;
}
void DelayMS(int n)
{
SysTick->LOAD = 8000 - 1;
SysTick->VAL = 0;
SysTick->CTRL = 0x00000005;
for (int i = 0; i < n; i++)
{
while ((SysTick->CTRL & 0x00010000) == 0);
}
SysTick->CTRL = 0x00000000;
}
void Clock_Init(void)
{
// enable port A -> bit 17, AHB
// enable port B -> bit 18, AHB
RCC->AHBENR |= 0x00060000;
// enable USART2 -> bit 17, APB1
RCC->APB1ENR |= 0x00020000;
// enable SPI1 -> bit 12, APB2
RCC->APB2ENR |= 0x00001000;
}
void GPIO_Init(void)
{
// set GPIO to general purpose -> PB3, bit 6:7
// -> PB5, bit 10:11
GPIOB->MODER |= 0x00000440;
}
void USART2_Init(void)
{
// set GPIO to alternate function -> PA2, bit 4:5
// -> PA3, bit 6:7
GPIOA->MODER |= 0x000000A0;
// define alternate function -> PA2, AF1
// -> PA3, AF1
GPIOA->AFR[0] |= 0x00001100;
// set the baud rate -> 8000000 / 9600 to HEX, 9600 @ 8MHz
USART2->BRR = 0x00000341;
// enable transmit -> bit 3
// enable receive -> bit 2
USART2->CR1 = 0x0000000C;
// enable usart enable -> bit 0
USART2->CR1 |= 0x00000001;
}
void SPI1_Init(void)
{
// clear GPIO pin -> PA5, bit 10:11
// -> PA6, bit 12:13
// -> PA7, bit 14:15
GPIOA->MODER &=~ 0x0000FC00;
// set GPIO to alternate function -> PA5, bit 10:11
// -> PA6, bit 12:13
// -> PA7, bit 14:15
GPIOA->MODER |= 0x0000A800;
// clear alternate function -> PA5, AF0
// -> PA6, AF0
// -> PA7, AF0
GPIOA->AFR[0] &=~ 0xFFF00000;
// define alternate function -> PA5, AF0
// -> PA6, AF0
// -> PA7, AF0
GPIOA->AFR[0] |= 0x00000000;
// clear GPIO pin -> PA4, bit 8:9
GPIOA->MODER &=~ 0x00000300;
// set GPIO to output -> PA4, bit 8:9
GPIOA->MODER |= 0x00000100;
// set the baud rate -> f_PCLK / 8
// set the data frame -> 8 bit
SPI1->CR1 = 0x00000314;
SPI1->CR2 = 0x00000000;
SPI1->CR1 |= 0x00000040;
}
void printHex(uint8_t data)
{
printf("0x%02x", data);
}
// implement stdin/stdout/stderr functionality
struct __FILE{int handle;};
FILE __stdin = {0};
FILE __stdout = {1};
FILE __stderr = {2};
int fgetc(FILE *f)
{
int c;
c = USART2_Read();
if (c == '\r')
{
USART2_Write(c);
c = '\n';
}
USART2_Write(c);
return c;
}
int fputc(int c, FILE *f)
{
return USART2_Write(c);
}
更新:我已经浏览了 ralf htp 提到的库,并尽我所能翻译了它们。我现在可以通过 SPI 从驱动程序获得响应,但我得到的唯一值是“0xFF”。在一个实例中,我得到了预期的控制寄存器响应,但它没有重复,我正在尝试重新创建确切的设置(尽管我很确定我已经有了)。新代码如下。
#include "stm32f0xx.h"
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
// initializations
void Clock_Init(void);
void USART2_Init(void);
void SPI1_Init(void);
// spi1
void csHigh(void);
void csLow(void);
void selectChip(void);
void deselectChip(void);
uint8_t transfer(uint8_t value);
uint8_t readReg(uint8_t address);
void writeReg(uint8_t address, uint8_t value);
void writeWR(void);
void writeCR0(void);
void writeCR1(void);
void writeCR2(void);
void writeCR3(void);
// driver functionality
void init(void);
bool verifySettings(void);
void applySettings(void);
void resetSettings(void);
void enableDriver(void);
void disableDriver(void);
void setCurrentMilliamps(uint16_t current);
uint16_t readPosition(void);
void setDirection(bool value);
void setStepMode(uint8_t mode);
void sleep(void);
void sleepStop(void);
void stepOnRisingEdge(void);
void stepOnFallingEdge(void);
void setPwmFrequencyDouble(void);
void setPwmFrequencyDefault(void);
void setPwmJitterOn(void);
void setPwmJitterOff(void);
void setPwmSlope(uint8_t emc);
void setSlaGainDefault(void);
void setSlaGainHalf(void);
void setSlaTransparencyOff(void);
void setSlaTransparencyOn(void);
uint8_t readStatusReg(uint8_t address);
void nxtHigh(void);
void nxtLow(void);
void dirHigh(void);
void dirLow(void);
void Step(void);
// general functionality
void DelayTicks(uint32_t ticks);
void DelayMS(int n);
void DelayUS(uint32_t n);
void printHex(uint8_t data);
// ENUMERATIONS: start
enum stepMode
{
MicroStep128 = 128,
MicroStep64 = 64,
MicroStep32 = 32,
MicroStep16 = 16,
MicroStep8 = 8,
MicroStep4 = 4,
MicroStep2 = 2,
MicroStep1 = 1,
CompensatedHalf = MicroStep2,
CompensatedFullTwoPhaseOn = MicroStep1,
CompensatedFullOnePhaseOn = 200,
UncompensatedHalf = 201,
UncompensatedFull = 202,
};
enum nonLatchedStatusFlag
{
OPENY = (1 << 2),
OPENX = (1 << 3),
WD = (1 << 4),
CPFAIL = (1 << 5),
TW = (1 << 6)
};
enum latchedStatusFlag
{
OVCXNB = (1 << 3),
OVCXNT = (1 << 4),
OVCXPB = (1 << 5),
OVCXPT = (1 << 6),
TSD = (1 << 10),
OVCYNB = (1 << 11),
OVCYNT = (1 << 12),
OVCYPB = (1 << 13),
OVCYPT = (1 << 14)
};
enum regAddr
{
WR = 0x00,
CR0 = 0x10,
CR1 = 0x20,
CR2 = 0x30,
CR3 = 0x90,
SR0 = 0x40,
SR1 = 0x50,
SR2 = 0x60,
SR3 = 0x70,
SR4 = 0xA0
};
// ENUMERATIONS: end
// declarations
uint8_t wr;
uint8_t cr0;
uint8_t cr1;
uint8_t cr2;
uint8_t cr3;
// PA2 / D1 -> USART2 TX -> transmit to PC
// PA3 / D2 -> USART2 RX -> receive from PC
// PA4 / A2 -> CS -> chip select (official)
// PA5 / D13 -> SCK -> clock source
// PA6 / D12 -> MISO -> master in slave out
// PA7 / D11 -> MOSI -> master out slave in
// PB3 / D3 -> NXT -> next step
// PB4 / D5 -> DIR -> direction
// PC7 / D9 -> CS -> chip select (unofficial)
int main(void)
{
Clock_Init();
USART2_Init();
SPI1_Init();
init();
nxtLow();
dirLow();
DelayMS(1);
resetSettings();
setCurrentMilliamps(132);
setStepMode(64);
enableDriver();
printHex(readReg(CR2));
printf("\r\n");
while (1)
{
dirHigh();
for (unsigned int i = 0; i < 64; i++)
{
Step();
}
DelayMS(300);
dirLow();
for (unsigned int i = 0; i < 64; i++)
{
Step();
}
DelayMS(300);
}
}
//
//
//
// INITIALIZATIONS: start
void Clock_Init(void)
{
// enable ports -> port A, AHB, bit 17
// -> port B, AHB, bit 18
// -> port C, AHB, bit 19
RCC->AHBENR = 0x000E0000;
// enable USART2 -> bit 17, APB1
RCC->APB1ENR = 0x00020000;
// enable SPI1 -> bit 12, APB2
RCC->APB2ENR = 0x00001000;
}
void USART2_Init(void)
{
// define GPIO pins -> PA2, alternate function
// -> PA3, alternate function
GPIOA->MODER = 0x000000A0;
// define alternate functions -> PA2, AF1, USART2 TX
// -> PA3, AF1, USART2 RX
GPIOA->AFR[0] = 0x00001100;
// set baud rate -> 8000000 / 9600 to HEX = 9600 @ 8MHz
USART2->BRR = 0x00000341;
// format usart -> enable tx, bit 3
// -> enable rx, bit 2
USART2->CR1 = 0x0000000C;
// enable usart -> enable ue, bit 0
USART2->CR1 |= 0x00000001;
}
void SPI1_Init(void)
{
// define GPIO pins -> PC7, output
// -> PB3, output
// -> PB4, output
// -> PA4, alternate function
// -> PA5, alternate function
// -> PA6, alternate function
// -> PA7, alternate function
GPIOC->MODER = 0x00004000;
GPIOB->MODER = 0x00000140;
GPIOA->MODER |= 0x0000AA00;
// define alternate functions -> PA4, AF0, SPI1 CS / NSS
// -> PA5, AF0, SPI1 SCK
// -> PA6, AF0, SPI1 MISO
// -> PA7, AF0, SPI1 MOSI
GPIOA->AFR[0] |= 0x00000000;
// format spi -> set br, bit 3-5
// -> enable ssm, bit 9
// -> enable ssi, bit 9
// -> set mstr, bit 2
SPI1->CR1 = 0x00000314;
// format spi -> set ds, bit 8-11
SPI1->CR2 = 0x00000700;
// enable spi -> enable spe
SPI1->CR1 |= 0x00000040;
}
// INITIALIZATIONS: end
//
//
// USART2: start
int USART2_Write(int ch)
{
while (!(USART2->ISR & 0x00000080));
USART2->TDR = (ch & 0xFF);
return ch;
}
int USART2_Read(void)
{
while (!(USART2->ISR & 0x00000020));
return USART2->RDR;
}
// USART2: end
//
//
// SPI1: start
void csHigh(void)
{
GPIOC->BSRR = 0x00000080;
GPIOA->BSRR = 0x00000010;
}
void csLow(void)
{
GPIOC->BSRR = 0x00800000;
GPIOA->BSRR = 0x00100000;
}
void selectChip(void)
{
csLow();
// begin spi transaction, unnecessary?
}
void deselectChip(void)
{
csHigh();
// end spi transaction, unnecessary?
// stabilization delay
DelayUS(3);
}
uint8_t transfer(uint8_t value)
{
// while (!(SPI1->SR & 0x00000002)); // wait for TX buffer to be empty
// SPI1->DR = value; // start the transmission
// while (!(SPI1->SR & 0x00000080)); // wait for TX to be complete
// return SPI1->DR; // return the received byte
while (!(SPI1->SR & SPI_SR_TXE));
SPI1->DR = value;
while (!(SPI1->SR & SPI_SR_BSY));
return SPI1->DR;
}
uint8_t readReg(uint8_t address)
{
selectChip();
transfer(address & 0b11111);
uint8_t dataOut = transfer(0);
deselectChip();
return dataOut;
}
void writeReg(uint8_t address, uint8_t value)
{
selectChip();
transfer(0x80 | (address & 0b11111));
transfer(value);
deselectChip();
}
void writeWR(void)
{
writeReg(WR, wr);
}
void writeCR0(void)
{
writeReg(CR0, cr0);
}
void writeCR1(void)
{
writeReg(CR1, cr1);
}
void writeCR2(void)
{
writeReg(CR2, cr2);
}
void writeCR3(void)
{
writeReg(CR3, cr3);
}
// SPI1: end
//
//
// DRIVER FUNCTIONALITY: start
void init(void)
{
csHigh();
}
bool verifySettings(void)
{
return readReg(WR) == wr && readReg(CR0) == cr0 && readReg(CR1) == cr1 && readReg(CR2) == cr2 && readReg(CR3) == cr3;
}
void applySettings(void)
{
writeReg(CR2, cr2);
writeReg(WR, wr);
writeReg(CR0, cr0);
writeReg(CR1, cr1);
writeReg(CR3, cr3);
}
void resetSettings(void)
{
wr = cr0 = cr1 = cr2 = cr3 = 0;
applySettings();
}
void enableDriver(void)
{
cr2 |= 0b10000000;
applySettings();
}
void disableDriver(void)
{
cr2 &= ~0b10000000;
applySettings();
}
void setCurrentMilliamps(uint16_t current)
{
uint8_t code = 0;
if (current >= 3000) { code = 0b11001; }
else if (current >= 2845) { code = 0b11000; }
else if (current >= 2700) { code = 0b10111; }
else if (current >= 2440) { code = 0b10110; }
else if (current >= 2240) { code = 0b10101; }
else if (current >= 2070) { code = 0b10100; }
else if (current >= 1850) { code = 0b10011; }
else if (current >= 1695) { code = 0b10010; }
else if (current >= 1520) { code = 0b10001; }
else if (current >= 1405) { code = 0b10000; }
else if (current >= 1260) { code = 0b01111; }
else if (current >= 1150) { code = 0b01110; }
else if (current >= 1060) { code = 0b01101; }
else if (current >= 955) { code = 0b01100; }
else if (current >= 870) { code = 0b01011; }
else if (current >= 780) { code = 0b01010; }
else if (current >= 715) { code = 0b01001; }
else if (current >= 640) { code = 0b01000; }
else if (current >= 585) { code = 0b00111; }
else if (current >= 540) { code = 0b00110; }
else if (current >= 485) { code = 0b00101; }
else if (current >= 445) { code = 0b00100; }
else if (current >= 395) { code = 0b00011; }
else if (current >= 355) { code = 0b00010; }
else if (current >= 245) { code = 0b00001; }
cr0 = (cr0 & 0b11100000) | code;
writeCR0();
}
uint16_t readPosition(void)
{
uint8_t sr3 = readStatusReg(SR3);
uint8_t sr4 = readStatusReg(SR4);
return ((uint16_t)sr3 << 2) | (sr4 & 3);
}
void setDirection(bool value)
{
if (value)
{
cr1 |= 0x80;
}
else
{
cr1 &= ~0x80;
}
writeCR1();
}
int getDirection(void)
{
return cr1 >> 7 & 1;
}
void setStepMode(uint8_t mode)
{
uint8_t esm = 0b000;
uint8_t sm = 0b000;
switch (mode)
{
case MicroStep32: sm = 0b000; break;
case MicroStep16: sm = 0b001; break;
case MicroStep8: sm = 0b010; break;
case MicroStep4: sm = 0b011; break;
case CompensatedHalf: sm = 0b100; break;
case UncompensatedHalf: sm = 0b101; break;
case UncompensatedFull: sm = 0b110; break;
case MicroStep128: esm = 0b001; break;
case MicroStep64: esm = 0b010; break;
case CompensatedFullTwoPhaseOn: esm = 0b011; break;
case CompensatedFullOnePhaseOn: esm = 0b100; break;
}
cr0 = (cr0 & ~0b11100000) | (sm << 5);
cr3 = (cr3 & ~0b111) | esm;
writeCR0();
writeCR3();
}
void sleep(void)
{
cr2 |= (1 << 6);
applySettings();
}
void sleepStop(void)
{
cr2 &= ~(1 << 6);
applySettings();
}
void stepOnRisingEdge(void)
{
cr1 &= ~0b01000000;
writeCR1();
}
void stepOnFallingEdge(void)
{
cr1 |= 0b01000000;
writeCR1();
}
void setPwmFrequencyDouble(void)
{
cr1 |= (1 << 3);
writeCR1();
}
void setPwmFrequencyDefault(void)
{
cr1 &= ~(1 << 3);
writeCR1();
}
void setPwmJitterOn(void)
{
cr1 |= (1 << 2);
writeCR1();
}
void setPwmJitterOff(void)
{
cr1 &= ~(1 << 2);
writeCR1();
}
void setPwmSlope(uint8_t emc)
{
cr1 = (cr1 & ~0b11) | (emc & 0b11);
writeCR1();
}
void setSlaGainDefault(void)
{
cr2 &= ~(1 << 5);
applySettings();
}
void setSlaGainHalf(void)
{
cr2 |= (1 << 5);
applySettings();
}
void setSlaTransparencyOff(void)
{
cr2 &= ~(1 << 4);
applySettings();
}
void setSlaTransparencyOn(void)
{
cr2 |= (1 << 4);
applySettings();
}
uint8_t readStatusReg(uint8_t address)
{
return readReg(address) & 0x7F;
}
void nxtHigh(void)
{
GPIOB->BSRR |= 0x00000008;
}
void nxtLow(void)
{
GPIOB->BSRR |= 0x00080000;
}
void dirHigh(void)
{
GPIOB->BSRR |= 0x00000010;
}
void dirLow(void)
{
GPIOB->BSRR |= 0x00100000;
}
void Step(void)
{
nxtHigh();
DelayUS(3);
nxtLow();
DelayUS(3);
DelayUS(1000);
}
// DRIVER FUNCTIONALITY: end
//
//
// GENERAL FUNCTIONALITY: start
void DelayTicks(uint32_t ticks)
{
SysTick->LOAD = ticks;
SysTick->VAL = 0;
SysTick->CTRL = SysTick_CTRL_ENABLE_Msk;
while ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0);
SysTick->CTRL = 0;
}
void DelayMS(int n)
{
SysTick->LOAD = 8000 - 1;
SysTick->VAL = 0;
SysTick->CTRL = 0x00000005;
for (int i = 0; i < n; i++)
{
while ((SysTick->CTRL & 0x00010000) == 0);
}
SysTick->CTRL = 0x00000000;
}
void DelayUS(uint32_t n)
{
DelayTicks((n * 1000));
}
void printHex(uint8_t data)
{
printf("0x%02x", data);
}
// GENERAL FUNCTIONALITY: end
//
//
// INTERFACE FUNCTIONALITY: start
struct __FILE{int handle;};
FILE __stdin = {0};
FILE __stdout = {1};
FILE __stderr = {2};
int fgetc(FILE *f)
{
int c;
c = USART2_Read();
if (c == '\r')
{
USART2_Write(c);
c = '\n';
}
USART2_Write(c);
return c;
}
int fputc(int c, FILE *f)
{
return USART2_Write(c);
}