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配置函数实现如下代码所示:
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后观察终端输入操作的不同,这样就能明白他们的不同了。
STM8S——Universal asynchronous receiver transmitter (UART)的更多相关文章
- Universal asynchronous receiver transmitter (UART)
UART基本介绍: 通用异步收发器UART他的功能非常强大 我们只使用UART的全双工异步通信功能,使用中断接收数据. UART_RX:串行数据输入. UART_TX:串行数据输出. 硬件支持: 连接 ...
- Universal Asynchronous Receiver/Transmitter
USART簡介與特性 NRZ標準資料格式(Mark/Space) 半雙工/全雙工 Synchronous 同步傳輸 CLOCK SKEW Asynchronous 非同步傳輸 半/全雙工.同步/非同步 ...
- 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 ...
- 27. USART, Universal synchronous asynchronous receiver transmitter
27.1 USART introduction 通用同步异步接收发射机(USART)对需要NRZ异步串行数据格式行业标准的外部设备,提供了一个灵活的全双工数据交换的方法.USART使用分数波特率生成器 ...
- UART to Serial Terminal(转载)
前一篇<UART Explained>介绍了UART的基本信息,重点分析了UART的信号.本文摘录的文章则重点介绍了波特率(Baud Rate)相关的内容,波特率越高,传输速度越快,但实际 ...
- Software UART, Timer, PWM, External Interrupt
How can you add extra hardware UARTs to a 32bit TMS470 ARM7-based microcontroller at zero cost? Solu ...
- UART学习之路(一)基本概念
第一篇博客,首先记录一下这一个多星期来的学习内容. UART学习之路第一篇,是UART的基本概念介绍.后续会用STM32F103的串口与PC机通信.最后使用Verilog HDL写出串口发送模块和接收 ...
- SAE J1708 DS36277 MAX3444, DS75176B
http://en.wikipedia.org/wiki/J1708 J1708 SAE J1708 is a standard used for serial communications betw ...
- dsp之BF531笔记
获得更多资料欢迎进入我的网站或者 csdn或者博客园 很久以前的BF531的笔记,觉得有用分享出来.摘自于open dsp 通用Gpio ADSP-BF53x 处理器上有16 个PF 接口,这些接口就 ...
随机推荐
- C# 所有特性,特性所在命名空间,那些命名空间拥有特性类
文章持续补充中 特性并不是集中在某一命名空间中,而是不同的特性在不同的命名空间下,特性是某一命名空间下提供的语法糖. 有哪些命名空间提供特性: 命名空间 描述 Microsoft.Build.Fram ...
- SpringBoot+RestTemplate 简单包装
RestTemplate设计是为了Spring更好的请求并解析Restful风格的接口返回值而设计的,通过这个类可以在请求接口时直接解析对应的类. 在SpringBoot中对这个类进行 ...
- November 22nd 2016 Week 48th Tuesday
Eventually, you will learn to cry on the inside. 终有一天,你得学会让眼泪在心里流. Cry on the inside. I am tired, an ...
- 全部读取------------ 一次性全部读取的.read() VS 一行一行的for迭代
全部读取 f = open("喜洋洋",mode= "r",encoding= "utf-8") 方法一: 一次性全部读取f = o ...
- django 错误之 OSError: mysql_config not found
pip 导入包时出现如下错误 Complete output from command python setup.py egg_info: /bin/: mysql_config: not found ...
- 【转载】MySQl 数据库插入加锁分析
http://yeshaoting.cn/article/database/mysql%20insert%E9%94%81%E6%9C%BA%E5%88%B6/
- SQL Server 中的排名函数与使用场景
1.RowNumber() Over (oder by.....) 在需要对某个不连续ID的表进行排序时使用 2.ROW_NUMBER() over(PARTITION by ...... ord ...
- Cloudera Manager 4.6 安装部署hadoop CDH集群
Cloudera Manager 4.6 安装详解 1. Cloudera Manager介绍 1.1. 功能介绍 Cloudera Manager是一个针对hadoop集群的管理工具,功能包括:cd ...
- React Native 基础报错及解决方案记录
刚开始上手RN,碰到很多坑,记录一下.碰到问题多去看看github上面的issue! 启动命令react-native run-ios报错 1.:xcrun: error: unable to fin ...
- [luogu2680] 运输计划
题面 很明显, 由于是求最长路的最小值, 我们可以使用二分求解. 我们二分一个长度\(mid\), 将所有使得\(dis(u, v)\)大于\(mid\)的点对\((u, v)\)找出, 设总共有 ...