历史上的今天
返回首页

历史上的今天

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

正在发生

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

2019-11-18 来源:eefocus

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)

推荐阅读

史海拾趣

DBS Microwave Inc公司的发展小趣事

随着公司产品的不断成熟和技术的不断进步,DBS Microwave开始积极拓展国际市场。公司参加了多个国际电子展会,与全球各地的客户建立了联系。同时,公司还积极寻求与国际知名企业的合作机会,通过技术交流和合作研发等方式,不断提升自身的技术水平和市场竞争力。这些努力使得DBS Microwave在国际市场上取得了良好的业绩。

启英泰伦(Chiplntelli)公司的发展小趣事

近期,启英泰伦完成了数千万元的B++轮融资,由水木春锦资本、盛裕资本和自觉资本共同投资。这笔资金将主要用于产品的大规模量产和新产品的研发,以进一步加速启英泰伦在智能语音芯片市场的布局。资本的注入不仅为公司的发展提供了强有力的支持,也反映了市场对启英泰伦技术和市场前景的认可。

China Semiconductor Corp公司的发展小趣事

随着公司的发展,CSC逐渐意识到技术创新是立足之本。于是,公司加大了研发投入,引进了一批高端人才,建立了完善的研发体系。通过不懈的努力,CSC在多个领域取得了重大突破,如高性能处理器、存储器等关键技术的研发,使公司在国际市场上逐渐获得了话语权。

德力西(DELIXI)公司的发展小趣事

1984年,胡成中偕其弟胡成国等人在浙江省乐清市创立了“乐清县求精开关厂”,这便是德力西的前身。当时,企业仅有3位股东,5万元的资本,8名员工,以及单一的热继电器产品。凭借“以质取胜”的经营理念和灵活的机制,德力西在温州市电器行业中逐渐崭露头角。

ABB公司的发展小趣事

德力西非常重视品牌建设,通过全方位的品牌建设及宣传,不断提高品牌知名度和美誉度。同时,公司也加快了国际化步伐。2007年,德力西低压电器业务迈向企业国际化的新阶段,在全国范围内进行资本大重组、产品大联合、市场大拓展和技术大提高。这些努力使德力西在国际市场上也取得了一席之地。

Blaze Display Technology Co Ltd公司的发展小趣事

随着技术的不断进步,Blaze公司意识到要想在激烈的市场竞争中立于不败之地,必须不断进行技术创新和品质升级。因此,公司加大了研发投入,引进了一批高端技术人才和先进设备,成功研发出了多项具有自主知识产权的核心技术。同时,公司还严格把控产品质量,确保每一块显示屏都达到行业领先水平。

问答坊 | AI 解惑

浅谈PCB敷铜的“弊与利”

敷铜作为PCB设计的一个重要环节,不管是国产的青越锋PCB设计软件,还国外的一些Protel,PowerPCB都提供了智能敷铜功能,那么怎样才能敷好铜,我将自己一些想法与大家一起分享,希望能给同行带来益处。 所谓覆铜,就是将PCB上闲置的空间作为基准面, ...…

查看全部问答>

P430颅内出血检测设备的研制策略

P430颅内出血检测设备的研制策略1 引言 在中国有许多因创伤性颅脑损伤的患者急需抢救,但相当一部分颅内出血患者因未能及时诊断,延误了抢救和治疗时机.因而出现脑血肿或脑疝后压迫脑组织.使脑干和脑实质受到不可逆转的损伤。近红外颅内出血检测 ...…

查看全部问答>

UBS to RS232 转接线(PL-2303HX)的特性及应用电路

本帖最后由 paulhyde 于 2014-9-15 09:20 编辑 1.USB转串口线:   PROLIFIC推出了USB TO 类RS232接口转换芯片PL-2303HX,PL-2303HX可完美的应用于PDA、Modem、GPS、手机、数码相机、读卡机等与PC机的通讯电缆上,实际上很多手机的USB数据线就是 ...…

查看全部问答>

这样压缩X曲线的坐标

绘制图形时,有时需要压缩X轴但Y轴不变,我绘图是先绘制到设备上再拷贝到绘图控件上的,请问高手该这么解决…

查看全部问答>

wince中dll驱动加载后马上卸载了 ,如何解决

wince启动信息: Loaded symbols for \'E:\\WINCE420\\PUBLIC\\DIRVERTEST\\RELDIR\\EMULATOR_X86DEBUG\\SCANDLL.DLL\' Unloaded symbols for \'E:\\WINCE420\\PUBLIC\\DIRVERTEST\\RELDIR\\EMULATOR_X86DEBUG\\SCANDLL.DLL\' 可以发现SCANDLL. ...…

查看全部问答>

s3c6410 winCE6.0 IIC驱动冲突原因是什么

在http://blog.eeworld.net/knock/archive/2009/11/05/4771874.aspx 看到一文章说s3c6410 winCE6.0 IIC驱动读写冲突的原因是电源管理IC驱动也要通过IIC总线去读取电池电压和电流及充放电状态,这样混在一起,就出现了TX Time Out的现象。而关掉PMU ...…

查看全部问答>

isa总线 编程的问题

要作的一个题目是PC104总线上对一个PPGA板子进行控制,读写寄存器控制FPGA, 不知道怎么写啊,有没有哪位大虾帮帮阿。 谢谢了…

查看全部问答>

谁能给提供一个nandflash的ECC校验代码?

                                  …

查看全部问答>

借人气寻一chip;

功能就是把19 v 稳压到3.3v 或3v, 给430 提供电源,情有经验的多说说几颗chip 型号 ,需要贴片的。 谢谢。…

查看全部问答>

在keill中模拟时有时候计算数值哪里出错,纠结很久了,求助

code unsigned  int adc[]={228,221,213,204,194,183,172,160,147,135,122,110,99,88,78,69,61,54,48,42,38,33,29,26,23,20,18,16,14,13,11 };code unsigned int tem[]={0,5,10,15,20,25,30,35,40,45,50,55,60,65,70,75,80,85,90,95,100,105,1 ...…

查看全部问答>