打印

高手请进,USART配置问题

[复制链接]
2864|10
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
chunfeng12|  楼主 | 2008-4-11 08:08 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

STM32F103的串口2配置
/*******************************************************************************
* Function Name  : RCC_Configuration
* Description    : Configures the different system clocks.
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void RCC_Configuration(void)
{
  // RCC system reset(for debug purpose) 
  RCC_DeInit();

  // Enable HSE 
  RCC_HSEConfig(RCC_HSE_ON);

  // Wait till HSE is ready 
  HSEStartUpStatus = RCC_WaitForHSEStartUp();

  if(HSEStartUpStatus == SUCCESS)
  {
    // HCLK = SYSCLK 
    RCC_HCLKConfig(RCC_SYSCLK_Div1); 
  
    // PCLK2 = HCLK 
    RCC_PCLK2Config(RCC_HCLK_Div1); 

    // PCLK1 = HCLK/2 
    RCC_PCLK1Config(RCC_HCLK_Div2);
    
    // ADCCLK = PCLK2/4  
    RCC_ADCCLKConfig(RCC_PCLK2_Div4); 
 
    // Flash 2 wait state 
    FLASH_SetLatency(FLASH_Latency_2);
    // Enable Prefetch Buffer 
    FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);

    // PLLCLK = 8MHz * 9 = 72 MHz 
    RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);

    // Enable PLL  
    RCC_PLLCmd(ENABLE);

    // Wait till PLL is ready 
    while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
    {
    }

    // Select PLL as system clock source 
    RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

    // Wait till PLL is used as system clock source 
    while(RCC_GetSYSCLKSource() != 0x08)
    {
    }
  }

/* Enable peripheral clocks --------------------------------------------------*/
  // I2C1 Periph clock enable 
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
  // Enable DMA clock 
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA, ENABLE);  

  // TIM3  TIM4  I2C1  I2C2  USART  clock enable 
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3 | RCC_APB1Periph_TIM4 | RCC_APB1Periph_I2C1 | RCC_APB1Periph_I2C2
                          | RCC_APB1Periph_USART2, ENABLE);

  // GPIOA  B  C  D  E  AFIO clock enable 
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC
                         | RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE | RCC_APB2Periph_AFIO, ENABLE);
  //USART1  ADC1  clock enable
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_ADC1, ENABLE);
  
}
/*******************************************************************************
* Function Name  : NVIC_Configuration
* Description    : Configures Vector Table base location.
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void NVIC_Configuration(void)
{
  NVIC_InitTypeDef NVIC_InitStructure;
  
#ifdef  VECT_TAB_RAM  
  // Set the Vector Table base location at 0x20000000 
  NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0); 
#else  // VECT_TAB_FLASH  
  // Set the Vector Table base location at 0x08000000  
  NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);   
#endif
  
  // Configure 1 bits for preemption priority 
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
  

  // Enable the USART2 Interrupt
  NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQChannel;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);

}
/*******************************************************************************
* Function Name  : GPIO_Configuration
* Description    : Configure the GPIOD Pins.
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void GPIO_Configuration(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;

  // GPIOA AF Configuration 
  // PIN_2 for 485-2T   PIN_7 for OutLeft   Pin_9 for 485-1T   Pin_12 for CANT
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_7 | GPIO_Pin_9 | GPIO_Pin_12;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  GPIO_Init(GPIOA, &GPIO_InitStructure);
  
  // GPIOB AF Configuration 
  // Pin_7 for OutRight   
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
  
  GPIO_Init(GPIOB, &GPIO_InitStructure);
  
  // Enable the I2C1 Pins Software Remapping 
  GPIO_PinRemapConfig(GPIO_Remap_I2C1, ENABLE);

  // GPIOB AFOD Configuration
  // Pin_8.9 for I2C1 SCL.SDA    Pin_10.11 for I2C2 SCL.SDA
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
  GPIO_Init(GPIOB, &GPIO_InitStructure);
  
  // GPIOA Out Configuration 
  // Pin_0 for 5620Load   Pin_1 for 485-2RTS   Pin_5 for 5620DATA   Pin_8 for 485-1TRS
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_5 | GPIO_Pin_8;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  GPIO_Init(GPIOA, &GPIO_InitStructure);
  
  // GPIOB Out Configuration 
  // Pin_0 for 165-2CLK   Pin_12 for 165-1CLK   Pin_14 for 165-1EN   Pin_15 for 5620CLK
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_12 | GPIO_Pin_14 | GPIO_Pin_15;

  GPIO_Init(GPIOB, &GPIO_InitStructure);
  
  // GPIOC OutConfiguration 
  // Pin_5 for 165-2EN   Pin_6.7.8 for 595-1CLK.SCLK.EN   Pin_10.11.12 for 595-2CLK.SCLK.EN
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12;

  GPIO_Init(GPIOC, &GPIO_InitStructure);
  
  // GPIOD Out Configuration 
  // Pin_2 for BELL
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;

  GPIO_Init(GPIOD, &GPIO_InitStructure);  
  
  // GPIOA INFLOATING Configuration 
  // Pin_3 for 485-2R   Pin_4 for OCrossing   Pin_6 for LeftOCrossing   Pin_10 for 485-1R   Pin_11 for CANR 
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_6 | GPIO_Pin_10 | GPIO_Pin_11;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;

  GPIO_Init(GPIOA, &GPIO_InitStructure); 
  
  // GPIOB INFLOATING Configuration 
  // Pin_1 for SIGNAL   Pin_6 for RightOCrossing   Pin_13 for 165-1Out
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_6 | GPIO_Pin_13;

  GPIO_Init(GPIOB, &GPIO_InitStructure); 
  
  // GPIOC INFLOATING Configuration 
  // Pin_4 for 165-2Out   Pin_9 for Interrupt
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_9;

  GPIO_Init(GPIOC, &GPIO_InitStructure);
  
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15 | GPIO_Pin_11 | GPIO_Pin_10 | GPIO_Pin_12;

  GPIO_Init(GPIOD, &GPIO_InitStructure);
    
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9;

  GPIO_Init(GPIOD, &GPIO_InitStructure);
    
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;
    
    GPIO_Init(GPIOE, &GPIO_InitStructure);
  // GPIOC AIN Configuration
  // Pin_0.1.2.3 for ADC0.1.2.3   
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
  
  GPIO_Init(GPIOC, &GPIO_InitStructure);
}
/*******************************************************************************
* Function Name  : USART_Configuration
* Description    : Configures USART1 and USART2
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/

USART_InitStructure.USART_BaudRate = 9600;// bps.
  USART_InitStructure.USART_WordLength = USART_WordLength_8b;
  USART_InitStructure.USART_StopBits = USART_StopBits_2;
  USART_InitStructure.USART_Parity = USART_Parity_No ;
  USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_RTS_CTS;//None
  USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
  USART_InitStructure.USART_Clock = USART_Clock_Disable;
  USART_InitStructure.USART_CPOL = USART_CPOL_Low;
  USART_InitStructure.USART_CPHA = USART_CPHA_1Edge;
  USART_InitStructure.USART_LastBit = USART_LastBit_Enable;

  USART_Init(USART2, &USART_InitStructure);
    USART_ITConfig(USART2, USART_IT_TXE, ENABLE);
    //USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
  // Enable the USART2 
  USART_Cmd(USART2, ENABLE);
/*******************************************************************************
* Function Name  : main
* Description    : Main program
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
int main(void)
{
#ifdef DEBUG
  debug();
#endif

  /* System clocks configuration ---------------------------------------------*/
  RCC_Configuration();

  /* NVIC configuration ------------------------------------------------------*/
  NVIC_Configuration();

  /* GPIO configuration */
  GPIO_Configuration();

  
  // Configure USART
  USART_Configuration();


    GPIO_WriteBit(GPIOA, GPIO_Pin_1, Bit_RESET);


  while(1)
  {int i;
     for(i=1;i<20;i++)
      {
    GPIO_WriteBit(GPIOA, GPIO_Pin_1, Bit_RESET);

         Delay74595(500);Delay74595(500);Delay74595(500);
    USART_SendData(USART2,1);}
  }
}

