原理图:
注:使用的数串口1的引脚,PA1是发送端引脚,PA3是接收端引脚,PA7串口的使能位。
1.0 WIFI模组驱动
驱动初始化函数:
void WifiModuleDrvInit(void)
{
WifiGpioInit();
WifiUartInit(115200);
WifiDmaInit();
HwresetWifiModule();
}
宏定义串口地址...
#define USART1_DATA_ADDR (USART1 + 0x04) // 串口2的数据寄存器16进制地址值
#define MAX_BUF_SIZE 256
static uint8_t g_recvDataBuf[MAX_BUF_SIZE];
创建结构体:
typedef struct
{
uint32_t uartNo;
rcu_periph_enum rcuUart;
rcu_periph_enum rcuGpio;
uint32_t gpio;
uint32_t txPin;
uint32_t rxPin;
uint8_t irq;
uint32_t dmaNo;
rcu_periph_enum rcuDma;
dma_channel_enum dmaCh;
}UartHwInfo_t;
创建结构体数组:
static UartHwInfo_t g_uartHwInfo =
{
USART1,
RCU_USART1,
RCU_GPIOA,
GPIOA,
GPIO_PIN_2,
GPIO_PIN_3,
USART1_IRQn,
DMA0,
RCU_DMA0,
DMA_CH5
};
GPIO初始化
static void WifiGpioInit(void)
{
rcu_periph_clock_enable(RCU_GPIOA);
gpio_init(GPIOA, GPIO_MODE_OUT_PP, GPIO_OSPEED_2MHZ, GPIO_PIN_7);
rcu_periph_clock_enable(g_uartHwInfo.rcuGpio);
gpio_init(g_uartHwInfo.gpio, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, g_uartHwInfo.txPin);
gpio_init(g_uartHwInfo.gpio, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, g_uartHwInfo.txPin);
}
串口初始化:
static void WifiUartInit(uint32_t baudRate)
{
rcu_periph_clock_enable(g_uartHwInfo.rcuUart);
usart_deinit(g_uartHwInfo.uartNo);
usart_baudrate_set(g_uartHwInfo.uartNo, baudRate);
usart_transmit_config(g_uartHwInfo.uartNo, USART_TRANSMIT_ENABLE);
usart_receive_config(g_uartHwInfo.uartNo, USART_RECEIVE_ENABLE);
usart_interrupt_enable(g_uartHwInfo.uartNo, USART_INT_IDLE);
// 使能串口中断,嵌套中断向量控制器
nvic_irq_enable(g_uartHwInfo.irq, 0, 0);
// 在USART_CTL0寄存器中设置UEN位,使能UART
usart_enable(g_uartHwInfo.uartNo);
}
DMA初始化:
static void WifiDmaInit(void)
{
// 使能DMA时钟
rcu_periph_clock_enable(g_uartHwInfo.rcuDma);
// 复位DMA通道
dma_deinit(g_uartHwInfo.dmaNo, g_uartHwInfo.dmaCh);
// DMA结构体初始化
dma_parameter_struct dmaStructure;
// 配置数据传输方向
dmaStructure.direction = DMA_PERIPHERAL_TO_MEMORY;
// 配置数据的源地址
dmaStructure.periph_addr = USART1_DATA_ADDR;
// 配置源地址数固定地址还是增长,配置为固定地址
dmaStructure.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
// 配置数据传输位宽
dmaStructure.periph_width = DMA_PERIPHERAL_WIDTH_8BIT;
// 配置数据目的地址
dmaStructure.memory_addr = (uint32_t)g_recvDataBuf;
// 配置目的地址是固定的还是增长的
dmaStructure.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
// 配置目的数据传输位宽
dmaStructure.memory_width = DMA_MEMORY_WIDTH_8BIT;
// 配置数据传输最大次数
dmaStructure.number = MAX_BUF_SIZE;
// 配置DMA通道优先级
dmaStructure.priority = DMA_PRIORITY_HIGH;
// 初始化DMA
dma_init(g_uartHwInfo.dmaNo, g_uartHwInfo.dmaCh, &dmaStructure);
// 使能串口接收数据使用DMA
usart_dma_receive_config(g_uartHwInfo.uartNo, USART_RECEIVE_DMA_ENABLE);
// 使能DMA通道
dma_channel_enable(g_uartHwInfo.dmaNo, g_uartHwInfo.dmaCh);
}
wifi驱动复位
void HwresetWifiModule(void)
{
DBG_log("wifi module,now hwreset it!\n");
gpio_bit_reset(GPIOA, GPIO_PIN_7);
DelayNms(100);
gpio_bit_set(GPIOA, GPIO_PIN_7);
}
串口中断服务函数:
void USART1_IRQHandle(void)
{
if (usart_interrupt_flag_get(g_uartHwInfo.uartNo, USART_INT_FLAG_IDLE) != RESET)
{
// 获取中断标志位后清除中断标志位
usart_interrupt_flag_clear(g_uartHwInfo.uartNo, USART_INT_FLAG_IDLE);
usart_data_receive(g_uartHwInfo.uartNo);
DBG_log("uart recv str:%s\n", g_recvDataBuf);
dma_channel_disable(g_uartHwInfo.dmaNo, g_uartHwInfo.dmaCh);
dma_transfer_number_config(g_uartHwInfo.dmaNo, g_uartHwInfo.dmaCh, MAX_BUF_SIZE);
dma_channel_enable(g_uartHwInfo.dmaNo, g_uartHwInfo.dmaCh);
}
}
获取接受和发送字符:
char *RecvWifiModuleStr(void)
{
return (char*)g_recvDataBuf;
}
void ClearRecvWifiStr(void)
{
memset(g_recvDataBuf, 0, MAX_BUF_SIZE);
}
void SendWifiModuleStr(const char *sendStr)
{
DBG_log("uart send str:%d\n",sendStr);
while(*sendStr != '\0')
{
usart_data_transmit(g_uartHwInfo.uartNo, *sendStr);
while(RESET == usart_flag_get(g_uartHwInfo.uartNo, USART_FLAG_TBE));
sendStr++;
}
}
2.0 头文件
#ifndef _WIFI_DRV_H_
#define _WIFI_DRV_H_
#include <stdint.h>
void HwresetWifiModule(void);
void WifiModuleDrvInit(void);
void USART1_IRQHandle(void);
char *RecvWifiModuleStr(void);
void ClearRecvWifiStr(void);
void SendWifiModuleStr(const char *sendStr);
#endif