OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 13093|回复: 4

串口1中断:接受一个字节再发回上位机,第一次发送不了,第二次才能发送;若发送其他单字节,会先发送之前那个字节一次,才能正常发送,请高手指点

[复制链接]

21

主题

123

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
354
金钱
354
注册时间
2012-3-11
在线时间
49 小时
发表于 2012-6-14 13:58:39 | 显示全部楼层 |阅读模式
#include"stm32f10x_lib.h"
void NVIC_Configuration(void);
void RCC_Configuration(void);
void GPIO_Configuration(void);

ErrorStatus HSEStartUpStatus;
USART_InitTypeDef USART_InitStructure;
USART_ClockInitTypeDef USART_ClockInitStructure;

int main()
{
 #ifdef DEBUG
  debug
 #endif
  RCC_Configuration();
  NVIC_Configuration();
  GPIO_Configuration();
/*串口传输速率的大小必须与RCC所设定的时钟相对应起来*/
  USART_InitStructure.USART_BaudRate = 9600;               //设置USART的传输速率
  /*设定数据的接收发送模式*/
  USART_InitStructure.USART_WordLength = USART_WordLength_8b;//在一帧中传输或接受8位数据位
  USART_InitStructure.USART_StopBits = USART_StopBits_1;     //定义在帧的结尾传输一个停止位
  USART_InitStructure.USART_Parity = USART_Parity_No;       //奇偶失能

  USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //指定硬件流控制模式RTS和CTS使能
  USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;   //指定使能或失能发送和接受模式 Tx发送使能和Rx接收使能

//  USART_ClockInitStructure.USART_Clock = USART_Clock_Disable;      //提升USART时钟时使能还是失能,钟低电平活动
//  USART_ClockInitStructure.USART_CPOL = USART_CPOL_Low;       //指定SLCK引脚上时钟的极性
 // USART_ClockInitStructure.USART_CPHA = USART_CPHA_2Edge;    //时钟第二个边缘进行数据捕获
//  USART_ClockInitStructure.USART_LastBit = USART_LastBit_Disable;  //在SCLK引脚上输出最后发送的那个数据字的脉冲不从SCLK输出
//  USART_ClockInit(USART1, &USART_ClockInitStructure);
  USART_Init(USART1, &USART_InitStructure);
/*输入输出的中断使能*/
//  USART_ITConfig(USART1, USART_IT_TXE, ENABLE);
  USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
  USART_Cmd(USART1, ENABLE);             //启动串口 使能USART1外设
    while(1)
  {
  }

}
 void NVIC_Configuration(void)
{
   NVIC_InitTypeDef NVIC_InitStructure;
#ifdef   VETB_TAB_RAM
  NVYC_SetVectorTable(NVIC_VectTab_RAM,0x0);
#else
  NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);   
#endif

  /* Enable the USART1 Interrupt */                         
  NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQChannel;   //通道设置为串口1中断(故后面应选择在"void USART1_IRQHandler(void)"开中断)
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;    //中断占先等级0
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;          //中断响应优先级0
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;           //打开中断
  NVIC_Init(&NVIC_InitStructure);
}
void RCC_Configuration(void)
{
    
    RCC_DeInit();
    RCC_HSEConfig(RCC_HSE_ON);
    HSEStartUpStatus=RCC_WaitForHSEStartUp();
      if(HSEStartUpStatus==SUCCESS)
      {
        FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
        FLASH_SetLatency(FLASH_Latency_2);
        RCC_HCLKConfig(RCC_SYSCLK_Div1);  
        RCC_PCLK2Config(RCC_HCLK_Div2);  //串口波特率的确定
        RCC_PCLK1Config(RCC_HCLK_Div2);
        RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
        RCC_PLLCmd(ENABLE); 
        while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY==RESET)) {}
        RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); 
        while(RCC_GetSYSCLKSource()!=0x08){}
      }
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_USART1, ENABLE);        //RCC中打开相应的串口|RCC_APB2Periph_GPIOE       
}
void GPIO_Configuration(void)
{
   GPIO_InitTypeDef GPIO_InitStructure;
 //  GPIO_PinRemapConfig(GPIO_Remap_USART1, ENABLE);      //改变指定管脚脚的映射 Changes the mapping of the specified pin
  /* Configure USART1 RTS (PA12) and USART1 Tx (PA9) 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);

  /* Configure USART2 CTS (PA11) and USART1 Rx (PA10) as input floating */
  GPIO_InitStructure.GPIO_Pin =GPIO_Pin_10;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

//  GPIO_InitStructure.GPIO_Pin=GPIO_Pin_1|GPIO_Pin_0|GPIO_Pin_2|GPIO_Pin_3;
//  GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
//  GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
 // GPIO_Init(GPIOE,&GPIO_InitStructure); 
}
//中断函数: (可在stm32f10x_.it.c中调用)

