- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试让我的 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
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);
}
#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);
}
#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 写入多个寄存器(sm
、esm
、...)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 }
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 }
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 };
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.h
在
https://www.arduino.cc/en/Reference/SPI和
https://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/
我有以下代码: interface F { (): string; a(): number; } function f() { return '3'; } f['a'] = f
比如我有一个 vector vector > v={{true,1},{true,2},{false,3},{false,4},{false,5},{true,6},{false,7},{true,8
我需要编写一个要在 GHCi 上运行的模块,并将函数组合为相同的函数。这个(经典的fog(x) = f(g(x)))运行: (.) f g = (\x -> f (g x)). 当我尝试这样写时出现问
动态规划这里有一个问题 大写字母AZ对应于整数[-13,12],因此一个字符串对应于一整列。我们将对应的整列的总和称为字符串的特征值。例如:字符串ACM对应的总体列为{-13,-11,-1},则ACM
我想知道为什么 F-Sharp 不支持无穷大。 这适用于 Ruby(但不适用于 f#): let numbers n = [1 .. 1/0] |> Seq.take(n) -> System.Div
如何从已编译的 F# 程序中的字符串执行 F# 代码? 最佳答案 这是一个小脚本,它使用 FSharp CodeDom 将字符串编译为程序集,并将其动态加载到脚本 session 中。 它使用类型扩展
有什么方法可以在 F# List 和 F# Tuple 之间转换? 例如: [1;2;3] -> (1,2,3) (1,2,3,4) -> [1;2;3;4] 我需要两个函数来做到这一点: le
我想将一个或多个 .fsx 文件加载到 F# 交互中,并将 .fsx 文件中定义的所有函数都包含在作用域中,以便我可以直接使用控制台中的功能。 #load 指令执行指定的 .fsx 文件,但随后我无法
我正在尝试像 this page 中那样编写 F 代数.不同之处在于,不是用元组组合,而是像这样: type FAlgebra[F[_], A] = F[A] => A def algebraZip[
给定一个 F# 记录: type R = { X : string ; Y : string } 和两个对象: let a = { X = null ; Y = "##" } let b = {
所以我们有一组文件名\url,如file、folder/file、folder/file2、folder/file3、folder/folder2/fileN等。我们得到一个字符串,如文件夹/。我们想
假设我有一个字符串“COLIN”。 这个字符串的数值是: 3 + 15 + 12 + 9 + 14 = 53. 所以 A = 1, B = 2, C = 3, and so on. 为此,我什至不知道
在 C# 中,我有以下代码来创建一个对象实例。 var myObject = new MyClass("paramvalue") { Property1 = "value1" Proper
即,标准库中有这样的函数吗? let ret x _ = x 为了保持代码可读性,我想尽量减少自制基本构建功能构建块的数量,并使用现有的东西。 最佳答案 不。你可能想看看 FSharpX。 关于f#
目前,我有一个函数可以将列表中每个列表的第一个元素( float )返回到单独的列表。 let firstElements list = match list with | head:
我刚刚解决了problem23在 Project Euler 中,我需要一个 set 来存储所有丰富的数字。 F# 有一个不可变集合,我可以使用 Set.empty.Add(i) 创建一个包含数字 i
F#语言具有计算自然对数的函数log和计算以10为底的对数的log10。 在F#中以2为底的对数的最佳计算方法是什么? 最佳答案 您可以简单地使用以下事实:“ b的a对数” = ln(b)/ ln(a
动机 我有一个长时间运行的 bool 函数,它应该在数组中执行,如果数组中的元素满足条件,我想立即返回。我想并行搜索并在第一个完整线程返回正确答案时终止其他线程。 问题 在 F# 中实现并行存在函数的
我最近完成了一个生成字符串列表的项目,我想知道执行此操作的最佳方法。 字符串生成是上下文敏感的,以确定它是否可以接受(这是游戏中的一系列游戏,所以你必须知道最后一次游戏是什么) 我这样做的方法是使用一
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引起辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the he
我是一名优秀的程序员,十分优秀!