gpt4 book ai didi

通过 SPI 使用 STM32F030R8 控制 AMIS-30543

转载 作者:行者123 更新时间:2023-12-04 10:37:09 26 4
gpt4 key购买 nike

我正在尝试让我的 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 引脚,以便电机根据其控制寄存器在每次切换时递增。我已经阅读了驱动程序的数据表并拥有 linked为了您的方便,它到这个帖子。

数据表上相关的部分是 SPI 接口(interface)部分(第 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。

更新:

我已经按照 here 的说明设置了一个 Arduino Uno和 here与上述库。步进电机不旋转。我换了另一个驱动器,步进电机仍然没有旋转。我可以有两个有问题的驱动程序吗?

#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);
}

最佳答案

您没有正确设置 AMIS-30543-D。要准确配置 AMIS-30543-D,您必须使用带有配置信息的 SPI 写入多个寄存器(smesm、...)AMIS-30543-D 的完整驱动程序位于 https://pololu.github.io/amis-30543-arduino/_a_m_i_s30543_8h_source.html必须写入的寄存器在代码部分中指定

 void writeWR()
554 {
555 driver.writeReg(WR, wr);
556 }
557
559 void writeCR0()
560 {
561 driver.writeReg(CR0, cr0);
562 }
563
565 void writeCR1()
566 {
567 driver.writeReg(CR1, cr1);
568 }
569
571 void writeCR3()
572 {
573 driver.writeReg(CR3, cr3);
574 }

这是 Arduino C,但是您可以轻松地将其转换为通用 C。

通过 SPI 写入寄存器的内容以及您可以在 AMIS-30543 的数据表/引用手册中看到的原因: https://www.onsemi.com/pub/Collateral/AMIS-30543-D.PDF

IE。设置步进模式,数据表第 12-24 页
void setStepMode(uint8_t mode)
341 {
342 // Pick 1/32 micro-step by default.
343 uint8_t esm = 0b000;
344 uint8_t sm = 0b000;
345
346 // The order of these cases matches the order in Table 12 of the
347 // AMIS-30543 datasheet.
348 switch(mode)
349 {
350 case MicroStep32: sm = 0b000; break;
351 case MicroStep16: sm = 0b001; break;
352 case MicroStep8: sm = 0b010; break;
353 case MicroStep4: sm = 0b011; break;
354 case CompensatedHalf: sm = 0b100; break; /* a.k.a. MicroStep2 */
355 case UncompensatedHalf: sm = 0b101; break;
356 case UncompensatedFull: sm = 0b110; break;
357 case MicroStep128: esm = 0b001; break;
358 case MicroStep64: esm = 0b010; break;
359 case CompensatedFullTwoPhaseOn: esm = 0b011; break; /* a.k.a. MicroStep 1 */
360 case CompensatedFullOnePhaseOn: esm = 0b100; break;
361 }
362
363 cr0 = (cr0 & ~0b11100000) | (sm << 5);
364 cr3 = (cr3 & ~0b111) | esm;
365 writeCR0();
366 writeCR3();
367 }

另外检查 SPI 通信是否正常

回复评论:

SPI代码是
   27 class AMIS30543SPI
28 {
29 public:
30
33 void init(uint8_t slaveSelectPin) { ssPin = slaveSelectPin;
34
35 digitalWrite(ssPin, HIGH);
36 pinMode(ssPin, OUTPUT);
37 }
38
40 uint8_t readReg(uint8_t address)
41 {
42 selectChip();
43 transfer(address & 0b11111);
44 uint8_t dataOut = transfer(0);
45 deselectChip();
46 return dataOut;
47 }
48
50 void writeReg(uint8_t address, uint8_t value)
51 {
52 selectChip();
53 transfer(0x80 | (address & 0b11111));
54 transfer(value);
55
56 // The CS line must go high after writing for the value to actually take
57 // effect.
58 deselectChip();
59 }
60
61 private:
62
63 SPISettings settings = SPISettings(500000, MSBFIRST, SPI_MODE0);
64
65 uint8_t transfer(uint8_t value)
66 {
67 return SPI.transfer(value);
68 }
69
70 void selectChip()
71 {
72 digitalWrite(ssPin, LOW);
73 SPI.beginTransaction(settings);
74 }
75
76 void deselectChip()
77 {
78 digitalWrite(ssPin, HIGH);
79 SPI.endTransaction();
80
81 // The CS high time is specified as 2.5 us in the AMIS-30543 datasheet.
82 delayMicroseconds(3);
83 }
84
85 uint8_t ssPin;
86 };

它包含一些特定于 Arduino 的语法,例如 digitalWrite()可以翻译成 GPIO_SetBits(GPIOx, GPIO_Piny) , ...(完整的 GPIO 教程在 https://stm32f4-discovery.net/2014/04/stm32f429-discovery-gpio-tutorial-with-onboard-leds-and-button/ 中)。 Arduino SPI代码也可以做到这一点,arduino的源代码 spi.hhttps://www.arduino.cc/en/Reference/SPIhttps://github.com/arduino/ArduinoCore-avr/blob/master/libraries/SPI/src/SPI.h对于可以转换为 ARM 的 AVR。

关于通过 SPI 使用 STM32F030R8 控制 AMIS-30543,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60115733/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com