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


豆皮 - 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 (258.02 KB)

IAR442工程

WORM_UART_INT.rar (259.01 KB)

IAR442工程

WORM_UART_520.rar (271.78 KB)

IAR520工程

WORM_UART_INT_520.rar (273.51 KB)

IAR520工程

1

评分人数

  • aleyn

我有一個夢想 擁有一大片土地 做個小地主 每天帶著一群狗奴才去調戲良家婦女....

不错1

谢谢了啊!这几天正愁着没资料看呢?

TOP

写的很详细,支持一下

TOP

谢谢

楼主,辛苦了.

TOP

楼主辛苦了,我下载此程序后实验了下,有个问题.
当函数单步执行到USART_SendData(USART1, (u8) ch);函数中执行:USARTx-->DR=(DATA & 0X1FF)时; 数据寄存器DR中,就是没有数据,导致receiveBUFFER中,没有数据,串口不工作,不知道为什么?
请楼主帮忙解释下?

TOP

好东东,讲的不错

好东东,讲的不错支持一下
http://shop35738797.taobao.com/

TOP

好东东支持一下,再支持一下,要不没分哈

好东东支持一下,再支持一下,要不没分哈
http://shop35738797.taobao.com/

TOP

还不会中断方式,学习学习

TOP

学习学习

TOP

学习学习

TOP

TOP

中断比较好使

TOP

开始涉及到中断优先级问题了,hoho

TOP

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



代码工程是IAR442上的

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

你rebuild一下 然后直接run 看看

如果对工程没有做修改的话 应该UART直接可以看到结果的
我有一個夢想 擁有一大片土地 做個小地主 每天帶著一群狗奴才去調戲良家婦女....

TOP

bucuo a

期待楼主更精彩表现!俺们都支持你呀

TOP

谢谢楼主了,真好

TOP

谢谢了啊!这几天正愁着没资料看呢?

TOP

需要用到串口,谢谢楼主

TOP

教程比较通俗易懂,我打算两天时间看完

TOP

没积分了,再支持一下!

TOP

很详细很具体  学习中

TOP

开始涉及到中断优先级问题了,hoho

TOP

好贴

好好学习usart 呵呵

TOP

USART通讯是基础中的基础呀,教程写得好,要是不要积分就能下载工程就更好了,希望安子能改变思路。

TOP

都很不错

都很不错

TOP

学习中!不过还没板子!

TOP

谢谢分享.

TOP

不错的教程,收下了。

TOP

看看。研究一下

TOP

感谢您的努力

TOP

Review opelc.org on alexa.com