由于才学STM32,所以有地方搞不清楚,调试串口时出现了问题。
测试目的:PC发送任意数据到STM32的USART1上,接收到再发送回PC上。
调试结果:PC发送一个十六进制,STM32接收到会发回到PC上,并是正确的,但发送2字节以上的数据就不对了。
用的是中断,忘高手指点!不胜感谢!:handshake 附上代码
配置串口:
int main(void)
{
/* System Clocks Configuration */
RCC_Configuration();
/* NVIC configuration */
NVIC_Configuration();
/* Configure the GPIO ports */
GPIO_Configuration();
USART_Configuraton();
while(1)
{
Handle_USART1();
}
}
/**
* @brief Configures the different system clocks.
* @param None
* @retval None
*/
void RCC_Configuration(void)
{
/* Enable GPIO clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD|RCC_APB2Periph_GPIOA|RCC_APB2Periph_USART1| RCC_APB2Periph_AFIO, ENABLE);
}
/**
* @brief Configures the different GPIO ports.
* @param None
* @retval None
*/
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* Configure USAR1 Rx as input floating */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* Configure USAR1 Tx as alternate function push-pull */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/*配置LED*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_2 | GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOD, &GPIO_InitStructure);
}
/**
* @brief Configures the nested vectored interrupt controller.
* @param None
* @retval None
*/
void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
/* Configure the NVIC Preemption Priority Bits */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
/* Enable the USART1 Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; //通道设置为串口1中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //中断占先等级0
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //中断响应优先级0
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //打开中断
NVIC_Init(&NVIC_InitStructure); //初始化
}
//-----------------------
void USART_Configuraton(void)
{
USART_InitTypeDef USART_InitStructure;
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;
/* Configure USARTy */
USART_Init(USART1, &USART_InitStructure);
/* Enable USARTy Receive and Transmit interrupts */
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
//USART_ITConfig(USART1, USART_IT_TXE, ENABLE);
/* Enable the USARTy */
USART_Cmd(USART1, ENABLE);
}
串口处理部分:
#define COM1RIBUFMAX 128
#define COM1TIBUFMAX 256
u16 COM1ti_wait = 1;
int COM1rirear = 0,COM1tirear = 0;
int COM1ribufcount = 0,COM1tibufcount = 0;
unsigned char COM1ribuf[COM1RIBUFMAX];
unsigned char COM1tibuf[COM1TIBUFMAX];
u16 Reciveok = 0;
//----------------------------------------------------------------------------------------------
//读COM1接收缓存区
void WrCOM1RiBuf(unsigned char c)
{
COM1ribuf[COM1rirear] = c;
COM1rirear++;
if(COM1rirear == COM1RIBUFMAX) COM1rirear = 0;
if(COM1ribufcount != COM1RIBUFMAX) COM1ribufcount++;
}
//----------------------------------------------------------------------------------------------
//取自定义发送缓冲区中数据
unsigned char RdCOM1TiBuf(void)
{
int p ;
unsigned char c ;
p = COM1tirear - COM1tibufcount;
if(p < 0) p = COM1TIBUFMAX + p;
COM1tibufcount--;
c = COM1tibuf[p];
return c;
}
//----------------------------------------------------------------------------------------------
//向自定义发送缓冲区写入数据
void WrCOM1TiBuf(unsigned char c)
{
COM1tibuf[COM1tirear] = c;
COM1tirear++;
if(COM1tirear == COM1TIBUFMAX) COM1tirear = 0;
if(COM1tibufcount != COM1TIBUFMAX) COM1tibufcount++;
if (COM1ti_wait)
{
USART1->CR1 |= USART_FLAG_TXE; //置发送中断
COM1ti_wait = 0;
}
}
//----------------------------------------------------------------------------------------------
unsigned char RdCOM1RiBuf(void)
{
int p;
unsigned char c;
p = COM1rirear - COM1ribufcount;
if(p < 0) p = COM1RIBUFMAX + p;
COM1ribufcount--;
c = COM1ribuf[p];
return c;
}
/*****************************************************************************/
void USART1_IRQHandler(void)
{
//串口接收中断
volatile unsigned int IIR;
IIR = USART1->SR;
if (IIR & USART_FLAG_RXNE)
{
//必须清除中断标志
USART1->SR &= ~USART_FLAG_RXNE; // clear interrupt
//放数据进缓冲区
WrCOM1RiBuf(USART1->DR & 0x1FF);
}
//串口发送中断
if (IIR & USART_FLAG_TXE)
{
//必须清除中断标志
USART1->SR &= ~USART_FLAG_TXE; // clear interrupt
if(COM1tibufcount)
{
//取发送缓存中数据
USART1->DR = (RdCOM1TiBuf() &0x1FF);
}
else
{
COM1ti_wait = 1;
USART1->CR1 &= ~USART_FLAG_TXE;
}
}
}
/*******************************************************************************/
void Handle_USART1(void)
{
unsigned char cmdata;
//接收缓存中有数据就放到发送缓存中,并发送
while(COM1ribufcount >0)
{
cmdata = RdCOM1RiBuf();
WrCOM1TiBuf(cmdata);
}
} |