历史上的今天

今天是:2024年11月18日(星期一)

2019年11月18日 | STM8S——Universal asynchronous receiver transmitter (UART)

发布者:渤海湾 来源: eefocus关键字:STM8S  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中;


//====================================================================================

  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)

[1] [2]
关键字:STM8S  Universal  asynchronous  receiver  transmitter  UART 引用地址:STM8S——Universal asynchronous receiver transmitter (UART)

上一篇:STM8S——Analog/digital converter (ADC)
下一篇:最后一页

推荐阅读

  “警察叔叔,这个机器人好可爱啊,它叫什么名字?”“它叫安安警官,正在协助我们执勤。”广州海珠警方在广州塔景区启用的-2000警用机器人上岗执勤,不少市民群众前来围观。   这位名为“安安警官”的警用机器人高1.6米,重80公斤,白胖圆润,可爱呆萌,身上贴有“警察”“POLICE”等警方标识。   “安安警官”的投入使用,是广州海珠警方坚...
自适应和智能计算的全球领先企业赛灵思公司(Xilinx, Inc.,(NASDAQ:XLNX))今天宣布推出两款赛灵思汽车级(XA )新器件Zynq®UltraScale+™ MPSoC 7EV 和11EG ,进一步丰富其汽车级16nm 产品系列。这两种新器件提供了最优异的可编程能力、性能和I/O 功能,面向L2+ 到L4 的高级驾驶员辅助系统(ADAS )应用和自动驾驶(AD )应用提供了高速...
AR一直是硬件厂商在不断攻克的技术领域,在本届OPPO未来科技大会上,OPPO也公布了新一代的AR概念眼镜和一款辅助生态的CybeReal AR应用。  OPPO最先从2014年开始投入AR领域研究,并在2019年的未来科技大会上首次亮相了AR眼镜产品,其搭载了oF、SLAM算法、衍射光波导技术、支持手势和语音识别等技术,是OPPO探索AR的首款概念硬件。  时隔两年...

史海拾趣

问答坊 | AI 解惑

有用过Android的朋友吗,该怎么学

如题。Android挺火的,不知道如何入手。请教了…

查看全部问答∨

wince iimage encoder

有哪位大侠实现过wince iimage组件的encoder 目前小弟困在IImageEncoder::GetEncodeSink( IImageSink** sink) 的实现上, 小弟是先CreateNewBitmap 一个bitmap然后queryinterface 得到imagesink, 但是不知道CreateNewBitmap 中的 width, & ...…

查看全部问答∨

负的AVss怎么处理?

我用dsPIC30F2012做一个A/D转换,正参考电压接在Vref+上,负参考电压接在Vref-上,VCC经过滤波后接在了AVDD上,现在AVss不知如何处理,因为要求转换的电压是有负电压的,我能不能直接将AVss接地。A/D转换的参考电压选用的是Vref+和Vref-。请前辈高 ...…

查看全部问答∨

找朋友一起开发

本人目前做数字电视软件,不过看今后3G发展不错,想写一个嵌入式浏览器,它的特点是易移植,速度快,内存小。之前我的工作做过一点,主要要支持html4.0,js 1.5, css2等,可以分步骤开发。主要现在一个人太慢,并且时间还很有限。目前考虑开源或者 ...…

查看全部问答∨

开发一个PDA问题

  要开发一个PDA   的应用程序,这PDA支持   Windows   Mobile   5.0   用 vs2005  ,只能用   vc.net     吗?     vb ...…

查看全部问答∨

北京微芯力科-大量ST-STM32现货到仓

北京微芯力科技术有限公司欢迎来电咨询:010-51581828010-51581825QQ:709357905EMAIL:casperwei@yeah.net…

查看全部问答∨

STM8S的硬SPI通不过

选择HSI做为主时钟,16MHz void CLK_Init(void) {     CLK_DeInit();     CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1); } //SPI初始化 void SPI_MyInit(void) {     SPI_DeInit();     ...…

查看全部问答∨

求xilinx高手指点

 刚开始学xilinx,现在有很大问题解决不了,求高手指点,能不能留个QQ,在论坛里交流不方便,贴图很麻烦。QQ:707587938谢谢 …

查看全部问答∨

LaunchPadFirmwareUpdater2.0

------------------------------------------------------------------------------- Readme file for LaunchPadFirmwareUpdater2.0.exe LaunchPadFirmwareUpdater2.0.exe is a GUI based utility to update the emulator firmware of Texas Ins ...…

查看全部问答∨

【问TI】LM3S系列IQmath如何使用?

以前编程序,用到数学公式中的三角函数,开方函数..公式的时候,自己使用泰勒展开并取到5阶.以前的IQmath用在DSP上比较多,许多的使用文档都是基于TMS320F281xx处理器的,现在好像IQmath能用在LM3S芯片上.麻烦问下TI专家,IQmath如何使用,其中的cmd文件如 ...…

查看全部问答∨
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
  • ARM裸机篇--按键中断
    先看看GPOI的输入实验:按键电路图:GPF1管教的功能:EINT1要使用GPF1作为EINT1的功能时,只要将GPFCON的3:2位配置成10就可以了!GPF1先配 ...
  • 网上下的--ARM入门笔记
    简单的介绍打今天起菜鸟的ARM笔记算是开张了,也算给我的这些笔记找个存的地方。为什么要发布出来?也许是大家感兴趣的,其实这些笔记之所 ...
  • 学习ARM开发(23)
    三个任务准备与运行结果下来看看创建任务和任运的栈空间怎么样的,以及运行输出。Made in china by UCSDN(caijunsheng)Lichee 1 0 0 ...
  • 学习ARM开发(22)
    关闭中断与打开中断中断是一种高效的对话机制,但有时并不想程序运行的过程中中断运行,比如正在打印东西,但程序突然中断了,又让另外一个 ...
  • 学习ARM开发(21)
    先要声明任务指针,因为后面需要使用。 任务指针 volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • 学习ARM开发(20)
  • 学习ARM开发(19)
  • 学习ARM开发(14)
  • 学习ARM开发(15)
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved