#include <stm32f10x_conf.h>
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "timer.h"
#include "pwm.h"
#include "gpio.h"
#include "fsmc.h"
#include "iic.h"
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
#include "task_com.h"
#include "task_motor.h"
#include "task_led.h"
#include "at_cmd.h"
#include "string.h"
#include "lib5500.h"
#include "flash.h"
#include "iwdg.h"
#include "ws2812_sim.h"
#define LOG_LEVEL_DISABLE -1
#define LOG_LEVEL_ERROR 0
#define LOG_LEVEL_WARNING 1
#define LOG_LEVEL_INFO 2
#define LOG_LEVEL_DEBUG 3
#define LOG_LEVEL LOG_LEVEL_DEBUG
#if defined(LOG_LEVEL) && (LOG_LEVEL >= LOG_LEVEL_DEBUG)
#define LOGD(fmt, ...) printf("[D %s,%d] "fmt, __FUNCTION__, __LINE__, ##__VA_ARGS__) //%16s,%3d
#else
#define LOGD(fmt, ...)
#endif
#if defined(LOG_LEVEL) && (LOG_LEVEL >= LOG_LEVEL_INFO)
#define LOGI(fmt, ...) printf("[I %s,%d] "fmt, __FUNCTION__, __LINE__, ##__VA_ARGS__)
#else
#define LOGI(fmt, ...)
#endif
#if defined(LOG_LEVEL) && (LOG_LEVEL >= LOG_LEVEL_WARNING)
#define LOGW(fmt, ...) printf( "[W %s,%d] "fmt, __FUNCTION__, __LINE__, ##__VA_ARGS__)
#else
#define LOGW(fmt, ...)
#endif
#if defined(LOG_LEVEL) && (LOG_LEVEL >= LOG_LEVEL_ERROR)
#define LOGE(fmt, ...) printf( "[E %s,%d] "fmt, __FUNCTION__, __LINE__, ##__VA_ARGS__)
#else
#define LOGE(fmt, ...)
#endif
#define MARK LOGD("\n");
SemaphoreHandle_t SensorReadLock;
SemaphoreHandle_t UdpSendLock;
SemaphoreHandle_t slave_ready_lock;
void TaskMaster( void *pvParameters );
void TaskSlave( void *pvParameters );
static void SPI1_init(void);
static void SPI2_init(void);
void Initialization()
{
MCU_INIT(RCC_PLLMul_9); //?????: 12MHz * 6 = 72MHz
Delay_Init(72);
Uart_Init(USART1,115200,72); //???????,PCLK1??????PCLK??RCC_HCLK_Div1???
Uart_Init(USART2,9600,36); //?????????,PCLK2??????PCLK??RCC_HCLK_Div1???
// Uart_Init(USART3,115200,36); //???????????
printf("\r\n\r\n****************Build:%s %s****************\r\n",__DATE__,__TIME__);
// UartSendStr(USART2,"System start\r\n");
}
int main(void)
{
Initialization();
// QStepMotorCommand = xQueueCreate( 1,sizeof(int) );
// QHostCommand = xQueueCreate( 16,sizeof(int) );
SensorReadLock = xSemaphoreCreateMutex();
xSemaphoreGive(SensorReadLock);
UdpSendLock = xSemaphoreCreateMutex();
xSemaphoreGive(UdpSendLock);
slave_ready_lock = xSemaphoreCreateMutex();
xSemaphoreTake(slave_ready_lock, 0 * portTICK_PERIOD_MS);
/* Start the tasks defined within this file/specific to this demo. */
// xTaskCreate( TaskComm, "task2", 2 * 256, NULL, 2, NULL );
xTaskCreate( TaskMaster, "task1", 4 * 256, NULL, 3, NULL );
xTaskCreate( TaskSlave, "task2", 4 * 256, NULL, 1, NULL );
/* Start the scheduler. */
vTaskStartScheduler();
while(1);
}
#define USART1_RX_DMA_BUFF_SIZE 128
#define SPI2_RX_DMA_BUFF_SIZE 32
#define SPI2_TX_DMA_BUFF_SIZE 32
static void read_uart_input_buff(void);
static void USART1_RX_DMA_Init(void);
static void SPI2_RX_DMA_Init(void);
static void SPI2_TX_DMA_Init(void);
static void read_spi2_input_buff(void);
static void SPI2_frame_handler(uint8_t data);
static u32 s_frame_buff[1024];
static u8 USART1_RX_DMA_Buff[USART1_RX_DMA_BUFF_SIZE]; //????????????��????????????????????��????????????
static u8 SPI2_RX_DMA_Buff[SPI2_RX_DMA_BUFF_SIZE];
static u8 SPI2_TX_DMA_Buff[SPI2_TX_DMA_BUFF_SIZE] = {0xA0, 0x0 , 0x1 , 0x2 , 0x3 , 0x4 , 0x5 , 0x6 , 0x7 , 0x8 , 0x9 , 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x30};
void TaskMaster( void *pvParameters )
{
LOGI("TaskMaster start...\r\n");
// USART1_RX_DMA_Init();
// ws2812_sim_init();
SPI1_init();
xSemaphoreTake(slave_ready_lock, portMAX_DELAY);
uint8_t count = 0;
while(1)
{
// LOGI("test %d %d\r\n", count, DMA_GetCurrDataCounter(DMA1_Channel4));
// read_uart_input_buff();
static int state = 0;
if (state == 0) {
SPIx_ReadWriteByte(0xA5); // preamble
SPIx_ReadWriteByte(0x5A);
SPIx_ReadWriteByte(0x55);
SPIx_ReadWriteByte(0xAA);
SPIx_ReadWriteByte(count); // addr
SPIx_ReadWriteByte(~count); // cmd
count++;
state = 1;
} else if (state == 1) {
uint8_t data = SPIx_ReadWriteByte(0xFF); // dummy byte
LOGI("%.2X\r\n", data);
if (data == 0xA0) {
for (int i = 0; i < 31; i++) {
uint8_t data = SPIx_ReadWriteByte(0xFF);
printf("%.2X ", data);
}
printf("\r\n");
state = 0;
}
} else if (state == 2) {
}
vTaskDelay(10);
}
}
void TaskSlave( void *pvParameters )
{
LOGI("TaskSlave start...\r\n");
SPI2_init();
SPI2_RX_DMA_Init();
SPI2_TX_DMA_Init();
xSemaphoreGive(slave_ready_lock);
uint8_t count = 0;
while(1)
{
read_spi2_input_buff();
vTaskDelay(1);
}
}
static void USART1_RX_DMA_Init(void)
{
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);
DMA_DeInit(DMA1_Channel5);
DMA_InitTypeDef DMA_InitStruct;
DMA_StructInit(&DMA_InitStruct);
DMA_InitStruct.DMA_PeripheralBaseAddr = (u32)(&USART1->DR);
DMA_InitStruct.DMA_MemoryBaseAddr = (u32)USART1_RX_DMA_Buff;
DMA_InitStruct.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStruct.DMA_BufferSize = sizeof(USART1_RX_DMA_Buff);
DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStruct.DMA_Mode = DMA_Mode_Circular;
DMA_InitStruct.DMA_Priority = DMA_Priority_High;
DMA_InitStruct.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel5,&DMA_InitStruct);
DMA_ITConfig(DMA1_Channel5,DMA_IT_TC,DISABLE);
DMA_ITConfig(DMA1_Channel5,DMA_IT_HT,DISABLE);
DMA_ITConfig(DMA1_Channel5,DMA_IT_TE,DISABLE);
NVIC_InitTypeDef NVIC_InitStruct;
NVIC_InitStruct.NVIC_IRQChannel = DMA1_Channel5_IRQn;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;
NVIC_Init(&NVIC_InitStruct);
USART1->CR3 |= (1<<6); //???DMA????
DMA_Cmd(DMA1_Channel5,ENABLE); //????DMA????
}
// void DMA1_Channel5_IRQHandler()
// {
// DMA_ClearFlag(DMA1_FLAG_TC5);
// int i;
// for(i=0;i<sizeof(USART1_RX_DMA_Buff);i++)
// printf("%c",USART1_RX_DMA_Buff[i]);
// printf("\r\n");
// }
static void read_uart_input_buff(void)
{
static int LastDataCount = 0;
//????????DMA��???.????DMA_GetCurrDataCounter?????????????????????.
int CurrDataCount = USART1_RX_DMA_BUFF_SIZE - DMA_GetCurrDataCounter(DMA1_Channel5);
if(LastDataCount != CurrDataCount)
{
int i;
if(LastDataCount < CurrDataCount)
{
// printf("1:%d %d,",LastDataCount,CurrDataCount);
for(i = LastDataCount;i<CurrDataCount;i++) {
// MasterFrameInput(USART2_RX_DMA_Buff[i]);
printf("%c",USART1_RX_DMA_Buff[i]);
}
// printf("\r\n");
}
else
{
// printf("2:%d %d,",LastDataCount,CurrDataCount);
for(i = LastDataCount;i<USART1_RX_DMA_BUFF_SIZE;i++) {
// MasterFrameInput(USART2_RX_DMA_Buff[i]);
printf("%c",USART1_RX_DMA_Buff[i]);
}
for(i = 0;i<CurrDataCount;i++) {
// MasterFrameInput(USART2_RX_DMA_Buff[i]);
printf("%c",USART1_RX_DMA_Buff[i]);
}
// printf("\r\n");
}
}
LastDataCount = CurrDataCount;
}
static void SPI1_init(void)
{
GPIO_InitTypeDef GPIO_InitStructure; //定义一个GPIO结构体变量
SPI_InitTypeDef SPI_InitStructure;
//初始化片选引脚
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
//chip select/reset pin init
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_11;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// SPI_CS = 1;
// SPI_RST = 1;
//初始化SPI引脚
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
//初始化SPI1
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1,ENABLE);
RCC_APB2PeriphResetCmd(RCC_APB2Periph_SPI1,ENABLE);//复位SPI1
RCC_APB2PeriphResetCmd(RCC_APB2Periph_SPI1,DISABLE);//停止复位SPI1
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Hard;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_Init(SPI1,&SPI_InitStructure);
SPI_SSOutputCmd(SPI1, ENABLE);
// SPI_Cmd(SPI1, DISABLE); //Enable SPI1
SPI_Cmd(SPI1, ENABLE); //Enable SPI1
// SPIx_ReadWriteByte(0xff); //启动传输
// SPI_Cmd(SPI1, DISABLE); //Enable SPI1
}
static void SPI2_init(void)
{
GPIO_InitTypeDef GPIO_InitStructure; //定义一个GPIO结构体变量
SPI_InitTypeDef SPI_InitStructure;
//初始化片选引脚
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
//chip select/reset pin init
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
// SPI_CS = 1;
// SPI_RST = 1;
//初始化SPI引脚
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
//初始化SPI2
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2,ENABLE);
RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI2,ENABLE);//复位SPI2
RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI2,DISABLE);//停止复位SPI2
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStructure.SPI_Mode = SPI_Mode_Slave;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Hard;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_Init(SPI2,&SPI_InitStructure);
SPI_SSOutputCmd(SPI2, DISABLE);
// SPI_Cmd(SPI2, DISABLE); //Enable SPI2
SPI_Cmd(SPI2, ENABLE); //Enable SPI2
// SPIx_ReadWriteByte(0xff); //启动传输
// SPI_Cmd(SPI2, DISABLE); //Enable SPI2
// SPI_I2S_ITConfig(SPI2, SPI_I2S_IT_RXNE, ENABLE);
NVIC_InitTypeDef NVIC_InitStruct;
NVIC_InitStruct.NVIC_IRQChannel = SPI2_IRQn;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;
NVIC_Init(&NVIC_InitStruct);
}
void SPI2_IRQHandler()
{
if (SPI_I2S_GetITStatus(SPI2, SPI_I2S_IT_RXNE) == SET) {
// SPI_I2S_ClearITPendingBit(SPI2, SPI_I2S_IT_RXNE);
LOGI("IRQ:%.2X\r\n", SPI2->DR);
}
}
static void SPI2_RX_DMA_Init(void)
{
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);
DMA_DeInit(DMA1_Channel4);
DMA_InitTypeDef DMA_InitStruct;
DMA_StructInit(&DMA_InitStruct);
DMA_InitStruct.DMA_PeripheralBaseAddr = (u32)(&SPI2->DR);
DMA_InitStruct.DMA_MemoryBaseAddr = (u32)SPI2_RX_DMA_Buff;
DMA_InitStruct.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStruct.DMA_BufferSize = sizeof(SPI2_RX_DMA_Buff);
DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStruct.DMA_Mode = DMA_Mode_Circular;
DMA_InitStruct.DMA_Priority = DMA_Priority_High;
DMA_InitStruct.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel4,&DMA_InitStruct);
DMA_ITConfig(DMA1_Channel4,DMA_IT_TC,DISABLE);
DMA_ITConfig(DMA1_Channel4,DMA_IT_HT,DISABLE);
DMA_ITConfig(DMA1_Channel4,DMA_IT_TE,DISABLE);
NVIC_InitTypeDef NVIC_InitStruct;
NVIC_InitStruct.NVIC_IRQChannel = DMA1_Channel4_IRQn;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;
NVIC_Init(&NVIC_InitStruct);
SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Rx, ENABLE);
DMA_Cmd(DMA1_Channel4,ENABLE); //????DMA????
}
void DMA1_Channel4_IRQHandler()
{
DMA_ClearFlag(DMA1_FLAG_TC4);
int i;
for(i=0;i<sizeof(SPI2_RX_DMA_Buff);i++)
printf("%c",SPI2_RX_DMA_Buff[i]);
printf("\r\n");
}
static void read_spi2_input_buff(void)
{
static int LastDataCount = 0;
int CurrDataCount = SPI2_RX_DMA_BUFF_SIZE - DMA_GetCurrDataCounter(DMA1_Channel4);
if(LastDataCount != CurrDataCount)
{
int i;
if(LastDataCount < CurrDataCount)
{
// printf("1:%d %d,",LastDataCount,CurrDataCount);
for(i = LastDataCount;i<CurrDataCount;i++) {
// printf("%.2X ",SPI2_RX_DMA_Buff[i]);
SPI2_frame_handler(SPI2_RX_DMA_Buff[i]);
}
// printf("\r\n");
}
else
{
// printf("2:%d %d,",LastDataCount,CurrDataCount);
for(i = LastDataCount;i<SPI2_RX_DMA_BUFF_SIZE;i++) {
// printf("%.2X ",SPI2_RX_DMA_Buff[i]);
SPI2_frame_handler(SPI2_RX_DMA_Buff[i]);
}
for(i = 0;i<CurrDataCount;i++) {
// printf("%.2X ",SPI2_RX_DMA_Buff[i]);
SPI2_frame_handler(SPI2_RX_DMA_Buff[i]);
}
// printf("\r\n");
}
}
LastDataCount = CurrDataCount;
}
static void SPI2_frame_handler(uint8_t data)
{
// printf("%.2X\r\n", data);
static int state = 0;
// 0xA5 5A 55 AA
if (state == 0) {
if (data == 0xA5) {
state = 1;
}
} else if (state == 1) {
if (data == 0x5A) {
state = 2;
} else if (data == 0xA5) {
} else {
LOGE("Frame err\r\n");
while (1);
state = 0;
}
} else if (state == 2) {
if (data == 0x55) {
state = 3;
} else if (data == 0xA5) {
state = 1;
} else {
LOGE("Frame err\r\n");
while (1);
state = 0;
}
} else if (state == 3) {
if (data == 0xAA) {
state = 4;
} else if (data == 0xA5) {
state = 1;
} else {
LOGE("Frame err\r\n");
while (1);
state = 0;
}
} else if (state == 4) {
printf("ADDR:%.2X\r\n", data);
state = 5;
} else if (state == 5) {
printf("CMD:%.2X\r\n", data);
// SPI2->DR = 0x33;
DMA_Cmd(DMA1_Channel5, DISABLE); // disable DMA before starting a new DMA transaction
DMA_InitTypeDef DMA_InitStruct;
DMA_StructInit(&DMA_InitStruct);
DMA_InitStruct.DMA_PeripheralBaseAddr = (u32)(&SPI2->DR);
DMA_InitStruct.DMA_MemoryBaseAddr = (u32)SPI2_TX_DMA_Buff;
DMA_InitStruct.DMA_DIR = DMA_DIR_PeripheralDST;
DMA_InitStruct.DMA_BufferSize = sizeof(SPI2_TX_DMA_Buff);
DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStruct.DMA_Mode = DMA_Mode_Normal;
DMA_InitStruct.DMA_Priority = DMA_Priority_High;
DMA_InitStruct.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel5,&DMA_InitStruct);
DMA_Cmd(DMA1_Channel5, ENABLE);
state = 0;
} else if (state == 6) {
} else if (state == 7) {
} else if (state == 8) {
} else if (state == 9) {
} else if (state == 10) {
} else {
}
}
static void SPI2_TX_DMA_Init(void)
{
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);
DMA_DeInit(DMA1_Channel5);
DMA_InitTypeDef DMA_InitStruct;
DMA_StructInit(&DMA_InitStruct);
DMA_InitStruct.DMA_PeripheralBaseAddr = (u32)(&SPI2->DR);
DMA_InitStruct.DMA_MemoryBaseAddr = (u32)SPI2_TX_DMA_Buff;
DMA_InitStruct.DMA_DIR = DMA_DIR_PeripheralDST;
DMA_InitStruct.DMA_BufferSize = sizeof(SPI2_TX_DMA_Buff);
DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStruct.DMA_Mode = DMA_Mode_Normal;
DMA_InitStruct.DMA_Priority = DMA_Priority_High;
DMA_InitStruct.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel5,&DMA_InitStruct);
DMA_ITConfig(DMA1_Channel5,DMA_IT_TC,ENABLE);
DMA_ITConfig(DMA1_Channel5,DMA_IT_HT,DISABLE);
DMA_ITConfig(DMA1_Channel5,DMA_IT_TE,DISABLE);
NVIC_InitTypeDef NVIC_InitStruct;
NVIC_InitStruct.NVIC_IRQChannel = DMA1_Channel5_IRQn;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;
NVIC_Init(&NVIC_InitStruct);
SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Tx, ENABLE);
DMA_Cmd(DMA1_Channel5,DISABLE); //????DMA????
// note: the last byte moved from RAM to SPI2->DR is seen as the end of DMA transmission
// but the last byte still not been transferred out from the shift register which means
// the SPI master might not received the last byte when the SPI slave finishing the DMA
// transfer.
}
void DMA1_Channel5_IRQHandler()
{
DMA_ClearFlag(DMA1_FLAG_TC5);
LOGI("Sent done\r\n");
DMA_Cmd(DMA1_Channel5, DISABLE);
SPI2->DR = 0x00; // set the shift register to 0x00 other wise SPI master will get the previous byte
// which might be 0xA0 and causes error.
}
【嵌入式】STM32F103 SPI主从收发实验
原创
©著作权归作者所有:来自51CTO博客作者qqtang797的原创作品,请联系作者获取转载授权,否则将追究法律责任

提问和评论都可以,用心的回复会被更多人看到
评论
发布评论
相关文章
-
【STM32】FreeRTOS 移植到 STM32F103
操场
stm32 #define 句柄 #include C -
stm32f103的串口通信之串口轮询实验
有关stm32串口轮询实验的有关问题
串口 串口通信 轮询实验 -
STM32F103开发环境的搭建
交叉开发嵌入式系统开发不同于通用PC系统的开发。通用PC系统拥有强劲的处理器、充裕的内存和硬
嵌入式 linux 单片机 开发环境 stm32