豆皮 - STM32开发板入门教程(四) - 串口通讯 UART (原创)

发布: 2008-10-26 17:02 | 作者: littleworm | 来源: StmFans思蜕盟 OPELC 自由电子联盟


豆皮 - STM32开发板入门教程(四) - 串口通讯 UART  (原创)


版权所有 STMFANS 原创,转载请保留出处

http://www.stmfans.com/bbs/viewthread.php?tid=1084&extra=page%3D1&frombbs=1




一步一步的走 GPIO  按键  LED  定时器都说了 下面开始串口UART咯

本教程的主角是:串口 UART  




通用同步异步收发器(USART)提供了一种灵活的方法来与使用工业标准NR 异步串行数据格式的外部设备之间进行全双工数据交换。 USART利用分数波特率发生器提供宽范围的波特率选择。
它支持同步单向通信和半双工单线通信。它也支持LIN(局部互连网),智能卡协议和IrDA(红外数据组织)SIR ENDEC规范,以及调制解调器(CTS/RTS)操作。它还允许多处理器通信。用于多缓冲器配置的DMA方式,可以实现高速数据通信。

主要特性:
   全双工的,异步通信
   NR 标准格式
   分数波特率发生器系统
        -发送和接收共用的可编程波特率,最高到4.5Mbits/s
   可编程数据字长度(8位或9位)
   可配置的停止位        -支持1或2个停止位
   LIN主发送同步断开符的能力以及LIN从检测断开符的能力
        -  当USART硬件配置成LIN时,生成13位断开符;检测10/11位断开符
   发送方为同步传输提供时钟
   IRDA SIR 编码器解码器
        -  在正常模式下支持3/16位的持续时间
   智能卡模拟功能
        -  智能卡接口支持ISO7816        -3标准里定义的异步协议智能卡
        -  智能卡用到的0.5和1.5个停止位
   单线半双工通信
   使用DMA的可配置的多缓冲器通信
        -  在保留的SRAM里利用集中式DMA缓冲接收/发送字节
   单独的发送器和接收器使能位
   检测标志
        -  接收缓冲器满
        -  发送缓冲器空
        -  传输结束标志
   校验控制
        -  发送校验位
        -  对接收数据进行校验
   四个错误检测标志
        -  溢出错误
        -  噪音错误
        -  帧错误
        -  校验错误
  10个带标志的中断源
        -  CTS改变
        -  LIN断开符检测
        -  发送数据寄存器
        -  发送完成
        -  接收数据寄存器
        -  检测到总线为空
        -  溢出错误
        -  帧错误
        -  噪音错误
        -  校验错误
   多处理器通信         -        - 如果地址不匹配,则进入静默模式
   从静默模式中唤醒(通过空闲总线检测或地址标志检测)
   两种唤醒接收器的方式
        -  地址位(MSB)
        -  空闲总线





STM32的串口配置 也挺方便的

首先是配置UART的GPIO口
/*******************************************************************************
* Function Name  : UART1_GPIO_Configuration
* Description        : Configures the uart1 GPIO ports.
* Input                    : None
* Output                 : None
* Return                 : None
*******************************************************************************/
void UART1_GPIO_Configuration(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    // Configure USART1_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);

    // Configure USART1_Rx as input floating
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOA, &GPIO_InitStructure);  
}

然后是配置串口参数


   /* 如果使用查询的方式发送和接收数据 则不需要使用串口的中断  
      如果需要使用中断的方式发送和接收数据 则需要使能串口中断
     函数原形   void USART_ITConfig(USART_TypeDef* USARTx, u16 USART_IT, FunctionalState NewState)
     功能描述   使能或者失能指定的 USART 中断
     
        USART_IT                     描述
        USART_IT_PE         奇偶错误中断
        USART_IT_TXE       发送中断
        USART_IT_TC          传输完成中断
        USART_IT_RXNE    接收中断
        USART_IT_IDLE      空闲总线中断
        USART_IT_LBD       LIN中断检测中断
        USART_IT_CTS       CTS中断
        USART_IT_ERR       错误中断

   */


/*******************************************************************************
* Function Name  : UART1_Configuration
* Description        : Configures the uart1
* Input                    : None
* Output                 : None
* Return                 : None
*******************************************************************************/
void UART1_Configuration(void)
{

  USART_InitTypeDef USART_InitStructure;
  /* USART1 configured as follow:
        - BaudRate = 9600 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 = 9600;
  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 the USART1*/
  USART_Init(USART1, &USART_InitStructure);

  /* Enable USART1 Receive and Transmit interrupts */
  USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
   

  /* Enable the USART1 */
  USART_Cmd(USART1, ENABLE);  
}


发送一个字符
[/*******************************************************************************
* Function Name  : Uart1_PutChar
* Description        : printf a char to the uart.
* Input                    : None
* Output                 : None
* Return                 : None
*******************************************************************************/
u8 Uart1_PutChar(u8 ch)
{
    /* Write a character to the USART */
    USART_SendData(USART1, (u8) ch);
    while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET)
   {
   }
   return ch;
}


