Universal asynchronous receiver transmitter (UART)

UART基本介绍:

通用异步收发器UART他的功能非常强大

我们只使用UART的全双工异步通信功能,使用中断接收数据。

UART_RX:串行数据输入。

UART_TX:串行数据输出。

硬件支持:

连接串口(RS232)实现在超级终端里输入输出

软件支持:

超级终端,teraterm-4.75

1、配置UART,我们使用UART2

(1)设置波特率为115200,设置数据字段长为8字,使用1个停止位,无基偶校验,UART Clock disabled,打开发送和接收使能

  以上基本设置使用一个函数进行封装设置:

  函数内部实现:

    设置数据字段长为8字:UART2->CR1 |= 0x00;

    使用1个停止位: UART2->CR3 |= 0x00;

    使用基数位校验:UART2->CR1 |= 0x00;

    UART Clock disabled、打开发送和接收使能等等

(2)打开接收中断,当接收发生或者溢出发生时候,产生接收中断

(3)UART使能

 UART2->CR1 &= (uint8_t)(~0x02);

(4)全局中断使能

 enableInterrupts();

总体UART配置函数实现如下代码所示:

 1 static void UART2_Config(void)
 2 {
 3   /* EVAL COM (UART) configuration -----------------------------------------*/
 4   /* USART configured as follow:
 5         - BaudRate = 115200 baud
 6         - Word Length = 8 Bits
 7         - One Stop Bit
 8         - Odd parity
 9         - Receive and transmit enabled
10         - UART Clock disabled
11   */
12   UART2_Init((uint32_t)115200, UART2_WORDLENGTH_8D,UART2_STOPBITS_1, UART2_PARITY_NO,
13                    UART2_SYNCMODE_CLOCK_DISABLE, UART2_MODE_TXRX_ENABLE);
14
15   /* Enable the UART Receive interrupt: this interrupt is generated when the UART
16     receive data register is not empty */
17   UART2_ITConfig(UART2_IT_RXNE_OR, ENABLE);
18
19   /* Enable the UART Transmit complete interrupt: this interrupt is generated
20      when the UART transmit Shift Register is empty */
21   UART2_ITConfig(UART2_IT_TXE, ENABLE);
22
23   /* Enable UART */
24   UART2_Cmd(ENABLE);
25
26     /* Enable general interrupts */
27   enableInterrupts();
28 }

UART2_Config

2、UART输出功能

如果直接使用C语言的printf函数,只会在编译器的Terminal-I/O中输出,不会在我们想要的超级终端里面输出,所以需要对输出函数做重定向;

实现每次想要输出的时候,将信息打印到超级终端中,故重定向putchar (int c)函数,在函数内使用UART的传送数据功能就可以了,即将要输出的信息写入UART的数据寄存器

 1 #define PUTCHAR_PROTOTYPE int putchar (int c)
 2 ...
 3 /**
 4   * @brief Retargets the C library printf function to the UART.
 5   * @param c Character to send
 6   * @retval char Character sent
 7   */
 8 PUTCHAR_PROTOTYPE
 9 {
10   /* Write a character to the UART2 */
11   UART2_SendData8(c);
12   /* Loop until the end of transmission */
13   while (UART2_GetFlagStatus(UART2_FLAG_TXE) == RESET);
14
15   return (c);
16 }

3、UART输入功能

输入功能实际上是字符串处理过程的实现,在超级终端中输入内容实际上是在UART的数据寄存器里写内容,所我们只需要去数据寄存器里面读取并处理字符串即可;

  • 处理函数功能

首先我们得定义一个支持终端回显的函数uart_GetStr,其中功能包括:

(1)当有我们在终端里敲键盘的时候会立马有正确的内容显示;

(2)当按下特殊按键的时候会有正确的反应;比如backspace会删除一个字符;return会表示输入完毕进入发送;

(3)对于其他特殊案件处理不了应当屏蔽;比如不想实现delete功能,删除刚刚读入的delete字符,并不会回显;

  • 函数实现:

