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配置函数实现如下代码所示:

 static void UART2_Config(void)
{
/* EVAL COM (UART) configuration -----------------------------------------*/
/* USART configured as follow:
- BaudRate = 115200 baud
- Word Length = 8 Bits
- One Stop Bit
- Odd parity
- Receive and transmit enabled
- UART Clock disabled
*/
UART2_Init((uint32_t), UART2_WORDLENGTH_8D,UART2_STOPBITS_1, UART2_PARITY_NO,
UART2_SYNCMODE_CLOCK_DISABLE, UART2_MODE_TXRX_ENABLE); /* Enable the UART Receive interrupt: this interrupt is generated when the UART
receive data register is not empty */
UART2_ITConfig(UART2_IT_RXNE_OR, ENABLE); /* Enable the UART Transmit complete interrupt: this interrupt is generated
when the UART transmit Shift Register is empty */
UART2_ITConfig(UART2_IT_TXE, ENABLE); /* Enable UART */
UART2_Cmd(ENABLE); /* Enable general interrupts */
enableInterrupts();
}

UART2_Config

2、UART输出功能

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

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

 #define PUTCHAR_PROTOTYPE int putchar (int c)
...
/**
* @brief Retargets the C library printf function to the UART.
* @param c Character to send
* @retval char Character sent
*/
PUTCHAR_PROTOTYPE
{
/* Write a character to the UART2 */
UART2_SendData8(c);
/* Loop until the end of transmission */
while (UART2_GetFlagStatus(UART2_FLAG_TXE) == RESET); return (c);
}

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中;

 //====================================================================================
//Function Name | dbg_GetStr
//Description | Get string via UART port.
//Input | *p_recv_buff : pointer to receive data buffer
// | b_echo_on : echo back on or off
//Output | detect terminal(0x0d character) :TRUE or FALSE
//Remark |
//====================================================================================
uint8_t uart_GetStr(uint8_t *p_recv_buff, bool b_echo_on)
{
uint8_t b_end = ;
int i;
static uint8_t len = ;
static uint8_t pos = ;
static uint8_t esc_seq = ;
uint8_t c; // Get a character.
if((c = ReciveBuff) == ){
return ;
}
// echo back
if(b_echo_on){
printf("%c",c); //show the input
} //Check
switch(esc_seq){
// Normal
case :
// Return(Terminate)
if(c == 0x0d){
p_recv_buff[len] = ;
len = pos = ; // clear
if(b_echo_on){
printf("\n");
}
b_end = ;
}
// Back Space
else if(c == 0x08){
if(len){
if(b_echo_on){
printf(" ");
printf("%c",0x08); // BS
}
len--; // update length info.
pos--; // update pos info
}
}
// ESC
else if(c == 0x1b){
esc_seq = ;
}
// DEL
else if(c == 0x7f){
if(len){
DeleteChar(pos, len, &p_recv_buff[]);
len --; // update length info
if(b_echo_on){
printf("%s",&p_recv_buff[pos]);
printf(" ");
printf("%c",0x08); // BS
// move cursor to character end.
for(i = ; i < len - pos; i++){
printf("%c",0x1b); // ESC
printf("%c",'[');
printf("%c",'D');
}
}
}
}
// Other
else{
p_recv_buff[pos] = c;
len++; // update length info
pos++; // update pos info
}
break;
// ESC SEQ -> 1st
case :
if(c == '['){
esc_seq = ; // Next seq.
}
else{
esc_seq = ; // not support(to normal)
}
break;
//ESC SEQ -> 2nd
case :
if(c=='D'){
if(pos){
pos--; // "<-" key
}
}
else if(c=='C'){
if(pos < len){
pos++; // "->" key
}
}
esc_seq = ; // To normal
break;
} return (b_end);
}

