博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
STM8S——Universal asynchronous receiver transmitter (UART)
阅读量:4599 次
发布时间:2019-06-09

本文共 7965 字,大约阅读时间需要 26 分钟。

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 enabled10         - UART Clock disabled11   */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 UART16     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 normal102           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 something18      19       if(RT) // return occurred20       {21         RT = 0; //clear flag22         23         printf("your put is:");24         printf("%s\n\r",RxBuffer); //verify the input25         26         /*-- operate the string --*/27         /*------------------------*/28         29         //memset(RxBuffer,0,32); //clear the buffer30         break; //operation finished31       }32       33     }34     35     /*-- or operate the string here --*/36     if(strcmp(RxBuffer, "Hello") == 0)37     { //case sensitive38       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后观察终端输入操作的不同,这样就能明白他们的不同了。

转载于:https://www.cnblogs.com/Christal-R/p/7131591.html

你可能感兴趣的文章
让IE6/IE7/IE8浏览器支持CSS3属性
查看>>
队列实现霍夫曼树
查看>>
【Java】图片高质量缩放类
查看>>
Python :类中设置默认属性并修改
查看>>
磁盘管理综合测试
查看>>
Unity3d Shader开发(三)Pass(Pass Tags,Name,BindChannels )
查看>>
UMLet
查看>>
从父控件移除控件
查看>>
calc()制作自适应布局
查看>>
Markdown-写作必备
查看>>
关于在Java中 a!=a 值为真的解释(摘抄)
查看>>
C#串口小助手
查看>>
详解定位与定位应用
查看>>
【前端开发】 5分钟创建 Mock Server
查看>>
一个Tomcat配置参数引发的血案
查看>>
java 从键盘录入的三种方法
查看>>
使用jQuery和YQL,以Ajax方式加载外部内容
查看>>
pyspider 示例
查看>>
Ubuntu下Sublime Text 3解决无法输入中文的方法
查看>>
电路板工艺中的NPTH和PTH
查看>>