- 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/
我想对现有堆栈(更新)和新堆栈(创建)使用相同的 CloudFormation 模板。我正在使用公共(public) SSM 参数存储来获取最新的 AMI: Parameters: LatestA
Ubuntu 将他们的云镜像认证为 ami-f95ef58a,并且它在区域 eu-west-1 中作为社区 AMI 提供。请参阅 Ubuntu 文档 here 另一方面,Centos 在 AWS Ma
我正在使用两个实例,一个是 ubuntu,另一个是具有相同配置的 Windows。对于浏览器上的每个操作,Ubuntu 实例比 Windows 实例花费更多的时间。这有什么原因吗? 最佳答案 性能和网
运行 vagrant 命令时出现如下错误, # vagrant up --provider=aws 这台机器的配置有错误。请修复以下错误并重试: AWS 提供商:* AMI 必须通过“ami”配置(
是否有一种从 Amazon Linux AMI 升级到 Amazon Linux 2 AMI 的简单方法,或者我是否必须创建一个新实例并再次进行所有服务器设置? 感谢您的反馈意见, 最佳答案 没有简单
我正在使用 Ansible 构建一个 EC2 实例,然后从该实例创建一个 AMI。我确定我在这里遗漏了一些东西,但是如何获得新创建的 AMI 的 DI?我试过了: tasks: - name: cre
我想使用yaml文件编写一个cloudformation。我知道公共(public) AMI 的格式。但我对如何在 yaml 文件中添加私有(private) AMI 感到困惑。我在网上搜索了解决方案
我正在使用 AMI Medical Imaging (AMI) JS ToolKit。有没有办法将窗口移动到鼠标事件,例如右键单击并移动? 我知道可以使用示例中的菜单更改窗口/级别,但我想更改 Con
我正在尝试以编程方式启动带有 EBS 的 Ubuntu 12.04 LTS 服务器 64 位。我写了以下代码: Placement placement = new Placement("eu-west
我创建了 AMI Oracle Database 11.2.0.1 64 位标准版的新实例;甲骨文提供的 ami-3f739c56。我试图通过 SSH 从我的 Windows 10 PC(也从我的 M
我正在使用基于 Windows 2019 Base AMI (ami-0fa60543f60171fe3) 构建的自定义 AMI 来创建 Windows 服务器。但我发现用户数据不起作用。这是我正在使
我正在尝试从 AWS 账户中清除我的快照和 AMI,要删除我知道需要取消注册 AMI 的快照。但是当我尝试通过控制台取消注册时,出现以下错误。 “尝试取消注册 amis 时发生错误” 有人对这个问题有
我已经升级到 Tensorflow 版本 1.0 并安装了 CUDA 8.0 和 cudnn 5.1 版本以及最新的 nvidia 驱动程序 375.39。我的 NVIDIA 硬件是在 Amazon
我想使用 AMI 在 Asterisk 中接听电话。我可以发起调用,但完全不知道,如何接听电话... 调用脚本: #login sock = socket.socket(af, socktype, p
我的 LAN 上正在运行 Asterisk 服务器,现在我想使用 Javascript 通过 AMI(Asterisk 管理器接口(interface))执行与正在运行的应用程序的套接字连接。 任何人
我有几个基于 ubuntu 的 ec2 实例在生产模式下运行。我的问题是,每当流量增加时,我都会手动启动实例,从 github 更新代码。 现在我必须配置自动缩放,这样每当 API 启动新实例时,它就
我正在 Amazon EC2 上开发 Ubuntu AMI。 在一个正在运行的实例上,我将 ubuntu 用户的密码更改为(比如说)“foobar”。 (我知道 EC2 通常不需要用户密码,因为 ss
我一直在尝试在 EC2 上登录我新创建的 Ubuntu oneiric AMI,但总是失败,说连接超时。我已经使用 AWS 管理控制台以及命令行工具进行了尝试。我已经在 Google 和 Server
我正在使用的 Windows AMI(EBS 支持)的启动时间存在巨大差异。有些只需 3 分钟即可启动。其他人可能需要 20 多分钟。我的理解是,默认的 Windows AMI 可能会很慢,因为它们需
我是Asterisk的新手。我的要求是,当我接到调用时,我需要识别调用者ID,并在接听电话时弹出该ID。我对AMI和AGI有一些了解。我想知道如何使用php脚本执行此操作。 任何示例或我可以用来执行此
我是一名优秀的程序员,十分优秀!