#include "stm32f10x.h"
#include "serial.h"
#include "rtthread.h"
#include <rtdevice.h>
/***********************************************************************************************************
@ pin config USART1_REMAP = 0
@____________________________________________________________________________*/ #define UART1_GPIO_TX GPIO_Pin_9
#define UART1_GPIO_RX GPIO_Pin_10
#define UART1_GPIO GPIOA
#define RCC_APBPeriph_UART1 RCC_APB2Periph_USART1
#define UART1_TX_DMA DMA1_Channel4
#define UART1_RX_DMA DMA1_Channel5 /***********************************************************************************************************
@ Struct Definition
@____________________________________________________________________________*/
struct serial_ringbuffer serial_int_rx_buffer;
struct serial_ringbuffer serial_int_tx_buffer;
struct rt_serial_device serialx_device;
struct serial_user_data
{
USART_TypeDef* uart_device;
const char name[RT_NAME_MAX];
}; /***********************************************************************************************************
@ Hardware clock configuration
@____________________________________________________________________________*/
static void RCC_Configuration(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); /* Enable USART1 and GPIOA clocks */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE); } static void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure; /* Configure USART1 Rx (PA.10) as input floating */
GPIO_InitStructure.GPIO_Pin = UART1_GPIO_RX;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(UART1_GPIO, &GPIO_InitStructure); /* Configure USART1 Tx (PA.09) as alternate function push-pull */
GPIO_InitStructure.GPIO_Pin = UART1_GPIO_TX;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(UART1_GPIO, &GPIO_InitStructure); } static void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure; /* Enable the USART1 Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = ;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = ;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure); } /***********************************************************************************************************
@ model driven architecture interface
@____________________________________________________________________________*/
int serial_put_char(struct rt_serial_device *serial, char c)
{
USART_ClearFlag(USART1,USART_FLAG_TC);
USART_SendData(USART1, (u8) c);
while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
return c;
} int serial_get_char(struct rt_serial_device *serial)
{
int ch = -;
struct serial_user_data* user = (struct serial_user_data *)(serial->parent.user_data); if(USART_GetITStatus(user->uart_device, USART_IT_RXNE) != RESET)
{
/* interrupt mode receive */
RT_ASSERT(serial->parent.flag & RT_DEVICE_FLAG_INT_RX); ch = USART_ReceiveData(user->uart_device); /* clear interrupt */
USART_ClearITPendingBit(user->uart_device, USART_IT_RXNE);
}
return ch;
} rt_err_t serial_control(struct rt_serial_device *serial, int cmd, void *arg)
{
u16 int_flag; //interrupt flag
FunctionalState NewState;
struct serial_user_data *user = (struct serial_user_data *)serial->parent.user_data; switch(*(rt_uint32_t *)arg)
{
case RT_SERIAL_RX_INT:
{
int_flag = USART_IT_RXNE;
break;
}
case RT_SERIAL_TX_INT:
{
int_flag = USART_IT_TC;
break;
}
default :
{
break;
}
} switch(cmd)
{
case RT_DEVICE_CTRL_SET_INT:
{
NewState = ENABLE;
break;
}
case RT_DEVICE_CTRL_CLR_INT:
{
NewState = DISABLE;
break;
}
default:
{
break;
}
}
USART_ITConfig(user->uart_device, int_flag, NewState);
} rt_size_t serial_dma_transmit(struct rt_serial_device *serial, const char *buf, rt_size_t size)
{ }
/***********************************************************************************************************
@Struct declaration
@____________________________________________________________________________*/
struct serial_configure serial_config =
{
,
,
,
,
,
, };
struct serial_user_data serial_user_struct=
{
USART1,
"usart1"
};
rt_err_t stm32_serial_config(struct rt_serial_device *serial, struct serial_configure *cfg);
struct rt_uart_ops serial_ops =
{
stm32_serial_config,
serial_control,
serial_put_char,
serial_get_char,
serial_dma_transmit
}; rt_err_t stm32_serial_config(struct rt_serial_device *serial, struct serial_configure *cfg)
{
USART_InitTypeDef USART_InitStructure;
USART_ClockInitTypeDef USART_ClockInitStructure;
struct serial_user_data* user = (struct serial_user_data *)serial->parent.user_data; RCC_Configuration(); GPIO_Configuration(); NVIC_Configuration();
/*
serial->config = serial_config;
serial->int_rx = &serial_int_rx_buffer;
serial->int_tx = &serial_int_tx_buffer;
serial->ops = &serial_ops;
*/
USART_InitStructure.USART_BaudRate = ;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_ClockInitStructure.USART_Clock = USART_Clock_Disable;
USART_ClockInitStructure.USART_CPOL = USART_CPOL_Low;
USART_ClockInitStructure.USART_CPHA = USART_CPHA_2Edge;
USART_ClockInitStructure.USART_LastBit = USART_LastBit_Disable; USART_Init(user->uart_device, &USART_InitStructure);
USART_ClockInit(user->uart_device, &USART_ClockInitStructure); // rt_hw_serial_register(serial, user->name,
// RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM,
// user); /* enable interrupt */
USART_ITConfig(user->uart_device, USART_IT_RXNE, ENABLE); return RT_EOK;
} void rt_hw_usart2_init(void)
{
/* USART_InitTypeDef USART_InitStructure;
USART_ClockInitTypeDef USART_ClockInitStructure; RCC_Configuration(); GPIO_Configuration(); NVIC_Configuration();
*/
serialx_device.config = serial_config;
serialx_device.int_rx = &serial_int_rx_buffer;
serialx_device.int_tx = &serial_int_tx_buffer;
serialx_device.ops = &serial_ops;
/*
USART_InitStructure.USART_BaudRate = 115200;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_ClockInitStructure.USART_Clock = USART_Clock_Disable;
USART_ClockInitStructure.USART_CPOL = USART_CPOL_Low;
USART_ClockInitStructure.USART_CPHA = USART_CPHA_2Edge;
USART_ClockInitStructure.USART_LastBit = USART_LastBit_Disable; USART_Init(serial_user_struct.uart_device, &USART_InitStructure);
USART_ClockInit(serial_user_struct.uart_device, &USART_ClockInitStructure); */
rt_hw_serial_register(&serialx_device, serial_user_struct.name,
RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM,
&serial_user_struct); /* enable interrupt */
//USART_ITConfig(serial_user_struct.uart_device, USART_IT_RXNE, ENABLE); //stm32_serial_config(&serialx_device,&serial_config);
}
下面是第二份代码:
#include "stm32f10x.h"
#include "serial.h"
#include "rtthread.h"
#include <rtdevice.h>
/***********************************************************************************************************
@ pin config USART1_REMAP = 0
@____________________________________________________________________________*/ /* USART1_REMAP = 0 */
#define UART1_GPIO_TX GPIO_Pin_9
#define UART1_GPIO_RX GPIO_Pin_10
#define UART1_GPIO GPIOA
#define RCC_APBPeriph_UART1 RCC_APB2Periph_USART1
#define USART1_TX_DMA DMA1_Channel4
#define USART1_RX_DMA DMA1_Channel5 #if defined(STM32F10X_LD) || defined(STM32F10X_MD) || defined(STM32F10X_CL)
#define UART2_GPIO_TX GPIO_Pin_5
#define UART2_GPIO_RX GPIO_Pin_6
#define UART2_GPIO GPIOD
#define RCC_APBPeriph_UART2 RCC_APB1Periph_USART2
#else /* for STM32F10X_HD */
/* USART2_REMAP = 0 */
#define UART2_GPIO_TX GPIO_Pin_2
#define UART2_GPIO_RX GPIO_Pin_3
#define UART2_GPIO GPIOA
#define RCC_APBPeriph_UART2 RCC_APB1Periph_USART2
#define UART2_TX_DMA DMA1_Channel7
#define UART2_RX_DMA DMA1_Channel6
#endif /* USART3_REMAP[1:0] = 00 */
#define UART3_GPIO_RX GPIO_Pin_11
#define UART3_GPIO_TX GPIO_Pin_10
#define UART3_GPIO GPIOB
#define RCC_APBPeriph_UART3 RCC_APB1Periph_USART3
#define UART3_TX_DMA DMA1_Channel2
#define UART3_RX_DMA DMA1_Channel3 /***********************************************************************************************************
@ Struct Definition
@____________________________________________________________________________*/
struct serial_user_data
{
USART_TypeDef* uart_device;
const char name[RT_NAME_MAX];
}; /***********************************************************************************************************
@ Hardware clock configuration
@____________________________________________________________________________*/
static void RCC_Configuration(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); /* Enable USART1 and GPIOA clocks */
RCC_APB2PeriphClockCmd(RCC_APBPeriph_UART1 | RCC_APB2Periph_GPIOA, ENABLE); /* Enable AFIO and GPIOD clock */
RCC_APB1PeriphClockCmd(RCC_APBPeriph_UART2, ENABLE); } static void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure; /* Configure USART1 Rx (PA.10) as input floating */
GPIO_InitStructure.GPIO_Pin = UART1_GPIO_RX;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(UART1_GPIO, &GPIO_InitStructure); /* Configure USART1 Tx (PA.09) as alternate function push-pull */
GPIO_InitStructure.GPIO_Pin = UART1_GPIO_TX;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(UART1_GPIO, &GPIO_InitStructure); /* Configure USART2 Rx as input floating */
GPIO_InitStructure.GPIO_Pin = UART2_GPIO_RX;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(UART2_GPIO, &GPIO_InitStructure); /* Configure USART2 Tx as alternate function push-pull */
GPIO_InitStructure.GPIO_Pin = UART2_GPIO_TX;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(UART2_GPIO, &GPIO_InitStructure); } static void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure; /* Enable the USART1 Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority =;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = ;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure); /* Enable the USART2 Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = ;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = ;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure); } static void DMA_Configuration(void)
{
#if defined (RT_USING_UART3)
DMA_InitTypeDef DMA_InitStructure; /* fill init structure */
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; /* DMA1 Channel5 (triggered by USART3 Tx event) Config */
DMA_DeInit(UART3_TX_DMA);
DMA_InitStructure.DMA_PeripheralBaseAddr = USART3_DR_Base;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
/* As we will set them before DMA actually enabled, the DMA_MemoryBaseAddr
* and DMA_BufferSize are meaningless. So just set them to proper values
* which could make DMA_Init happy.
*/
DMA_InitStructure.DMA_MemoryBaseAddr = (u32);
DMA_InitStructure.DMA_BufferSize = ;
DMA_Init(UART3_TX_DMA, &DMA_InitStructure);
DMA_ITConfig(UART3_TX_DMA, DMA_IT_TC | DMA_IT_TE, ENABLE);
DMA_ClearFlag(DMA1_FLAG_TC2);
#endif
} /***********************************************************************************************************
@ model driven architecture interface
@____________________________________________________________________________*/
rt_err_t stm32_serial_config(struct rt_serial_device *serial, struct serial_configure *cfg); int serial_put_char(struct rt_serial_device *serial, char c)
{
struct serial_user_data* user = (struct serial_user_data *)(serial->parent.user_data); USART_ClearFlag(user->uart_device,USART_FLAG_TC);
USART_SendData(user->uart_device, c);
while (USART_GetFlagStatus(user->uart_device, USART_FLAG_TC) == RESET); return c;
} int serial_get_char(struct rt_serial_device *serial)
{
int ch = -;
struct serial_user_data* user = (struct serial_user_data *)(serial->parent.user_data); if(USART_GetITStatus(user->uart_device, USART_IT_RXNE) != RESET)
{
/* interrupt mode receive */
RT_ASSERT(serial->parent.flag & RT_DEVICE_FLAG_INT_RX); ch = USART_ReceiveData(user->uart_device); /* clear interrupt */
USART_ClearITPendingBit(user->uart_device, USART_IT_RXNE);
}
return ch;
} rt_err_t serial_control(struct rt_serial_device *serial, int cmd, void *arg)
{
FunctionalState NewState; struct serial_user_data *user = (struct serial_user_data *)serial->parent.user_data; switch(cmd)
{
case RT_DEVICE_CTRL_SET_INT:
{
NewState = ENABLE;
break;
}
case RT_DEVICE_CTRL_CLR_INT:
{
NewState = DISABLE;
break;
}
default:
{
break;
}
} switch(*(rt_uint32_t *)arg)
{
case RT_SERIAL_RX_INT:
{
USART_ITConfig(user->uart_device, USART_IT_RXNE, NewState);
break;
}
case RT_SERIAL_TX_INT:
{
USART_ITConfig(user->uart_device, USART_IT_TC, NewState);
break;
}
default :
{
break;
}
} return RT_EOK;
} rt_size_t serial_dma_transmit(struct rt_serial_device *serial, const char *buf, rt_size_t size)
{
return size;
} rt_err_t stm32_serial_config(struct rt_serial_device *serial, struct serial_configure *cfg)
{
USART_InitTypeDef USART_InitStructure;
USART_ClockInitTypeDef USART_ClockInitStructure;
struct serial_user_data* user = (struct serial_user_data *)serial->parent.user_data; RCC_Configuration();
GPIO_Configuration();
NVIC_Configuration();
DMA_Configuration(); USART_InitStructure.USART_BaudRate = cfg->baud_rate; switch(cfg->data_bits)
{
case :
{
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
break;
}
case :
{
USART_InitStructure.USART_WordLength = USART_WordLength_9b;
break;
}
default :
{
#ifndef RT_USING_FINSH
rt_kprintf("data bit set error\n");
#endif
break;
}
} switch(cfg->stop_bits)
{
case :
{
USART_InitStructure.USART_StopBits = USART_StopBits_1;
break;
}
case :
{
USART_InitStructure.USART_StopBits = USART_StopBits_2;
break;
}
case :
{
USART_InitStructure.USART_StopBits = USART_StopBits_0_5;
break;
}
case :
{
USART_InitStructure.USART_StopBits = USART_StopBits_1_5;
break;
}
default :
{
#ifndef RT_USING_FINSH
rt_kprintf("stopbits bit set error\n");
#endif
break;
}
} switch(cfg->parity)
{
case :
{
USART_InitStructure.USART_Parity = USART_Parity_No;
break;
}
case :
{
USART_InitStructure.USART_Parity = USART_Parity_Odd;
break;
}
case :
{
USART_InitStructure.USART_Parity = USART_Parity_Even;
break;
}
default :
{
#ifndef RT_USING_FINSH
rt_kprintf("data bit set error\n");
#endif
break;
}
} USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_ClockInitStructure.USART_Clock = USART_Clock_Disable;
USART_ClockInitStructure.USART_CPOL = USART_CPOL_Low;
USART_ClockInitStructure.USART_CPHA = USART_CPHA_2Edge;
USART_ClockInitStructure.USART_LastBit = USART_LastBit_Disable; USART_Init(user->uart_device, &USART_InitStructure);
USART_ClockInit(user->uart_device, &USART_ClockInitStructure); /* enable interrupt */
USART_ITConfig(user->uart_device, USART_IT_RXNE, ENABLE); return RT_EOK;
} /***********************************************************************************************************
@serial private function
@____________________________________________________________________________*/
struct rt_uart_ops serial_ops =
{
stm32_serial_config,
serial_control,
serial_put_char,
serial_get_char,
serial_dma_transmit
};
/***********************************************************************************************************
@Struct declaration
@____________________________________________________________________________*/
struct serial_configure serial_config =
{
, //USART_BaudRate
, //USART_WordLength
, //USART_StopBits
, //USART_Parity
, //
, //
//
};
struct serial_user_data serial_user_struct =
{
USART2, //hardware device
"uart2" //device name
};
struct serial_ringbuffer serial_int_rx_buffer;
struct serial_ringbuffer serial_int_tx_buffer;
struct rt_serial_device serialx_device; void rt_hw_serialx_register(void)
{
serialx_device.config = serial_config;
serialx_device.int_rx = &serial_int_rx_buffer;
serialx_device.int_tx = &serial_int_tx_buffer;
serialx_device.ops = &serial_ops; rt_hw_serial_register(&serialx_device, serial_user_struct.name,
RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM,
&serial_user_struct);
} struct serial_user_data serial_user_struct1 =
{
USART1, //hardware device
"uart1" //device name
};
struct rt_serial_device serialx_device1;
struct serial_ringbuffer serial_int_rx_buffer1;
struct serial_ringbuffer serial_int_tx_buffer1;
void rt_hw_serialx_register1(void)
{
serialx_device1.config = serial_config;
serialx_device1.int_rx = &serial_int_rx_buffer1;
serialx_device1.int_tx = &serial_int_tx_buffer1;
serialx_device1.ops = &serial_ops; rt_hw_serial_register(&serialx_device1, serial_user_struct1.name,
RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM,
&serial_user_struct1);
} #ifdef RT_USING_FINSH
#include <finsh.h>
static rt_uint8_t led_inited = ;
void usarts2(char *str)
{
rt_device_t usart; usart = rt_device_find("uart2");
rt_device_write(usart,,str,);
}
FINSH_FUNCTION_EXPORT(usarts2,str)
#endif