新手入门
- 积分
- 27
- 金钱
- 27
- 注册时间
- 2012-12-6
- 在线时间
- 0 小时
|
本人现在需要将stm32串口1中断接收到的数据,通过串口2发送出去,可是现在出现的情况是,每次从串口调试助手向串口1发送数据时,串口1只能将数据转发出一次,当串口1接收到第二帧数据时,串口2并不能将数据转发出来,
于是我开始怀疑是不是串口1进入一次中断以后就死在里面了,一直出不了中断。在网上我也看到有人说是溢出中断,于是加了防溢出中断的程序,可是还是不行。
单步调试,发现溢出中断标志位一直是0,所以不存在溢出中断。我怀疑是不是串口1的USART1->SR中TXE位为1导致,串口一直在中断程序中,出不去。
发现将串口1接收到的数据同时通过串口1和2发送出去,就可以了。(这时USART1->SR中TXE位就置0了,估计就不会再死在中断里了)
不知道有没有大神知道怎么回事,实际上我根本没有开串口1的发送中断,即使发送缓冲区空中断标志置1,也不应该进入中断啊,结果现在如果想接收多帧数据,必须将接收到的数据同时通过串口1和2发出来,
而我不需要串口1发送数据,郁闷呐!!!
每一帧数据都已0X0D,0X0A,结束
u8 USART_RX_STA=0; // 是自己定义的一个接收状态标记
//接收状态
//bit7,接收完成标志
//bit6,接收到0x0d
//bit5~0,接收到的有效字节数目
求大神指教,小弟感激不尽。
附上代码;程序参考原子哥的,在此感谢!
int main(void)
{
Stm32_Clock_Init(9);//系统时钟设置
delay_init(72); //延时初始化
uart_init(72,9600); //串口1初始化
USART2_Init(36,9600);
LED_Init();
KEY_Init();
while(1)
{
u16 i;
if((USART_RX_STA&0x80))
{
for(i=0;i<(USART_RX_STA&0x3F);i++)
{
USART1->DR=USART_RX_BUF;//如果删掉这一行,串口2就只会发送出来一帧数据,然后估计就死在串口接收的中断程序中了
USART2->DR=USART_RX_BUF;
delay_ms(2);
}
USART_RX_STA=0;
}
}
}
串口2配置
//初始化IO 串口2
//pclk1 CLK1时钟频率(Mhz)
//bound:波特率
void USART2_Init(u32 pclk1,u32 bound)
{
RCC->APB2ENR|=1<<2; //使能PORTA口时钟
GPIOA->CRL&=0XFFFF00FF; //IO状态设置
GPIOA->CRL|=0X00008B00; //IO状态设置
RCC->APB1ENR|=1<<17; //使能串口时钟
RCC->APB1RSTR|=1<<17; //复位串口2
RCC->APB1RSTR&=~(1<<17);//停止复位
//波特率设置
USART2->BRR=(pclk1*1000000)/(bound);// 波特率设置
USART2->CR1|=0X200C; //1位停止,无校验位.
USART2->CR3=1<<7; //使能串口2的DMA发送
UART_DMA_Config(DMA1_Channel7,(u32)&USART2->DR,(u32)USART2_TX_BUF);//DMA1通道7,外设为串口2,存储器为USART2_TX_BUF
USART2->CR1|=1<<8; //PE中断使能
USART2->CR1|=1<<5; //接收缓冲区非空中断使能
MY_NVIC_Init(2,3,USART2_IRQChannel,2);//组2,优先级2,3
}
串口1配置
#include "sys.h"
#include "usart.h"
#include "led.h"
#include "delay.h"
#include "usart2.h"
//加入以下代码,支持printf函数,而不需要选择use MicroLIB
#if 1
#pragma import(__use_no_semihosting)
//标准库需要的支持函数
struct __FILE
{
int handle;
/* Whatever you require here. If the only file you are using is */
/* standard output using printf() for debugging, no file handling */
/* is required. */
};
/* FILE is typedef’ d in stdio.h. */
FILE __stdout;
//定义_sys_exit()以避免使用半主机模式
_sys_exit(int x)
{
x = x;
}
//重定义fputc函数
int fputc(int ch, FILE *f)
{
while((USART1->SR&0X40)==0);//循环发送,直到发送完毕
USART1->DR = (u8) ch;
return ch;
}
#endif
//////////////////////////////////////////////////////////////////
//串口1中断服务程序
//注意,读取USARTx->SR能避免莫名其妙的错误
u8 USART_RX_BUF[64]; //接收缓冲,最大64个字节.每个字节都是8位,超出此空间大小则溢出,认为接收错误
u8 USART_TX_BUF[64]={'m','b','c','d','e','f'}; //发送缓冲
u8 USART_BUF[64];
//接收状态
//bit7,接收完成标志
//bit6,接收到0x0d
//bit5~0,接收到的有效字节数目
//定义所有数据均以A结束。A作为结束标识
u8 USART_RX_STA=0; //接收状态标记 是自己定义的一个接收状态寄存器
void USART1_IRQHandler(void)//接收数据采用中断,将接收的数据存放在数组UART_RX_BUF[64];
{
u8 res,i;
USART1->CR1&=~(1<<8); //PE中断禁止
//溢出-如果发生溢出需要先读SR,再读DR寄存器 则可清除不断入中断的问题
if(USART1->SR&(1<<3))
{
USART1->SR&=~(1<<3); //读SR
USART_ReceiveData(USART1); //读DR
}
if(USART1->SR&(1<<5))//接收到数据
{
USART1->SR&=~(1<<5);//清除RXNE标志位
res=USART1->DR;
if((USART_RX_STA&0x80)==0)//接收未完成
{
if(USART_RX_STA&0x40)//接收到了0x0d
{
if(res!=0x0a)USART_RX_STA=0;//接收错误,重新开始
else USART_RX_STA|=0x80; //接收完成了
}else //还没收到0X0D
{
if(res==0x0d)USART_RX_STA|=0x40;
else
{
USART_RX_BUF[USART_RX_STA&0X3F]=res;
USART_RX_STA++;
if(USART_RX_STA>63)USART_RX_STA=0;//接收数据错误,重新开始接收
}
}
}
}
#endif
//初始化IO 串口1
//pclk2 CLK2时钟频率(Mhz)
//bound:波特率
//CHECK OK
//091209
void uart_init(u32 pclk2,u32 bound)
{
float temp;
u16 mantissa;
u16 fraction;
temp=(float)(pclk2*1000000)/(bound*16);//得到USARTDIV
mantissa=temp; //得到整数部分 将一个浮点型的数赋值给一个整型的数,会强制类型转换,省去小数部分
fraction=(temp-mantissa)*16; //得到小数部分
mantissa<<=4;
mantissa+=fraction;
RCC->APB2ENR|=1<<2; //使能PORTA口时钟
RCC->APB2ENR|=1<<14; //使能串口时钟
////////////////////max232的RXD接的是PA9,TXD接的是PA10,在此将PA10配置成上拉输入:8;将PA9配置成复用推挽输出:B
GPIOA->CRH&=0XFFFFF00F;
GPIOA->CRH|=0X000008B0;//IO状态设置
RCC->APB2RSTR|=1<<14; //复位串口1
RCC->APB2RSTR&=~(1<<14);//停止复位
//波特率设置
USART1->BRR=mantissa; // 波特率设置
USART1->CR1=0x0000;
USART1->CR1|=0X200C; //1位停止,无校验
//USART1->CR1&=0X200C; //1位停止,无校验位.
//使能接收中断
USART1->CR1|=1<<8; //PE中断使能
USART1->CR1|=1<<5; //接收缓冲区非空中断使能
MY_NVIC_Init(3,3,USART1_IRQChannel,2);//组2,最低优先级
}
|
|