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 接口,这些接口就 ...
随机推荐
- 企业级NFS网络文件共享服务_【all】
1.1. 什么是NFS(1台机器提供服务) Network File System(网络文件系统)通过局域网让不同的主机系统之间共享文件或目录. NFS客户端可以通过挂载的方式将NFS服务器端共享的数 ...
- 阿里云全球首次互联网8K直播背后的技术解读
3月28日,云栖大会·深圳峰会现场,阿里云发布并现场演示了阿里视频云最新8K互联网直播解决方案.这是全球发布的首个8K视频云解决方案,也是全球首次8K互联网视频直播. 视频地址:https://v.q ...
- C++实现一个Vector3空间向量类(转)
转自:http://www.2cto.com/kf/201311/260139.html ector2,3,4类在DirectX中都有现成的可以调用,不过要实现其中的功能其实也不难,也都是一些简单的数 ...
- Array对象常用方法
不改变原数组: 1.concat() 连接两个或多个数组 不改变原数组 返回被连接数组的一个副本 2.join() 把数组中所有元素放入一个字符串 不改变原数组 返回字符串 3.slice() ...
- [转]JMX的Hello World
这篇写的很详尽了: http://www.blogjava.net/hengheng123456789/articles/65690.html
- Java虚拟机18:Java对象大小、对象内存布局及锁状态变化
一个对象占多少字节? 关于对象的大小,对于C/C++来说,都是有sizeof函数可以直接获取的,但是Java似乎没有这样的方法.不过还好,在JDK1.5之后引入了Instrumentation类,这个 ...
- macaca常见错误排查
1.Error: cannot resolve path (or pattern) 'macaca-test' 这是因为执行run命令的时候未进入用例目录 C:\Users\Tony\node_mod ...
- iPhone 电脑备份路径
C:\Users\iChen\AppData\Roaming\Apple Computer\MobileSync\Backup
- Python 把数据库的数据导出到excel表
import io,xlwt def export_excel(request): """导出数据到excel表""" list_obj = ...
- 一条SQL语句执行得很慢原因有哪些
一条SQL语句执行得很慢,要分两种情况: 1.大多数情况是正常,偶尔很慢 数据库在处理数据忙时候,更新或新增数据都会暂时记录到redo log日志,等空闲时把数据同步到磁盘.假设数据库一直很忙,更新又 ...