前言
用国产CW32F030C8T6单片机做个旋转展示台玩玩。具体硬件设计请移步【CW32】基于CW32F030的旋转展示台 - 嘉立创EDA开源硬件平台 (oshwhub.com)
一、步进电机驱动
这里以四拍驱动5V步进电机为例。首先初始化一个基本定时器(BTIM),不过定时器的频率需要根据调试结果合理选择。
void BTIM_configuration(void){
BTIM_TimeBaseInitStruct.BTIM_Mode = BTIM_Mode_TIMER;
BTIM_TimeBaseInitStruct.BTIM_Period = 7000-1;
BTIM_TimeBaseInitStruct.BTIM_Prescaler = BTIM_PRS_DIV16;
BTIM_TimeBaseInitStruct.BTIM_OPMode=BTIM_OPMode_Repetitive;
BTIM_TimeBaseInit(CW_BTIM1, &BTIM_TimeBaseInitStruct);
BTIM_ITConfig(CW_BTIM1, BTIM_IT_OV, ENABLE);
BTIM_Cmd(CW_BTIM1, ENABLE);
}
然后找4个IO端口给脉冲信号。如果有条件的话,可以分配相邻编号的4个管脚连到ULN2003驱动步进电机。那么,每一步的话,直接改BSRR寄存器一行完成。
void BTIM1_IRQHandler(void)
{
/* USER CODE BEGIN */
if (BTIM_GetITStatus(CW_BTIM1, BTIM_IT_OV))
{
BTIM_ClearITPendingBit(CW_BTIM1, BTIM_IT_OV);
if (motor_enable==1){
if(motor_direction==1){
switch(motor_stage){
case 1: CW_GPIOB->BSRR=0X00800030; break;
case 2: CW_GPIOB->BSRR=0X00100060; break;
case 3: CW_GPIOB->BSRR=0X002000C0; break;
default: CW_GPIOB->BSRR=0X00400090; break; //case 4
}
}
else{
switch(motor_stage){
case 1: CW_GPIOB->BSRR=0X00400030; break;
case 2: CW_GPIOB->BSRR=0X00800060; break;
case 3: CW_GPIOB->BSRR=0X001000C0; break;
default: CW_GPIOB->BSRR=0X00200090; break; //case 4
}
}
if(motor_direction==1) motor_stage++;
else motor_stage--;
if(motor_stage==5) motor_stage=1;
if(motor_stage==0) motor_stage=4;
}
else{
CW_GPIOB->BSRR=0X00F00000;
}
}
/* USER CODE END */
}
这里的代码还考虑了正反转两种情况,根据motor_direction切换驱动模式。
二、WS2812驱动
用STM32+ws2812灯条,点灯升级版_stm32 ws2812_哆啦哆小魔仙的博客-CSDN博客的代码,不过要根据CW32的实际情况改一下配置。为了分出7MHz时钟,CW32F030主频配成56MHz。
然后参考例程配置SPI和DMA。一些宏定义可以在文章最后的main.h找到。
void SPI_Configuration()
{
SPI_InitTypeDef SPI_InitStructure;
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; // 双线全双工
SPI_InitStructure.SPI_Mode = SPI_Mode_Master; // 主机模式
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; // 帧数据长度为8bit
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; // 时钟空闲电平为低
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; // 第一个边沿采样
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; // 片选信号由SSI寄存器控制
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8; // 波特率为PCLK的4分频
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; // 最高有效位 MSB 收发在前
SPI_InitStructure.SPI_Speed = SPI_Speed_High; // 高速SPI
SPI_Init(SPIx, &SPI_InitStructure);
SPI_Cmd(SPIx, ENABLE);
}
void DMA_Configuration(void)
{
DMA_InitTypeDef DMA_InitStructure;
//初始化SPI DMA TX
DMA_InitStructure.DMA_Mode = DMA_MODE_BLOCK;
DMA_InitStructure.DMA_TransferWidth = DMA_TRANSFER_WIDTH_8BIT;
DMA_InitStructure.DMA_SrcInc = DMA_SrcAddress_Increase;
DMA_InitStructure.DMA_DstInc = DMA_DstAddress_Fix;
DMA_InitStructure.TrigMode = DMA_HardTrig;
DMA_InitStructure.HardTrigSource = SPIx_DMA_TxTrigSource;
DMA_InitStructure.DMA_TransferCnt = 24*PIXEL_NUM;
DMA_InitStructure.DMA_SrcAddress = (uint32_t)pixelBuffer;
DMA_InitStructure.DMA_DstAddress = (uint32_t)&SPIx->DR;
DMA_Init(SPIx_TX_DMACHANNEL, &DMA_InitStructure);
DMA_Cmd(SPIx_TX_DMACHANNEL, ENABLE);
}
总结
如果会用STM32,使用CW32是一件不困难的事情。当然了,一些端口的名称会和STM32有些小的区别,写代码时对着例程写,那就没有问题了。
最后附上main.h
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : main.h
* @brief : Header for main.c file.
* This file contains the common defines of the application.
******************************************************************************
* @attention
*
* <h2><center>© Copyright (c) 2021 CW.
* All rights reserved.</center></h2>
*
*
******************************************************************************
*/
/* USER CODE END Header */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __MAIN_H
#define __MAIN_H
#ifdef __cplusplus
extern "C"
{
#endif
/* Includes ------------------------------------------------------------------*/
#include "base_types.h"
#include "cw32f030.h"
#include "system_cw32f030.h"
#include "interrupts_cw32f030.h"
#include "cw32f030_gtim.h"
#include "cw32f030_gpio.h"
#include "cw32f030_rcc.h"
#include "cw32f030_flash.h"
#include "cw32f030_spi.h"
#include "cw32f030_dma.h"
#include "cw32f030_btim.h"
#include "cw32f030_uart.h"
#include "ws2812.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Exported types ------------------------------------------------------------*/
/* USER CODE BEGIN ET */
/* USER CODE END ET */
/* Exported constants --------------------------------------------------------*/
/* USER CODE BEGIN EC */
/* USER CODE END EC */
/* Exported macro ------------------------------------------------------------*/
/* USER CODE BEGIN EM */
/* USER CODE END EM */
/* Exported functions prototypes ---------------------------------------------*/
/* USER CODE BEGIN EFP */
void DMA_Configuration(void);
void BTIM_configuration(void);
void USART_SendString(UART_TypeDef* USARTx, char *String);
void keyPress_BTIM_config(void);
/* USER CODE END EFP */
/* Private defines -----------------------------------------------------------*/
/* USER CODE BEGIN Private defines */
#define SPI_MASTER //????
//#define SPI_SLAVE //????
//SPI
#define SPIx CW_SPI2
#define SPIx_CLK RCC_APB1_PERIPH_SPI2
#define SPIx_APBClkENx RCC_APBPeriphClk_Enable1
//SPI GPIO
#define SPIx_SCK_GPIO_CLK RCC_AHB_PERIPH_GPIOA
#define SPIx_SCK_GPIO_PORT CW_GPIOA
#define SPIx_SCK_GPIO_PIN GPIO_PIN_2
#define SPIx_SCK_AF() PA02_AFx_SPI2SCK()
#define SPIx_MISO_GPIO_CLK RCC_AHB_PERIPH_GPIOA
#define SPIx_MISO_GPIO_PORT CW_GPIOA
#define SPIx_MISO_GPIO_PIN GPIO_PIN_0
#define SPIx_MISO_AF() PA00_AFx_SPI2MISO()
#define SPIx_MOSI_GPIO_CLK RCC_AHB_PERIPH_GPIOA
#define SPIx_MOSI_GPIO_PORT CW_GPIOA
#define SPIx_MOSI_GPIO_PIN GPIO_PIN_1
#define SPIx_MOSI_AF() PA01_AFx_SPI2MOSI()
#define SPIx_CS_GPIO_CLK RCC_AHB_PERIPH_GPIOA
#define SPIx_CS_GPIO_PORT CW_GPIOA
#define SPIx_CS_GPIO_PIN GPIO_PIN_3
#define SPIx_CS_AF() PA03_AFx_SPI2CS()
//CS LOW or HIGH
#define SPIx_CS_LOW() PA03_SETLOW()
#define SPIx_CS_HIGH() PA03_SETHIGH()
//DMA
#define SPIx_RX_DMACHANNEL CW_DMACHANNEL1
#define SPIx_TX_DMACHANNEL CW_DMACHANNEL2
#define SPIx_DMA_RxTrigSource DMA_HardTrig_SPI2_RXBufferNE
#define SPIx_DMA_TxTrigSource DMA_HardTrig_SPI2_TXBufferE
#define BufferSize ARRAY_SZ(TxBuffer)
#define MOTOR_PORT CW_GPIOB
#define MT1 GPIO_PIN_4
#define MT2 GPIO_PIN_5
#define MT3 GPIO_PIN_6
#define MT4 GPIO_PIN_7
//UARTx
#define DEBUG_USARTx CW_UART1
#define DEBUG_USART_CLK RCC_APB2_PERIPH_UART1
#define DEBUG_USART_APBClkENx RCC_APBPeriphClk_Enable2
#define DEBUG_USART_BaudRate 9600
#define DEBUG_USART_UclkFreq 32800
//UARTx GPIO
#define DEBUG_USART_GPIO_CLK RCC_AHB_PERIPH_GPIOA
#define DEBUG_USART_TX_GPIO_PORT CW_GPIOA
#define DEBUG_USART_TX_GPIO_PIN GPIO_PIN_8
#define DEBUG_USART_RX_GPIO_PORT CW_GPIOA
#define DEBUG_USART_RX_GPIO_PIN GPIO_PIN_9
//GPIO AF
#define DEBUG_USART_AFTX PA08_AFx_UART1TXD()
#define DEBUG_USART_AFRX PA09_AFx_UART1RXD()
//GPIO INPUT
#define USR_SW_PORT CW_GPIOB
#define USR_SW1_PIN GPIO_PIN_10
#define USR_SW2_PIN GPIO_PIN_2
#define USR_SW3_PIN GPIO_PIN_1
#define USR_SW4_PIN GPIO_PIN_0
//??
#define DEBUG_USART_IRQ UART1_IRQn
/* USER CODE END Private defines */
#ifdef __cplusplus
}
#endif
#endif /* __MAIN_H */
/************************ (C) COPYRIGHT CW *****END OF FILE****/