C 通过SPI使用STM32F030R8控制AMIS-30543
我试图让我的STM32板控制步进电机(使用AMIS-30543驱动器,26M024B2B步进电机)使用SPI。我使用的是Keil uVision 5,在C语言中采用裸机方式。我的问题是电机没有旋转,我不确定错误隐藏在哪里。如果您能指出我在这方面的错误,以及如何解决问题,我将不胜感激。谢谢你抽出时间 我把它接线在一起,如下所示C 通过SPI使用STM32F030R8控制AMIS-30543,c,embedded,stm32,bare-metal,cmsis,C,Embedded,Stm32,Bare Metal,Cmsis,我试图让我的STM32板控制步进电机(使用AMIS-30543驱动器,26M024B2B步进电机)使用SPI。我使用的是Keil uVision 5,在C语言中采用裸机方式。我的问题是电机没有旋转,我不确定错误隐藏在哪里。如果您能指出我在这方面的错误,以及如何解决问题,我将不胜感激。谢谢你抽出时间 我把它接线在一起,如下所示 STM AMIS 3.3v IOREF GND GND PB3 NXT PB5 DIR PA7 DO PA6 DI P
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
#包括“stm32f0xx.h”
#包括
#包括
//GPIO->PB5->方向
//GPIO->PB3->下一步
//USART2 TX->PA2,AF1->传输
//USART2接收->PA3,AF1->接收
//SPI1 NSS->PA4->从选择
//SPI1 SCK->PA5,AF0->时钟
//SPI1 MISO->PA6,AF0->主输入从输出
//SPI1 MOSI->PA7,AF0->主输出从输入
无效时钟初始化(无效);
无效GPIO_初始(无效);
无效USART2_初始(无效);
无效SPI1_初始(无效);
无效SPI1_写入(uint8_t数据);
无效延迟ms(int n);
内部主(空)
{
时钟初始化();
GPIO_Init();
USART2_Init();
SPI1_Init();
//char-str[100];
//设置步进电机的旋转方向
GPIOB->ODR |=0x00000020;
//将设置应用于步进电机驱动器
uint8_t packet0;
uint8_t包装1;
GPIOA->ODR=0x00000010;//写入NSS高
packet0=0x81;//写入CR0
packet1=0x20;//设置旋转量
SPI1_Write(packet0);//发送写命令和寄存器地址
SPI1_Write(packet1);//发送寄存器数据
GPIOA->ODR=0x00000000;//将NSS写入低位
GPIOA->ODR=0x00000010;//写入NSS高
packet0=0x82;//写入CR1
packet1=0x80;//设置旋转量
SPI1_Write(packet0);//发送写命令和寄存器地址
SPI1_Write(packet1);//发送寄存器数据
GPIOA->ODR=0x00000000;//将NSS写入低位
GPIOA->ODR=0x00000010;//写入NSS高
packet0=0x83;//写入CR2
packet1=0x80;//设置电机启用
SPI1_Write(packet0);//发送写命令和寄存器地址
SPI1_Write(packet1);//发送寄存器数据
GPIOA->ODR=0x00000000;//将NSS写入低位
printf(“\r\n测试接口\r\n”);
而(1)
{
//printf(“命令:”);
//获取(str);
//printf(“\r\n”);
//printf(“您的命令是:”);
//put(str);
//printf(“\r\n”);
GPIOB->ODR^=0x00000008;//切换阶跃信号
DelayMS(50);
}
}
//初始化设备时钟
无效时钟初始化(无效)
{
//启用端口A->位17,AHB
//启用端口B->位18,AHB
RCC->AHBENR |=0x00060000;
//启用USART2->位17,APB1
RCC->APB1ENR |=0x00020000;
//启用SPI1->位12,APB2
RCC->APB2ENR |=0x00001000;
}
//初始化GPIO引脚
无效GPIO_初始化(无效)
{
//将GPIO设置为通用->PB3,位6:7
//->PB5,位10:11
GPIOB->MODER |=0x00000440;
}
//初始化USART2
无效USART2_初始(无效)
{
//将GPIO设置为备用功能->PA2,位4:5
//->PA3,位6:7
GPIOA->MODER |=0x000000A0;
//定义备用功能->PA2,AF1
//->PA3,AF1
GPIOA->AFR[0]|=0x00001100;
//将波特率->8000000/9600设置为十六进制,9600@8MHz
USART2->BRR=0x00000341;
//启用传输->位3
//启用接收->位2
USART2->CR1=0x0000000C;
//启用usart启用->位0
USART2->CR1 |=0x00000001;
}
//初始化SPI1
无效SPI1_初始(无效)
{
//清除GPIO引脚->PA5,位10:11
//->PA6,第12:13位
//->PA7,位14:15
GPIOA->MODER&=~0x0000FC00;
//将GPIO设置为备用功能->PA5,位10:11
//->PA6,第12:13位
//->PA7,位14:15
GPIOA->MODER |=0x0000A800;
//清除备用功能->PA5,AF0
//->PA6,AF0
//->PA7,AF0
GPIOA->AFR[0]&=~0xFFF00000;
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 };