单片机的串口配置
//===========================================
void Set485asTransmitter()
{    P16=0;
}
void Set485asReceiver()
{    P16=1;
}
void Send(unsigned char com)
{
    
    SBUF=com;
    while(TI==0){;}
    TI=0;
}
//================================================
void IniCPU110592Mhz(unsigned int baud_rate)
{//VB Setting  2400,n,8,1
     EX1=1;    //Enable Infra-Red Interruption
    IT1=1;    // Falling Edge Triger INT1 (Infra-red Interruption)
      PX1=1;    // INT1 (Infra-red) prioritary
     EX0=1;    // Zero-crossing Interruption Enabled   
    IT0=1;    // -_ INT0 (Zero Interruption)
//      TMOD=0x21;/*Timer 0(ZERO_CROSSING): MODE 1, Timer 1:MODE 2 (AUTOCHARGING)      
 // Timer0 for Zero_crossing    Timer1 for BAUD RATE for 4800     Timer2 for Infra_red 
    PS=1;
    switch(baud_rate)
      {
          case 1200: TH1=TL1=0xe8;PCON=0;TMOD=0x21;break;
          case 2400:  TH1=TL1=0xf4;PCON=0;TMOD=0x21;break;
          case 4800:  TH1=TL1=0xfa;PCON=0;TMOD=0x21;break;
          case 9600:  TH1=TL1=0xfd;PCON=0;TMOD=0x21;break;
          case 19200:  TH1=TL1=0xfd;PCON=0x80;TMOD=0x21;break;  
      }
    SCON=0x50;// 11 bit 
    ES=1;
    TR1=1;    // Start TIMER 1 for BAUD RATE generation
    T2CON=0x00;    //TF2:0,EXF2:0, RCLK:1, TCLK:1, EXEN2:0, TR2:1,  
    TR2=1;
    TH0=-(1000/256);
    TL0=-(1000%256);
    ET0=1;
    TR0=1;
    EA=1;    

//===========================================    
void SSIO(void) interrupt 4 using 1
{
   if(RI)
       {
       RI=0;
       SerialRe[SerialReIndicator]=SBUF;
       {SerialReIndicator+=1;}
       if(SerialReIndicator==30)
           SerialReIndicator=0;
           }
       }


//================================ 
void main(void)    
{uchar i;
    IniCPU110592Mhz(9600);
    while(1)    
        { 
            for(i=1;i<21;i++)
            //Set485asTransmitter();Delay(90);
                     //Send(0x1);
                Delay(90);

            //Set485asReceiver(); 
                
    
        }
    
}


通过以上配置后运行程序,STM32发送数据,单片机接收,单片机接收到的数据要么全是“0x01”,要么全是“0x64”,我查过是否是波特率的问题,经过验证,波特率都是9600.在配置上有什么问题吗?




沙发
chunfeng12|  楼主 | 2008-4-11 08:51 | 只看该作者

补充一下

如果使用单片机持续发送1~100,STM32来接收,接收到的数据可以保证100次无差错,单片机型号是AT89C55WD

使用特权

评论回复
板凳
chunfeng12|  楼主 | 2008-4-11 11:26 | 只看该作者

初步结果

在对STM32每发送一个数据后增加一个执行20000条空语句的延时后,单片机接收到的数据很稳定,可以保证100次无差错。这就是STM32与51速度上的差别吗?我观察了单片机每发送一个数据不加延时的波形,发现每次有100us左右的延时,再观察STM32每发送一个数据不加延时的波形,这时我的示波器已经捕获不到数据之间的延时。如果真的需要在每次发送一个数据STM32都要有个延时,这个延时的时间是不是太久了,资源上的浪费太大。如果改用STM32之间的通讯,成本上又增加了。期待折中的办法或更高明的结论。欢迎来讨论哈!!
迂腐只见,仅供参考!

使用特权

评论回复
地板
香水城| | 2008-4-11 11:47 | 只看该作者

发送完一个字节后,你必须等发送缓冲器变空之后才能再发

否则后面的字节要把前面的未传输完成的数据破坏掉,可以用轮询或中断获知发送缓冲器变空。请参考ST提供的例子。

使用特权

评论回复
5
chunfeng12|  楼主 | 2008-4-11 12:46 | 只看该作者

香主的说法似乎不能解释这个问题

曾经尝试过用同样的程序在STM32之间进行串口的收发数据,即使不对USART_FLAG_TXE位进行判断,观察接收到的数据也是完全可靠的。当然,还是对USART_FLAG_TXE位进行判断比较可靠。

使用特权

评论回复
6
香水城| | 2008-4-11 13:13 | 只看该作者

如果是这样,你就需要用示波器看看字节与字节之间的间距

字节与字节之间的间距被拉长,你的接收方才能正确接收,这表示接收方太慢了,你要想办法改进,加快接收方的处理速度。

使用特权

评论回复
7
chunfeng12|  楼主 | 2008-4-11 14:21 | 只看该作者

这个问题我在3楼已经想到

字节与字节之间的间距确实被拉长,也就是您说的“接收方太慢了”
我是个菜鸟,对待这种问题没了主见,所以发帖到网上寻求帮助o(∩_∩)o

使用特权

评论回复
8
香水城| | 2008-4-11 14:30 | 只看该作者

哈哈,你已经不是菜鸟了

3楼的分析表示你经过了自己的思考,我认为会思考的人都不菜。

赶快看看优化一下你的接收方吧。

使用特权

评论回复
9
chunfeng12|  楼主 | 2008-4-11 16:48 | 只看该作者

还是迷糊


加了2条限制语句
    while(USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET);

         while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); 
现在单片机的接收正常了,只是不明白这是为什么,这比延时程序的执行时间少多了,为什么把延时时间设置的比这个时间长,比3楼是说的那个短时,单片机的接收就不稳定了呢?

使用特权

评论回复
10
香水城| | 2008-4-11 17:09 | 只看该作者

通过示波器看看波形,应该可以找出差别

使用特权

评论回复
11
chunfeng12|  楼主 | 2008-4-11 18:18 | 只看该作者

弄了一天了

感谢香主的回应,不过还是没搞清楚具体的原因。真的菜了,都弄半导体4个月了!

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

8

主题

52

帖子

1

粉丝