目的

把字库文件录入到W25QXX存储模块中,供oled显示使用。

涉及模块

  • stm32f103c8t6
    • 用到usart1,dma1,spi1,tim2
  • W25Q64
  • 0.96寸oled
  • 串口调试器

思路

  1. 电脑通过串口发送字库数据给stm32
  2. stm32通过dma1接收字库数据
  3. stm32通过spi1发送字库数据到W25Q64
  4. 通过定时器计时判断串口数据是否完成传输

具体实现

串口发送接收数据

  1. 初始化usart1串口
  • 初始化usart1串口,波特率为9600,8位数据,无校验位,1位停止位。
  • 开启串口空闲的中断
  • 开启DMA1串口接收数据转运
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
void UART1_Init(u32 baud_rate)
{
/*开启时钟*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); //开启USART1的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //开启GPIOA的时钟

/*GPIO初始化*/
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure); //将PA9引脚初始化为复用推挽输出

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure); //将PA10引脚初始化为上拉输入

/*USART初始化*/
USART_InitTypeDef USART_InitStructure; //定义结构体变量
USART_InitStructure.USART_BaudRate = baud_rate; //波特率
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //硬件流控制,不需要
USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; //模式,发送模式和接收模式均选择
USART_InitStructure.USART_Parity = USART_Parity_No; //奇偶校验,不需要
USART_InitStructure.USART_StopBits = USART_StopBits_1; //停止位,选择1位
USART_InitStructure.USART_WordLength = USART_WordLength_8b; //字长,选择8位
USART_Init(USART1, &USART_InitStructure); //将结构体变量交给USART_Init,配置USART1

/*中断输出配置*/
// USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); //开启串口接收数据中断
USART_ITConfig(USART1, USART_IT_IDLE, ENABLE); //开启串口空闲的中断
/*NVIC中断分组*/
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //配置NVIC为分组2

/*NVIC配置*/
NVIC_InitTypeDef NVIC_InitStructure; //定义结构体变量
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; //选择配置NVIC的USART1线
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //指定NVIC线路使能
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //指定NVIC线路的抢占优先级为1
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; //指定NVIC线路的响应优先级为1
NVIC_Init(&NVIC_InitStructure); //将结构体变量交给NVIC_Init,配置NVIC外设

/*USART使能*/
USART_Cmd(USART1, ENABLE); //使能USART1,串口开始运行
}

u8 uart1_buf0[UART1_RXBUF_LEN] = {0};

void USART1_DMA_Init(void)
{
DMA_InitTypeDef DMA_InitStructure;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
// ==========================
// DMA1 通道5 → USART1 RX(接收)
// ==========================
DMA_DeInit(DMA1_Channel5);
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; // 外设→内存
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)uart1_buf0;
DMA_InitStructure.DMA_BufferSize = UART1_RXBUF_LEN;
DMA_Init(DMA1_Channel5, &DMA_InitStructure);

// 使能RX的DMA`
DMA_Cmd(DMA1_Channel5, ENABLE);
USART_DMACmd(USART1, USART_DMAReq_Rx, ENABLE);
}

2.