void USART1_IRQHandler(void)
{
   u8 RX_dat;                                                          //定义字符变量
    if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //判断发生接收中断
  {
 //  GPIO_WriteBit(GPIOE, GPIO_Pin_1, (BitAction)0x01);      //LED M
   RX_dat=(USART_ReceiveData(USART1));      //接收数据,整理除去前两位& 0x7F                                     
   USART_ClearITPendingBit(USART1,  USART_IT_RXNE);          //清除中断标志
   while(USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET){}//等待接收结束
//   USART_ITConfig(USART1, USART_IT_RXNE, DISABLE);          //关中断
       USART_SendData(USART1,RX_dat);             //发送数据      
 //      GPIO_WriteBit(GPIOE, GPIO_Pin_2, (BitAction)0x01);      //LED M
  }
}

这辈子只会两件事:这也不会,那也不会!
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

21

主题

123

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
354
金钱
354
注册时间
2012-3-11
在线时间
49 小时
 楼主| 发表于 2012-6-14 14:01:12 | 显示全部楼层
补充:库文件用的是3.5.0版本,片子是:stm32f103c8t6
这辈子只会两件事:这也不会,那也不会!
回复 支持 反对

使用道具 举报

11

主题

52

帖子

0

精华

初级会员

Rank: 2

积分
135
金钱
135
注册时间
2012-6-1
在线时间
3 小时
发表于 2012-6-14 14:11:08 | 显示全部楼层
void USART_Configuration(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    USART_InitTypeDef USART_InitStructure;

    /* 第1步:打開GPIO和USART部件的時鐘 */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);

    /* 第2步:將USART Tx的GPIO配置為推挽復用模式 */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    /* 第3步:將USART Rx的GPIO配置為浮空輸入模式
        由於CPU復位後,GPIO缺省都是浮空輸入模式,因此下面這個步驟不是必須的
        但是,我還是建議加上便於閱讀,並且防止其它地方修改了這個口線的設置參數
    */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    /*  第3步已經做了,因此這步可以不做
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    */
    GPIO_Init(GPIOA, &GPIO_InitStructure);


    /* 第4步:配置USART參數
        - BaudRate = 115200 baud
        - Word Length = 8 Bits
        - One Stop Bit
        - No parity
        - Hardware flow control disabled (RTS and CTS signals)
        - Receive and transmit enabled
    */
    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);

    /* 第5步:使能 USART, 配置完畢 */
    USART_Cmd(USART1, ENABLE);

    /* CPU的小缺陷:串口配置好,如果直接Send,則第1個字節發送不出去
        如下語句解決第1個字節無法正確發送出去的問題 */
    USART_ClearFlag(USART1, USART_FLAG_TC);     /* 清發送外城標誌,Transmission Complete flag */
}
回复 支持 反对

使用道具 举报

21

主题

123

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
354
金钱
354
注册时间
2012-3-11
在线时间
49 小时
 楼主| 发表于 2012-6-14 14:46:50 | 显示全部楼层
貌似没用
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165371
金钱
165371
注册时间
2010-12-1
在线时间
2110 小时
发表于 2012-6-14 16:33:11 | 显示全部楼层
在USART_SendData(USART1,RX_dat);             //发送数据     
之前添加一句等待发送区空试试.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-2-26 06:55

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表