STM32F103C8T6之通用异步收发器(发送接收中断)
来源:互联网 发布:产品数据分析总结 编辑:程序博客网 时间:2024/06/05 20:09
文档简介:本文档主要讲解了关于STM32F103C8T6 外设之UART数据上传与下发的功能实现以及UART的基本概念。这里对于寄存器的配置不做分析,提供UART标准程序的设计思路。前面几部分着重描述UART通信方式及其特点的一些概念介绍与理解。
一、文档导航
1、什么是串行通信
2、什么是并行通信
3、什么是同步通信
4、什么是异步通信
5、全双工、半双工、单工三者区别
6、标准UART的通信数据帧格式
7、标准UART程序设计思路
8、STM32F103C8T6 UART内部框架
9、具体实现代码
10、后续更新
二、什么是串行通信
2.1 概念理解
只有一根数据线的通信方式叫串行通信。就是将数据一个一个位传递,实现串行通信。
2.2 此通信方式特点
优点:硬件设计非常简单,可靠性高。
缺点:数据传输速度慢,不适合需求数据传输速度快的设备。
三、什么是并行通信
3.1 概念理解
具有多条线的进行数据通信的方式叫并行通信。
3.2 此通信方式特点
优点:通信速度快。适合需求数据传输速度的设备。
缺点:硬件设计复杂,可靠性低。
四、什么是同步通信
4.1 概念
通信双方具有相同的时钟,并且有时钟线相连接。
4.2 通讯特点
通信数据会持续输出,不会存在积累误差。
五、什么是异步通信
5.1 概念
通信双方不具有相同的时钟,没有时钟线相连接。
5.2 通讯特点
通信双方数据输出会存在积累误差。为了解决积累误差,数据不准确的问题,采用数据没传输一帧,下一次数据传输就从帧头开始传输。
六、全双工、半双工、单工三者区别
6.1 全双工
在同一时刻,数据的收发能够同时进行,互不干扰。其数据线为双向单线。
6.2 单双工
在同一时刻,数据收发只能进行收或者发,相当于独木桥。要么收,要么发,正在进行数据交换时,可以对数据收发的方向进行切换。其数据线为双线单线。
6.3 单工
只具有一个方向的数据通信。具有单向性。其数据线为单向单线。
6.4 UART属于全双工。
七、标准UART的通信数据帧格式
7.1 通信方式
标准UART属于异步串行通信,也是全双工通信。
7.2 帧格式说明
在UART的通信方式中,它的数据或者字符是以帧格式进行数据传送的。帧格式为串口通信的数据格式。其帧格式是以一个起始位“0”表示字符的开始,接着是5-8位的数据位,一般规定低位在前,高位在后;数据位后是奇偶校验位,然后是停止位。停止位一般分为0.5位、1位、1.5位、2.0位。一个完整的帧格式从起始位到停止位。
起始位:通信线上没有数据传送时,为高电平(逻辑1);当要发送数据时,首先发1个低电平信号(逻辑0),此信号称为“起始位”,表示开始传输1帧数据。
数据位:起始位之后就是数据位,数据位一般为5-8位,规定低位在前、高位在后。一般都是从低位开始传送,然后高位传送。
奇偶校验位:数据位之后的位为奇偶校验位(有的方式具有)。此位可用于判别字符传送的正确性,其有3种可能的选择,即奇、偶、无校验,用户可根据需要选择
停止位:它是一个字符数据的结束标志。可以是1位、1.5位(每一位时间是固定,1.5位就是高电平时间 长度是1.5位占用的时间)、2位的高电平。 由于数据是在传输线上定时的,并且每一个设备有其自己的时钟,很可能在通信中两台设备间出现了小小的不同步。因此停止位不仅仅是表示传输的结束,并且提供计算机校正时钟同步的机会。适用于停止位的位数越多,不同时钟同步的容忍程度越大,但是数据传输率同时也越慢。
八、标准UART程序设计思路
8.1 实现UART通信的必备四大元素
波特率:一秒钟传输的二进制位数。
数据位:实际数据一般存放在数据位。5-8位。
停止位:主要用来消除积累误差
校验位:硬件校验,一般的硬件支持奇偶校验。
8.2 UART通信
常规的UART通信,只需要实现以下几个方面即可通信。
①配置UART通信的四大元素--UART初始化;
②数据发送函数
③数据接收函数
九、STM32F103C8T6 UART内部框架
9.1内部框架
如果通过配置寄存器的方式,需要对UART内部框架图进行详细分析。
9.2具体配置过程
9.2.1 UART初始化
①开启TX/RX对应IO时钟、开启串口时钟、IO引脚复用时钟
②TX配置成复用推挽输出、RX配置成上下拉输入
③TX/RX复用为串口使能
④计算波特率、写入波特率寄存器
⑤使能UART、配置数据格式(1-start、8-databit、1-stop)、奇偶校验位、停止位
⑥发送使能、接收使能
⑦若需中断,开启UART总中断,开启接收空闲中断,NVIC控制器配置。
⑧中断服务处理
9.2.2 数据发送
等待发送完成、将发送的data写入register;
9.2.3 数据接收
等待接收完成,将register的值传递到buff;
十、具体实现代码
#include "uart.h"
#include <stdio.h>
#include <rt_misc.h>
volatile uint8_t uart_interrupt_flag = UART_RECE_DATA_NO_FLAG;
char uart_frame_buffer[UART_RECE_LENGTH];
#if 1
#pragma import(__use_no_semihosting_swi)
struct __FILE
{
int handle;
};
FILE __stdout;
int fputc(int ch, FILE *f)
{
return ( send_data(ch));
}
int ferror(FILE *f)
{
/* Your implementation of ferror */
return EOF;
}
void _ttywrch(int ch)
{
send_data(ch);
}
void _sys_exit(int return_code)
{
label:
goto label; /* endless loop */
}
#endif
#if UART_INTERRUPT
void uart_interrupt_init(void)
{
uint32_t Priority;
USART1->CR1 |= 1 << 5;
USART1->CR1 |= 1 << 4;
NVIC_SetPriorityGrouping(7-2);
Priority=NVIC_EncodePriority(7-2,3,1);
NVIC_SetPriority(USART1_IRQn,Priority);
NVIC_EnableIRQ(USART1_IRQn);
}
#endif
void uart1_init(uint32_t baund,uint32_t clk)
{
float temp;
uint16_t mantissa;
uint16_t fraction;
RCC->APB2ENR |= 1 << 2;
RCC->APB2ENR |= 1 << 14;
RCC->APB2ENR |= 1 << 0;
GPIOA->CRH &= ~(0xFF << 4);
GPIOA->CRH |= (0x4B << 4);
AFIO->MAPR2 &= ~(0X1 << 2);
temp = (float)(clk)/ (baund * 16.0);
mantissa = temp ;
fraction =(int)(temp -mantissa)*16 + 0.5f;
mantissa <<= 4;
mantissa |= fraction;
USART1->BRR = mantissa;
USART1->CR1 |= 1 << 13 |
0 << 12 |
0 << 10 |
0 << 8 |
1 << 2 | //receiver enable
1 << 3 ; //transform enable
USART1->CR2 |= (0 << 12);
USART1->CR2 |= (0 << 13);
USART1->CR3 = 0;
#if UART_INTERRUPT
uart_interrupt_init();
#endif
}
char send_data(char buff)
{
while(!( (USART1->SR) & (1 << 7) ))
{
;
}
USART1->DR = buff;
return buff;
}
char rece_data(void)
{
while(!( (USART1->SR) & (1 << 5)))
{
;
}
return USART1->DR;
}
void send_data_string(char *string)
{
while(*string)
{
send_data(*string++);
}
send_data('\r');
send_data('\n');
}
char* rece_data_string(char *string)
{
uint8_t r_data;
uint8_t i=0;
while(1)
{
r_data = rece_data();
string[i++]=r_data;
if(r_data == '\n')
{
break;
}
#if 1
#if (ECHO == ECHO_ON)
send_data(r_data) ;
#endif
#endif
}
#if 1
#if (ECHO == ECHO_ON)
send_data('\r') ;
send_data('\n') ;
#endif
#endif
string[i]=0;
return string;
}
void USART1_IRQHandler(void)
{
uint32_t ch_data;
static uint32_t i=0;
if( (USART1->SR) & (1 << 5))
{
ch_data=USART1->DR;
uart_frame_buffer[i++]=ch_data;
if(i >= UART_RECE_LENGTH)
{
uart_frame_buffer[i++]='\0';
uart_interrupt_flag = UART_RECE_DATA_NO_FLAG;//Òç³ö±êÖ¾
i=0;
}
}
if( (USART1->SR) & (1 << 4))
{
ch_data=USART1->DR;
uart_frame_buffer[i++]='\0';
i=0;
uart_interrupt_flag = UART_RECE_DATA_OK_FLAG;
}
}
在实现过程中,波特率配置出现问题,写入寄存器没有注意到小数部分为前面四位,刚开始理解成前面8位,导致串口上传failed;
另外还有volatile 此关键词在应用,不管在哪里都需要将它放在变量前。
十一、后续更新会继续更新
- STM32F103C8T6之通用异步收发器(发送接收中断)
- UART(通用异步收发器)简介
- 通用异步收发器UART-学习笔记
- STM32通用同步异步收发器(USART)
- android MMS/SMS 收发流程分析(接收发送)
- UART (Universal Asynchronous Receiver/Transmitter) 通用异步收发器
- ARM学习笔记--通用异步收发器UART
- 四、s3c2440 裸机开发 通用异步收发器UARN
- JZ2440 第11章 通用异步收发器UART
- Tcp异步接收发送
- LAN9221网卡驱动之三 接收/发送完成中断
- C51 中断接收 查询发送
- STM32串口中断接收和中断发送
- Socket异步发送接收,Windows
- 【MSP430】MSP430深入研究 之 通用收发器USART(上)
- STM32F103C8T6按键中断功能实现
- STM32F103C8T6学习笔记_中断
- C# Scoket异步通讯实现(发送数据、接收数据)
- 博客---错了就是错了
- Java——入门“HelloWorld”
- Python 动态生成多维数组
- nginx和swoole高并发原理
- HDU
- STM32F103C8T6之通用异步收发器(发送接收中断)
- 【poj 2942 】 Knights of the Round Table 【tarjan求bcc+黑白染色判二分图】
- 2017 Multi-University Training Contest
- Structs2通过耦合的方式访问WEB资源
- 木兰词·拟古决绝词柬友
- ParseXML 和 parseJson
- HDU-3974 Assign the task题解报告【dfs序+线段树】
- gcc和makefile(二)
- MarkDown语法