发送一个字符串
/*******************************************************************************
* Function Name  : Uart1_PutString
* Description        : print a string to the uart1
* Input                    : buf为发送数据的地址 , len为发送字符的个数
* Output                 : None
* Return                 : None
*******************************************************************************/
void Uart1_PutString(u8* buf , u8 len)
{
    for(u8 i=0;i<len;i++)
    {
        Uart1_PutChar(*buf++);
    }
}


如果UART使用中断发送数据 则需要修改stm32f10x_it.c 中的串口中断函数 并且需要修改void NVIC_Configuration(void)函数

在中断里面的处理 原则上是需要简短和高效 下面的流程是 如果接收到255个字符或者接收到回车符 则关闭中断 并且把标志位UartHaveData 置1

/*******************************************************************************
* Function Name  : USART1_IRQHandler
* Description        : This function handles USART1 global interrupt request.
* Input                    : None
* Output                 : None
* Return                 : None
*******************************************************************************/
void USART1_IRQHandler(void)
{
  if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
  {
    /* Read one byte from the receive data register */
    RxBuffer[ RxCounter ] = USART_ReceiveData(USART1);      
    if( RxCounter == 0xfe || '\r' == RxBuffer[ RxCounter ] )
    {
      /* Disable the USART1 Receive interrupt */
      USART_ITConfig(USART1, USART_IT_RXNE, DISABLE);
      RxBuffer[ RxCounter ] = '\0';
      UartHaveData = 1;
    }
   
    RxCounter++;
  }
}


修改NVIC_Configuration函数

/*******************************************************************************
* Function Name  : NVIC_Configuration
* Description        : Configures NVIC and 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 the NVIC Preemption Priority Bits */  
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
  
  /* Enable the USART1 Interrupt */
  NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQChannel;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
  
}


至此 串口就可以工作起来了 附件中的程序功能是 开机后 从串口中输出2行信息 然后就等待接收串口数据 并且把接收到的数据发回到PC机上来 附件有2个 一个是查询方式的 一个是中断方式的



完整工程在附件里

敬请继续关注 豆皮的的教程会逐步推出



[ 本帖最后由 littleworm 于 2008-11-24 12:49 编辑 ]

WORM_UART.rar
(2008-10-26 18:07:34, Size: 258 KB, Downloads: 708)

WORM_UART_INT.rar
(2008-10-26 18:07:34, Size: 259 KB, Downloads: 645)

WORM_UART_520.rar
(2008-11-24 12:49:54, Size: 272 KB, Downloads: 769)

WORM_UART_INT_520.rar
(2008-11-24 12:49:54, Size: 274 KB, Downloads: 747)

yunfei7370 (2008-11-01 20:37:05)
谢谢了啊!这几天正愁着没资料看呢?
lostgb (2008-11-01 22:44:32)
写的很详细,支持一下
hover_sky (2008-11-05 09:16:50)
楼主,辛苦了.
beeqer (2008-11-08 08:46:44)
楼主辛苦了,我下载此程序后实验了下,有个问题.
当函数单步执行到USART_SendData(USART1, (u8) ch);函数中执行:USARTx-->DR=(DATA & 0X1FF)时; 数据寄存器DR中,就是没有数据,导致receiveBUFFER中,没有数据,串口不工作,不知道为什么?
请楼主帮忙解释下?
ddllxxrr (2008-11-09 07:08:48)
好东东,讲的不错支持一下
ddllxxrr (2008-11-09 07:09:55)
好东东支持一下,再支持一下,要不没分哈
kbgyzp (2008-11-10 13:34:30)
还不会中断方式,学习学习
kbgyzp (2008-11-10 13:35:16)
学习学习
kbgyzp (2008-11-10 13:37:27)
学习学习
wjmcu (2008-11-18 09:40:45)
yayongzhang (2008-11-18 16:24:31)
中断比较好使
yayongzhang (2008-11-18 16:25:47)
开始涉及到中断优先级问题了,hoho
littleworm (2008-11-18 16:33:02)

QUOTE:

原帖由 beeqer 于 2008-11-8 08:46 发表
楼主辛苦了,我下载此程序后实验了下,有个问题.
当函数单步执行到USART_SendData(USART1, (u8) ch);函数中执行:USARTx-->DR=(DATA & 0X1FF)时; 数据寄存器DR中,就是没有数据,导致receiveBUFFER中,没有数据,串口不工作 ...
代码工程是IAR442上的

在我的板子上测试通过了的

你rebuild一下 然后直接run 看看

如果对工程没有做修改的话 应该UART直接可以看到结果的
isd2560 (2008-11-27 10:40:28)
期待楼主更精彩表现!俺们都支持你呀
missyou198 (2008-12-05 09:08:38)
谢谢楼主了,真好
jameslee2005 (2008-12-05 10:54:42)
谢谢了啊!这几天正愁着没资料看呢?
c51avr (2008-12-06 11:05:24)
需要用到串口,谢谢楼主
caixingang (2008-12-09 19:28:06)
教程比较通俗易懂,我打算两天时间看完
caixingang (2008-12-09 19:34:17)
没积分了,再支持一下!
abo83819 (2008-12-09 21:52:15)
很详细很具体  学习中