поборол уарт боле менее
Среда CooCox 1.7
- Код: выделить все
#include "stm32f10x_conf.h"
// USART Receiver buffer
#define RX_BUFFER_SIZE 350
uint8_t rx_buffer[RX_BUFFER_SIZE];
unsigned int rx_wr_index = 0,
rx_rd_index = 0,
rx_counter = 0;
uint8_t rx_buffer_overflow=0;
// USART Transmitter buffer
#define TX_BUFFER_SIZE 350
uint8_t tx_buffer[TX_BUFFER_SIZE];
unsigned int tx_wr_index=0,
tx_rd_index=0,tx_counter=0;
void USART_init(void);
uint8_t get_char(void);
void put_char(uint8_t);
void put_str(unsigned char *s);
void put_int(int32_t data);
int main()
{
USART_init();
put_str((unsigned char *)"Hellojjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj1!");
while (1)
{
put_char(get_char());
// put_str((unsigned char *)"Hellojjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj1!!");
}
}
void USART_init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
USART_InitTypeDef USART_InitStruct;
NVIC_InitTypeDef NVIC_InitStruct;
// Включаем тактирование GPIOA, USART1 и альтернативных функций AFIO
RCC_APB2PeriphClockCmd((RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO), ENABLE);
// Инициализации вывода PA9 - USART1_Tx
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9; // Настройки вывода PA9
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; // Скорость порта максимальная
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP; // Режим альтернативной функции, выход Push-Pull
GPIO_Init(GPIOA, &GPIO_InitStruct); // Заданные настройки сохраняем в регистрах GPIOА
// Инициализации вывода PA10 - USART1_Rx
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10; // Настройки вывода PA10
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING; // Input floating
GPIO_Init(GPIOA, &GPIO_InitStruct); // Заданные настройки сохраняем в регистрах GPIOА
USART_InitStruct.USART_BaudRate = 9600UL; // Скорость обмена 9600 бод
USART_InitStruct.USART_WordLength = USART_WordLength_8b; // Длина слова 8 бит
USART_InitStruct.USART_Parity = USART_Parity_No ; // Без проверки четности
USART_InitStruct.USART_StopBits = USART_StopBits_1; // 1 стоп-бит
USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None; // Без аппаратного контроля
USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; // Включен передатчик и приемник USART1
USART_Init(USART1, &USART_InitStruct); // Заданные настройки сохраняем в регистрах USART1
/* NVIC configuration */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStruct);
/* Enable USART */
USART_Cmd(USART1, ENABLE);
// USART_ITConfig(USART1, USART_IT_ORE, ENABLE);
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
USART_ITConfig(USART1, USART_IT_TXE, ENABLE);
}
void USART1_IRQHandler(void)
{
if(USART_GetITStatus(USART1, USART_IT_RXNE) == SET)
{
if ((USART1->SR & (USART_FLAG_NE|USART_FLAG_FE|USART_FLAG_PE|USART_FLAG_ORE)) == 0)
{
rx_buffer[rx_wr_index++]=(uint8_t)(USART_ReceiveData(USART1)& 0xFF);
if (rx_wr_index == RX_BUFFER_SIZE) rx_wr_index=0;
if (++rx_counter == RX_BUFFER_SIZE)
{
rx_counter=0;
rx_buffer_overflow=1;
}
}
else USART_ReceiveData(USART1);
//вообще здесь нужен обработчик ошибок, а мы просто пропускаем битый байт
}
if(USART_GetITStatus(USART1, USART_IT_ORE) == SET) //прерывание по переполнению буфера
{
USART_ReceiveData(USART1); //в идеале пишем здесь обработчик переполнения буфера, но мы просто сбрасываем этот флаг прерывания чтением из регистра данных.
}
if(USART_GetITStatus(USART1, USART_IT_TXE) == SET)
{
if (tx_counter)
{
--tx_counter;
USART_SendData(USART1,tx_buffer[tx_rd_index++]);
if (tx_rd_index == TX_BUFFER_SIZE) tx_rd_index=0;
}
else
{
USART_ITConfig(USART1, USART_IT_TXE, DISABLE);
}
}
}
uint8_t get_char(void)
{
uint8_t data;
while (rx_counter == 0);
data = rx_buffer[ rx_rd_index++ ];
if (rx_rd_index == RX_BUFFER_SIZE) rx_rd_index = 0;
USART_ITConfig(USART1, USART_IT_RXNE, DISABLE);
--rx_counter;
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
return data;
}
void put_char(uint8_t c)
{
while (tx_counter == TX_BUFFER_SIZE);
USART_ITConfig(USART1, USART_IT_TXE, DISABLE);
if (tx_counter || (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET))
{
tx_buffer[tx_wr_index++]=c;
if (tx_wr_index == TX_BUFFER_SIZE) tx_wr_index=0;
++tx_counter;
USART_ITConfig(USART1, USART_IT_TXE, ENABLE);
}
else
USART_SendData(USART1,c);
}
void put_str(unsigned char *s)
{
while (*s != 0)
put_char(*s++);
}
void put_int(int32_t data)
{
unsigned char temp[10],count=0;
if (data<0)
{
data=-data;
put_char('-');
}
if (data)
{
while (data)
{
temp[count++]=data%10+'0';
data/=10;
}
while (count)
{
put_char(temp[--count]);
}
}
else put_char('0');
}