6561|10

12

帖子

0

TA的资源

一粒金砂(中级)

楼主
 

STM32F205串口1使用不正常,输出错误 [复制链接]

STM32新手~~~

// usart.c
void NVIC_Config(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
/* Enable the USARTx Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);        
}
void Uart_Init(void)
{
USART_InitTypeDef USART_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
uchar temp;
temp++;

// PA9 -- TX PA10 -- RX
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_USART1);  
GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_USART1);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_Init(GPIOA, &GPIO_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;
USART_Init(USART1, &USART_InitStructure);
USART_Cmd(USART1, ENABLE);
//USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
//NVIC_Config();
}
void UART1Write(uchar* data,uint len)
{
u16 i;
  for(i=0; i    UART1_SendBuf[i] = data[i];
  UART1_SendSum = len;
  USART_ITConfig(USART1, USART_IT_TXE, ENABLE);
    for (i=0; i     {
        USART_SendData(USART1, data[i]);
        while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET)
        {
            ;
        }
    }
}
void USART1_IRQHandler(void)
{   
     if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
    {
        UART1_BUF[UART1_COUNT++] = USART_ReceiveData(USART1);  //接收数据
        if(UART1_COUNT >= UART1BUF_SIZE_MAX)        //超过最大缓存,清零计数
        {
            UART1_COUNT = 0;
        }
    }
}

// main.c
uchar array[] = {0xaa, 0xaa, 0xaa, 0xaa, 0xaa};
SystemInit();
while(1)
{
  UART1Write(array, 1);
}

//-------------------------程序分割线------------------------------------
以上是usart.c和main.c中的内容 省略了头文件和一些参数的声明
遇到了两个问题:
1.发送的数据错误,不是0xaa,而是别的值。测试过Tx脚的波特率,应该是正确的,不知道是什么原因了,求解。
2.如果//NVIC_Config();去掉注释,则程序会一直死在里面出不来,后面的数据也不会发送。
以上配置都是从其他贴子中复制过来的,不知道错在哪里。
此帖出自stm32/stm8论坛

最新回复

这样主时钟才是120M RCC_GetClocksFreq(&RCC_Clocks);         printf("\r\n SYSCLK_Frequency %d", RCC_Clocks.SYSCLK_Frequency);         printf("\r\n HCLK_Frequency %d", RCC_Clocks.HCLK_Frequency);         printf("\r\n PCLK1_Frequency %d", RCC_Clocks.PCLK1_Frequency);         printf("\r\n PCLK2_Frequency %d", RCC_Clocks.PCLK2_Frequency);  详情 回复 发表于 2015-12-28 21:35
点赞 关注
 

回复
举报

6040

帖子

196

TA的资源

版主

推荐
 
奥义u 发表于 2014-6-16 11:15
1.我查看了下数据手册,上面说TXE中断标志位需要通过软件清楚,所以我在发送函数最后加了一句USART1->CR1 ...

1. 在函数外面清中断标志属于无意义的语句,如果未发生中断,清标志有什么用?如果发生中断了,则根本就不会执行那个语句。
2. 仔细看手册吧,看看能不能找到答案。
此帖出自stm32/stm8论坛
 
 

回复

1119

帖子

0

TA的资源

一粒金砂(中级)

沙发
 
有心无力啊~~~~~~~~~
此帖出自stm32/stm8论坛

点评

为什么这么说?  详情 回复 发表于 2014-6-14 15:42
 
 

回复

12

帖子

0

TA的资源

一粒金砂(中级)

板凳
 
kemasz 发表于 2014-6-14 15:34
有心无力啊~~~~~~~~~

为什么这么说?
此帖出自stm32/stm8论坛
 
 
 

回复

6040

帖子

196

TA的资源

版主

4
 
//NVIC_Config();
这个函数开启了串口1的中断,而你又在发送函数中开启了TXE中断,并且你中断函数里没有对TXE中断进行处理,所以会死在中断函数里面。
此帖出自stm32/stm8论坛

点评

1.我查看了下数据手册,上面说TXE中断标志位需要通过软件清楚,所以我在发送函数最后加了一句USART1->CR1 &= 0xff7f;可是结果还是死在循环中。[/backcolor] 2.为何在数据手册中说RXNE中断也需要通过软件清楚标志位  详情 回复 发表于 2014-6-16 11:15
 
 
 

回复

12

帖子

0

TA的资源

一粒金砂(中级)

5
 
lcofjp 发表于 2014-6-14 16:26
//NVIC_Config();
这个函数开启了串口1的中断,而你又在发送函数中开启了TXE中断,并且你中断函数里没有对 ...

1.我查看了下数据手册,上面说TXE中断标志位需要通过软件清楚,所以我在发送函数最后加了一句USART1->CR1 &= 0xff7f;可是结果还是死在循环中。
2.为何在数据手册中说RXNE中断也需要通过软件清楚标志位,可是正常使用的时候开启RXNE中断,每次只需要读取其中接收到的数据,程序就不会死在循环中?
此帖出自stm32/stm8论坛

点评

1. 在函数外面清中断标志属于无意义的语句,如果未发生中断,清标志有什么用?如果发生中断了,则根本就不会执行那个语句。 2. 仔细看手册吧,看看能不能找到答案。  详情 回复 发表于 2014-6-16 11:49
 
 
 

回复

6040

帖子

196

TA的资源

版主

7
 
Bit 5 RXNE: Read data register not empty
This bit is set by hardware when the content of the RDR shift register has been transferred
to the USART_DR register. An interrupt is generated if RXNEIE=1 in the USART_CR1
register. It is cleared by a read to the USART_DR register. The RXNE flag can also be
cleared by writing a zero to it. This clearing sequence is recommended only for multibuffer
communication.
0: Data is not received
1: Received data is ready to be read.
此帖出自stm32/stm8论坛
 
 
 

回复

12

帖子

0

TA的资源

一粒金砂(中级)

8
 
问题都解决了,做以下结贴:
第一个问题:
USART1是由PCLK2提供时钟,故读取如下的值:
  apbclock_SYSCLK = RCC_ClocksStatus.SYSCLK_Frequency;// 系统时钟
  apbclock_PCLK2 = RCC_ClocksStatus.PCLK2_Frequency; //PCLK2值
  Uart_Init();     // 使用的波特率是9600
  baud_div = USART1->BRR;    // 串口分频值
可以读出apbclock_SYSCLK = 0x7270E0000(120M)
apbclock_PCLK2 = 0x3938700(60M)
baud_div = 0x186A(6250)
计算baudrate = apbclock_PCLK2 / baud_div = 9600 一切都是如此完美
可,这一切都是假象,在stm32f2xx.h中有这么一句
#define HSE_VALUE            ((uint32_t)25000000) /*!< Value of the External oscillator in Hz */
原来这里把外围晶振定义为了25MHZ,修改为12MHZ,
从新读取apbclock_SYSCLK = 0x57600000(57.6M)
apbclock_PCLK2 = 0x28800000(28.8M)
baud_div = 0xBB8(3000)
USART1使用的实际频率是28.8MHZ,28800000 / 6250 = 4608(实际的波特率) 原来这才是真相啊
之后修改了RCC寄出器一些寄存器的值,使系统时钟达到120MHZ就可以了
第二个问题:打开NVIC_Config();会“死”在中断中
如4楼所说,因为开启了串口发送中断,但是没有对TXE中断进行处理,感谢4楼的回答
datesheet有如下说明:
Bit 7TXE: Transmit data register empty
This bit is set by hardware when the content of the TDR register has been transferred into
the shift register. An interrupt is generated if the TXEIE bit =1 in the USART_CR1 register. It
is cleared by a write to the USART_DR register.
0: Data is not transferred to the shift register
1: Data is transferred to the shift register)
即当向USART_DR中写数据的时候才可以将标志位清楚。所以我将中断函数做了如写的修改
void USART1_IRQHandler(void)
{
    if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
    {
        UART5_RcvBuf[UART5_COUNT++] = USART_ReceiveData(USART1);       
                //USART1->SR &= ~0x20;                                                                               
        }
        if(USART_GetITStatus(USART1, USART_IT_TXE) != RESET)
        {       
                UART1_SendCount++;
                /* Write one byte to the transmit data register */
                USART_SendData(USART1, 0xAA);
               
                if(UART1_SendCount >= 10)
                {
                        /* Disable the USART1 Transmit interrupt */
                        USART_ITConfig(USART1, USART_IT_TXE, DISABLE);
                }
        }
}
此帖出自stm32/stm8论坛
 
 
 

回复

2

帖子

2

TA的资源

一粒金砂(初级)

9
 
求STM32F205的串口1的中断程序
此帖出自stm32/stm8论坛
 
 
 

回复

85

帖子

0

TA的资源

一粒金砂(中级)

10
 
感谢楼主,另外补充:system_stm32f2xx.h里面的#define PLL_M      12也要修改,原来是25
此帖出自stm32/stm8论坛
 
 
 

回复

85

帖子

0

TA的资源

一粒金砂(中级)

11
 
sf116 发表于 2015-12-28 21:34
感谢楼主,另外补充:system_stm32f2xx.h里面的#define PLL_M      12也要修改,原来是25

这样主时钟才是120M
RCC_GetClocksFreq(&RCC_Clocks);
        printf("\r\n SYSCLK_Frequency %d", RCC_Clocks.SYSCLK_Frequency);
        printf("\r\n HCLK_Frequency %d", RCC_Clocks.HCLK_Frequency);
        printf("\r\n PCLK1_Frequency %d", RCC_Clocks.PCLK1_Frequency);
        printf("\r\n PCLK2_Frequency %d", RCC_Clocks.PCLK2_Frequency);
此帖出自stm32/stm8论坛
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/9 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表