uart_GetStr

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

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

  • 运行流程

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

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

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

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

  INTERRUPT_HANDLER(UART2_RX_IRQHandler, )
{ /* Read one byte from the receive data register and send it back */ ReciveBuff = (UART2_ReceiveData8() & 0x7F); //get input char RT = uart_GetStr(RxBuffer, TRUE); //operate the char }

interrupt

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

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

 void main(void)
{
/* Clock configuration -----------------------------------------*/
CLK_Config(); /* TIM4 configuration -----------------------------------------*/
TIM4_Config(); /* UART2 configuration -----------------------------------------*/
UART2_Config(); while(){
printf("\n\rplease input something: \n\r"); while(){ //wait until input something if(RT) // return occurred
{
RT = ; //clear flag printf("your put is:");
printf("%s\n\r",RxBuffer); //verify the input /*-- operate the string --*/
/*------------------------*/ //memset(RxBuffer,0,32); //clear the buffer
break; //operation finished
} } /*-- or operate the string here --*/
if(strcmp(RxBuffer, "Hello") == )
{ //case sensitive
printf("\n\rHello World !!\n\r");
}
/*--------------------------------*/ } }

main

  • 说明:

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

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

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

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

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

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

  1. STM8S——Universal asynchronous receiver transmitter (UART)

    UART基本介绍: 通用异步收发器UART他的功能非常强大 我们只使用UART的全双工异步通信功能,使用中断接收数据. UART_RX:串行数据输入. UART_TX:串行数据输出. 硬件支持: 连接 ...

  2. Universal Asynchronous Receiver/Transmitter

    USART簡介與特性 NRZ標準資料格式(Mark/Space) 半雙工/全雙工 Synchronous 同步傳輸 CLOCK SKEW Asynchronous 非同步傳輸 半/全雙工.同步/非同步 ...

  3. k64 datasheet学习笔记52---Universal Asynchronous Receiver/Transmitter (UART)

    1.前言 UART实现与外设或CPU的通信 2. UART概述 2.1基本特性 (1)Full-duplex operation (2)Standard mark/space non-return-t ...

  4. 27. USART, Universal synchronous asynchronous receiver transmitter

    27.1 USART introduction 通用同步异步接收发射机(USART)对需要NRZ异步串行数据格式行业标准的外部设备,提供了一个灵活的全双工数据交换的方法.USART使用分数波特率生成器 ...

  5. UART to Serial Terminal(转载)

    前一篇<UART Explained>介绍了UART的基本信息,重点分析了UART的信号.本文摘录的文章则重点介绍了波特率(Baud Rate)相关的内容,波特率越高,传输速度越快,但实际 ...

  6. Software UART, Timer, PWM, External Interrupt

    How can you add extra hardware UARTs to a 32bit TMS470 ARM7-based microcontroller at zero cost? Solu ...

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

    第一篇博客,首先记录一下这一个多星期来的学习内容. UART学习之路第一篇,是UART的基本概念介绍.后续会用STM32F103的串口与PC机通信.最后使用Verilog HDL写出串口发送模块和接收 ...

  8. SAE J1708 DS36277 MAX3444, DS75176B

    http://en.wikipedia.org/wiki/J1708 J1708 SAE J1708 is a standard used for serial communications betw ...

  9. dsp之BF531笔记

    获得更多资料欢迎进入我的网站或者 csdn或者博客园 很久以前的BF531的笔记,觉得有用分享出来.摘自于open dsp 通用Gpio ADSP-BF53x 处理器上有16 个PF 接口,这些接口就 ...

随机推荐

  1. C#总结(三)DataGridView增加全选列

    最近的一个winform的项目中,碰到datagridview控件的第一列添加全选的功能,通常这个功能,有两种实现方式:1. 为控件添加DataGridViewCheckBoxColumn来实现,但是 ...

  2. Java Synchronization

    Volatile Since Java 5 the volatile keyword guarantees more than just the reading from and writing to ...

  3. 1.Java 加解密技术系列之 BASE64

    Java 加解密技术系列之 BASE64 序号 背景 正文 总结 序 这段时间,工作中 用到了 Java 的加解密技术,本着学习的态度,打算从这篇文章开始,详细的研究一番 Java 在加解密技术上有什 ...

  4. 数据库表间多对多关系(附带额外字段)的实体类(POJO 或 POCO)表示

    介绍 在之前的 Entity Framework 快速上手介绍 之中,两个实体之间只是简单的一对一关系,而在实际的应用场景中,还会出现多对多关系,同时还有可能会出现多对多关系还附带有其他字段的情况. ...

  5. 在容器中利用Nginx-proxy实现多域名的自动反向代理、免费SSL证书

    在个人的小项目或者测试环境中,配置反向代理显得十分繁琐,而借助 Nginx-proxy 的镜像,即使是小白,也能快速实现域名转发. 1.域名.IP自动转发 在开始之前,首先黑进了自家的路由器,将某个域 ...

  6. 写markdown博客如何截图并快速上传到图床——记一个工具插件的实现

    1. 背景 写博客有一个自己的图床是不错的选择,如果不借助工具,在markdown博客中添加图片的步骤如下: 截取图片,保存到本地(得来回点对话框,选择保存路径,选择文件类型,输入文件名). 上传到图 ...

  7. 特朗普退出《巴黎协定》:python词云图舆情分析

    1 前言 2017年6月1日,美国特朗普总统正式宣布美国退出<巴黎协定>.宣布退出<巴黎协定>后,特朗普似乎成了“全球公敌”. 特斯拉总裁马斯克宣布退出总统顾问团队 迪士尼董事 ...

  8. sql备份(.mdf文件备份)

    第一步: 右键需要备份的数据库(这里以MyDB为例),选择“属性”. 第二步: 选择“文件”,复制路径 第三步: 打开文件所在目录,复制MyDB.mdf和MyDB_log.ldf 第四步: 把数据库停 ...

  9. dotnet 命令实战

    以下用实例串起dotnet所有命令,带你玩转dotnet命令. 1.创建(dotnet new) 首先我们创建一个项目,这里我们创建控制台程序,命令如下图所示. dotnet new dotnet n ...

  10. 走进BFC

    在解释 BFC 是什么之前,需要先介绍 Box.Formatting Context的概念. Box: CSS布局的基本单位: Box 是 CSS 布局的对象和基本单位, 直观点来说,就是一个页面是由 ...