uart_GetStr传入的第一个参数是指向接收数据数组的指针,第二个参数表示是否允许回显;

几个有用变量:

  __IO uint8_t ReciveBuff = 0; //save the current char

  uint8_t RxBuffer[32] = {0}; //save the input string

  __IO uint8_t RxCounter = 0; //the length of valid string

所以,RxBuffer就是uart_GetStr函数的第一个参数,在uart_GetStr函数内部会对每一个字符进行处理,正确的字符才放入RxBuffer中;

  1 //====================================================================================
  2 //Function Name    | dbg_GetStr
  3 //Description    | Get string via UART port.
  4 //Input        | *p_recv_buff : pointer to receive data buffer
  5 //        | b_echo_on : echo back on or off
  6 //Output    | detect terminal(0x0d character) :TRUE or FALSE
  7 //Remark    |
  8 //====================================================================================
  9 uint8_t uart_GetStr(uint8_t *p_recv_buff, bool b_echo_on)
 10 {
 11     uint8_t b_end = 0;
 12     int i;
 13     static uint8_t len = 0;
 14     static uint8_t pos = 0;
 15     static uint8_t esc_seq = 0;
 16     uint8_t c;
 17
 18     // Get a character.
 19     if((c = ReciveBuff) == 0){
 20           return 0;
 21     }
 22     // echo back
 23     if(b_echo_on){
 24           printf("%c",c); //show the input
 25     }
 26
 27     //Check
 28     switch(esc_seq){
 29         // Normal
 30         case 0:
 31           // Return(Terminate)
 32           if(c == 0x0d){
 33             p_recv_buff[len] = 0;
 34             len =  pos = 0;    // clear
 35             if(b_echo_on){
 36               printf("\n");
 37             }
 38             b_end = 1;
 39           }
 40           // Back Space
 41           else if(c == 0x08){
 42             if(len){
 43               if(b_echo_on){
 44                 printf(" ");
 45                 printf("%c",0x08);      // BS
 46               }
 47               len--;    // update length info.
 48               pos--;    // update pos info
 49             }
 50           }
 51           // ESC
 52           else if(c == 0x1b){
 53             esc_seq = 1;
 54           }
 55           // DEL
 56           else if(c == 0x7f){
 57             if(len){
 58               DeleteChar(pos, len, &p_recv_buff[0]);
 59               len --;   // update length info
 60               if(b_echo_on){
 61                 printf("%s",&p_recv_buff[pos]);
 62                 printf(" ");
 63                 printf("%c",0x08);      // BS
 64         // move cursor to character end.
 65         for(i = 0; i < len - pos; i++){
 66                   printf("%c",0x1b);    // ESC
 67                   printf("%c",‘[‘);
 68                   printf("%c",‘D‘);
 69                 }
 70               }
 71             }
 72           }
 73           // Other
 74           else{
 75             p_recv_buff[pos] = c;
 76             len++;      // update length info
 77             pos++;      // update pos info
 78           }
 79           break;
 80           // ESC SEQ -> 1st
 81         case 1:
 82           if(c == ‘[‘){
 83             esc_seq = 2;        // Next seq.
 84           }
 85           else{
 86             esc_seq = 0;        // not support(to normal)
 87           }
 88           break;
 89           //ESC SEQ -> 2nd
 90         case 2:
 91           if(c==‘D‘){
 92             if(pos){
 93               pos--;    // "<-" key
 94             }
 95           }
 96           else if(c==‘C‘){
 97             if(pos < len){
 98               pos++;    // "->" key
 99             }
100           }
101           esc_seq = 0;  // To normal
102           break;
103         }
104
105         return (b_end);
106 }

uart_GetStr

uart_GetStr函数值为0或者为1,只有在终端中输入回车时才会返回1,其他情况均返回0;

有了这一特点,我们在使用这个函数的时候,只需要获取返回值,当返回0时,把处理过后的、用户正确输入的字符串打印出来看;

  • 运行流程

(1)当终端中有输入的时候,即数据寄存器不为空,从而触发接收中断;

(2)在接收中断中,我们每次从数据寄存器UART2->DR中读取一个字节,赋值到ReciveBuff;

(3)然后调用uart_GetStr函数,对当前输入字符进行处理;(即每一个输入调用一次处理函数)

(4)将uart_GetStr函数的返回值赋值给RT;

 1  INTERRUPT_HANDLER(UART2_RX_IRQHandler, 21)
 2 {
 3
 4   /* Read one byte from the receive data register and send it back */
 5
 6   ReciveBuff = (UART2_ReceiveData8() & 0x7F); //get input char
 7
 8   RT = uart_GetStr(RxBuffer, TRUE); //operate the char
 9
10 }

interrupt

(5)在主函数里死等,直到RT的值变为1(表示有return发生,即一次输入完毕);

(6)当RT=1时,主函数输出正确的输入字符串RxBuffer(这里可以实现更强大的功能,此处只是简单实现验证功能,可以对正确字符串做判断后实现更强大的功能)

 1 void main(void)
 2 {
 3   /* Clock configuration -----------------------------------------*/
 4   CLK_Config();
 5
 6   /* TIM4 configuration -----------------------------------------*/
 7   TIM4_Config();
 8
 9
10   /* UART2 configuration -----------------------------------------*/
11   UART2_Config();
12
13
14   while(1){
15     printf("\n\rplease input something: \n\r");
16
17     while(1){ //wait until input something
18
19       if(RT) // return occurred
20       {
21         RT = 0; //clear flag
22
23         printf("your put is:");
24         printf("%s\n\r",RxBuffer); //verify the input
25
26         /*-- operate the string --*/
27         /*------------------------*/
28
29         //memset(RxBuffer,0,32); //clear the buffer
30         break; //operation finished
31       }
32
33     }
34
35     /*-- or operate the string here --*/
36     if(strcmp(RxBuffer, "Hello") == 0)
37     { //case sensitive
38       printf("\n\rHello World !!\n\r");
39     }
40     /*--------------------------------*/
41
42   }
43
44 }

main

  • 说明:

这里的打印和上面的回显虽然都是输出到终端,但是不同的是,回显是为了让用户知道自己是在实时输入内容的,而打印是把用户本次输入的字符串处理之后再一并返回给终端,方便用户检查自己输入的内容;

  如用户输入:ABCED‘backspace‘‘backspace‘DE

  在终端中实时回显的就是字符串:ABCED‘backspace‘‘backspace‘DE

  而打印的字符串是处理过后的字符串,为:ABCDE

把uart_GetStr的第二个参数分别设置为TRUE和FALSE后观察终端输入操作的不同,这样就能明白他们的不同了。

时间: 2024-10-10 05:30:17

Universal asynchronous receiver transmitter (UART)的相关文章

UART to Serial Terminal(转载)

前一篇<UART Explained>介绍了UART的基本信息,重点分析了UART的信号.本文摘录的文章则重点介绍了波特率(Baud Rate)相关的内容,波特率越高,传输速度越快,但实际使用时波特率是越高越好吗,多少合适?文中给出了答案,具体如下. Although the PIC32 is an elegant and powerful microcontroller, it doesn't stand so tall when compared against a PC in terms

Software UART, Timer, PWM, External Interrupt

How can you add extra hardware UARTs to a 32bit TMS470 ARM7-based microcontroller at zero cost? Solution: Designers can use the high-end timer (HET) peripheral found on all Texas Instruments ARM7-based, 32-bit TMS470 microcontrollers to implement add

UART学习之路(一)基本概念

第一篇博客,首先记录一下这一个多星期来的学习内容. UART学习之路第一篇,是UART的基本概念介绍.后续会用STM32F407的串口与PC机通信.最后使用Verilog HDL写出串口发送模块和接收模块,完成仿真,在Zedboard板上完成通信. 首先先明确什么是UART,COM口,TTL,RS-232. 通用异步收发传送器(Universal Asynchronous Receiver/Transmitter, UART)有4个管脚分别为VCC,GND,TX,RX,电平标准为TTL电平.低电

串行异步通信接口

串行异步通信接口UART(通用异步收发器)(Universal Asynchronous Receiver/Transmitter,UART)常用于全双工串行异步通信. UART有发送器.接收器.控制单元.波特率发生器等构成. 发送器负责字符的发送,可采用先进先出(FIFO)模式,也可采用普通模式发送.发送的字符先发送缓冲寄存器,然后通过移位寄存器,在控制单元的作用下,通过TXDn引脚的一位一位顺序发送出去.在FIFO模式下,当N个字节全部到位后才进行发送.不同嵌入式处理芯片内部设置的N值不同.

BSP

1       BSP概述 BSP即Board Support Package,板级支持包.它来源于嵌入式操作系统与硬件无关的设计思想,操作系统被设计为运行在虚拟的硬件平台上.对于具体的硬件平台,与硬件相关的代码都被封装在BSP中,由BSP向上提供虚拟的硬件平台,BSP与操作系统通过定义好的接口进行交互.BSP是所有与硬件相关的代码体的集合. 一个成熟的商用操作系统,其被广泛应用的必要条件之一就是能够支持众多的硬件平台,并实现应用程序的硬件无关性.一般来说,这种无关性都是由操作系统实现的. 但对

dsp之BF531笔记

获得更多资料欢迎进入我的网站或者 csdn或者博客园 很久以前的BF531的笔记,觉得有用分享出来.摘自于open dsp 通用Gpio ADSP-BF53x 处理器上有16 个PF 接口,这些接口就是通常所有的IO 接口,通过寄存器配置,每一个PF 接口都可以作为外部中断接口. Blackfin 处理器的IO 使用与单片机不同,在使用前必须对该接口进行初始化,如告知接口的方向,如配置为输出接口,则直接配置输出接口电平信号,如配置为输入接口,需打开输入使能开关,配置输出信号触发方式,是否中断触发

基带处理器和应用处理器的核间通信

当前的手机架构使用着多种处理器间通信方式,目前分离式AP.CP流行的接口有SPI.I2C.UART.USB和双端口互联等,SoC式则采用共享内存.控制命令以消息的格式在基带处理器和AP处理器间传送,完成通话.短消息.移动上网等功能,通信协议包括传统AT命令.MBIM等.一般来说,芯片都会支持多种接口,并设计通用的软件驱动平台驱动. 1,GPIO:通用输入输出控制线(General Purpose Input/Output) 当微控制器或芯片组没有足够的I/O端口,或当系统需要采用远端串行通信或控

SPI、IIC、IIS、UART、JTAG的应用场合级区别

SPI  SPI接口的全称是"Serial Peripheral Interface",意为串行外围接口,是Motorola首先在其MC68HCXX系列处理器上定义的. SPI接口主要应用在EEPROM,FLASH,实时时钟,AD转换器,还有数字信号处理器和数字信号解码器之间.  SPI接口是以主从方式工作的,这种模式通常有一个主器件和一个或多个从器件,其接口包括以下四种信号: (1)MOSI – 主器件数据输出,从器件数据输入 (2)MISO – 主器件数据输入,从器件数据输出 (3

SPI、I2C、UART三种串行总线协议的区别和SPI接口介绍(转)

SPI.I2C.UART三种串行总线协议的区别 第一个区别当然是名字: SPI(Serial Peripheral Interface:串行外设接口); I2C(INTER IC BUS) UART(Universal Asynchronous Receiver Transmitter:通用异步收发器) 第二,区别在电气信号线上: SPI总线由三条信号线组成:串行时钟(SCLK).串行数据输出(SDO).串行数据输入(SDI).SPI总线可以实现多个SPI设备互相连接.提供SPI串行时钟的SPI