STM32 C++编程 003 USART(串口)类
使用 C++ 语言给 STM32 编写一个 Usart 类
我使用的STM32芯片:STM32F103ZET6
我们使用的STM32库版本:V3.5.0
注意:
想学习本套 STM32 C++编程 的专栏是有点门槛的。你需要有一点点 STM32 基础 和 一点点 C++ 语言基础。
完整的STM32 C++ Usart类 的下载地址可以在本篇博客的最下面找到。
Usart.cpp
#include "Usart.h"
#include "Gpio.h"
using namespace stm32f10x;
//2015-9-1 00:47:46 Usart2, Uart4,5 没有测试
//_______初始化部分______________
Usart::Usart(USART_TypeDef* USARTx, uint32_t USART_BaudRate, uint32_t NVIC_PriorityGroup,
uint8_t NVIC_IRQChannelPreemptionPriority, uint8_t NVIC_IRQChannelSubPriority)
:usartx(USARTx),baudRate(USART_BaudRate),nvicPriorityGroup(NVIC_PriorityGroup),
preemptionPriority(NVIC_IRQChannelPreemptionPriority), subPriority(NVIC_IRQChannelSubPriority){
initialize();
}
void Usart::initialize(){
Gpio txd,rxd;
switch((uint32_t)usartx){
case (uint32_t)USART1: txd = Gpio(PA,9,GM_AFPP); rxd=Gpio(PA,10,GM_IN_FLOATING); break;
case (uint32_t)USART2: txd = Gpio(PA,2,GM_AFPP); rxd=Gpio(PA,3,GM_IN_FLOATING); break;
case (uint32_t)USART3: txd = Gpio(PB,10,GM_AFPP); rxd=Gpio(PB,11,GM_IN_FLOATING); break;
case (uint32_t)UART4: txd = Gpio(PC,10,GM_AFPP); rxd=Gpio(PC,11,GM_IN_FLOATING); break;
case (uint32_t)UART5: txd = Gpio(PC,12,GM_AFPP); rxd=Gpio(PD,2,GM_IN_FLOATING); break;
}
//打开USARTx时钟
if((uint32_t)usartx < APB2PERIPH_BASE){
uint32_t RCC_APB1Periph = (uint32_t)(1<< ( ((uint32_t)usartx-APB1PERIPH_BASE)>>10));
RCC_APB1PeriphClockCmd(RCC_APB1Periph, ENABLE);
}
else{
uint32_t RCC_APB2Periph = (uint32_t)(1<< ( ((uint32_t)usartx-APB2PERIPH_BASE)>>10));
RCC_APB2PeriphClockCmd(RCC_APB2Periph, ENABLE);
}
USART_InitTypeDef USART_InitStructure;
//配置USARTx
USART_InitStructure.USART_BaudRate = baudRate; //波特率可以通过地面站配置
USART_InitStructure.USART_WordLength = USART_WordLength_8b; //8位数据
USART_InitStructure.USART_StopBits = USART_StopBits_1; //在帧结尾传输1个停止位
USART_InitStructure.USART_Parity = USART_Parity_No; //禁用奇偶校验
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //硬件流控制失能
USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; //发送、接收使能
USART_Init(usartx, &USART_InitStructure);
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig(nvicPriorityGroup);
switch((uint32_t)usartx){
case (uint32_t)USART1: NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; break;
case (uint32_t)USART2: NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn; break;
case (uint32_t)USART3: NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn; break;
case (uint32_t)UART4: NVIC_InitStructure.NVIC_IRQChannel = UART4_IRQn; break;
case (uint32_t)UART5: NVIC_InitStructure.NVIC_IRQChannel = UART5_IRQn; break;
}
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = preemptionPriority;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = subPriority;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
//使能接收中断
USART_ITConfig(usartx, USART_IT_RXNE, ENABLE);
//使能USARTx
USART_Cmd(usartx, ENABLE);
}
//_________初始化部分end___________________
//_________发送数据部分______________________
//////////发送字符串
void Usart::print(const char* pfmt, ...){
double vargflt = 0;
int vargint = 0;
char* vargpch = NULL;
char vargch = 0;
va_list vp;
va_start(vp, pfmt);
while(*pfmt){
if(*pfmt == '%'){
switch(*(++pfmt)){
case 'c':
vargch = va_arg(vp, int);
/* va_arg(ap, type), if type is narrow type (char, short, float) an error is given in strict ANSI
mode, or a warning otherwise.In non-strict ANSI mode, 'type' is allowed to be any expression. */
print((char)vargch);
break;
case 'd':
case 'i':
vargint = va_arg(vp, int);
printdec(vargint);
break;
case 'f':
vargflt = va_arg(vp, double);
/* va_arg(ap, type), if type is narrow type (char, short, float) an error is given in strict ANSI
mode, or a warning otherwise.In non-strict ANSI mode, 'type' is allowed to be any expression. */
print(vargflt);
break;
case 's':
vargpch = va_arg(vp, char*);
print(vargpch);
break;
case 'b':
case 'B':
vargint = va_arg(vp, int);
printbin(vargint);
break;
case 'x':
case 'X':
vargint = va_arg(vp, int);
printhex(vargint);
break;
case '%':
print('%');
break;
case 'o':
case 'O':
vargint = va_arg(vp, int);
printoct(vargint);
break;
default:
break;
}
pfmt++;
}
else{
print(*pfmt++);
}
}
va_end(vp);
}
//2015年9月3日11:41:40 支持 打印 0 和 负数
void Usart::printdec(int dec){
static uint8_t dp = 0;
static int _dec;
if(dec<=0 && dp == 0){
if(dec == 0){
print('0');
return ;
}else{
print('-');
dec = -dec;
}
}
if(dp ==0 ){
dp = 1;
_dec = dec;
}
if(dec==0){
return; }
printdec(dec/10);
print( (char)(dec%10 + '0'));
if(_dec == dec)
dp = 0;
}
void Usart::printflt(double flt){
int tmpint = 0;
tmpint = (int)flt;
printdec(tmpint);
print('.');
flt = flt - tmpint;
flt = flt<0?-flt:flt;
tmpint = (int)(flt * 1000000);
printdec(tmpint);
}
void Usart::printbin(int bin){
if(bin == 0){
//printstr("0b");
return; }
printbin(bin/2);
print( (char)(bin%2 + '0'));
}
void Usart::printhex(int hex){
if(hex==0){
//printstr("0x");
return; }
printhex(hex/16);
if(hex%16 < 10)
print((char)(hex%16 + '0'));
else
print((char)(hex%16 - 10 + 'a' ));
}
void Usart::printoct(int oct){
if(oct==0){
//printstr("8JinZhi");
return;
}
printoct(oct/8);
print((char)(oct%8 + '0'));
}
//________2015-8-31 02:57:51
void Usart::print(char ch){
USART_SendData(usartx, ch); /*发送单个数据 */
while(USART_GetFlagStatus(usartx, USART_FLAG_TXE)==RESET);/* 检测指定的USART标志位 即RESET=1时 发送完成*/
}
void Usart::print(const unsigned char *str){
while(*str){
USART_SendData(usartx, *str); /*发送单个数据 */
while(USART_GetFlagStatus(usartx, USART_FLAG_TXE)==RESET);/* 检测指定的USART标志位 即RESET=1时 发送完成*/
str++;
}
}
void Usart::print(int val, Format format){
switch((uint8_t)format){
case (uint8_t)DEC:
printdec(val);
break;
case (uint8_t)HEX:
printhex(val);
break;
case (uint8_t)BIN:
printbin(val);
break;
case (uint8_t)OCT:
printoct(val);
break;
default:
break;
}
}
int Usart::pow(int a, int n){
int sum = 1;
while(n--){
sum = sum*a;
}
return sum;
}
void Usart::print(double flt, uint8_t para){
int tmpint = 0;
tmpint = (int)flt;
printdec(tmpint);
print('.');
flt = flt - tmpint;
flt = flt<0?-flt:flt;
tmpint = (int)(flt * pow(10, para));
printdec(tmpint);
}
void Usart::println(const char* pfmt, ...){
double vargflt = 0;
int vargint = 0;
char* vargpch = NULL;
char vargch = 0;
va_list vp;
va_start(vp, pfmt);
while(*pfmt){
if(*pfmt == '%'){
switch(*(++pfmt)){
case 'c':
vargch = va_arg(vp, int);
/* va_arg(ap, type), if type is narrow type (char, short, float) an error is given in strict ANSI
mode, or a warning otherwise.In non-strict ANSI mode, 'type' is allowed to be any expression. */
print((char)vargch);
break;
case 'd':
case 'i':
vargint = va_arg(vp, int);
printdec(vargint);
break;
case 'f':
vargflt = va_arg(vp, double);
/* va_arg(ap, type), if type is narrow type (char, short, float) an error is given in strict ANSI
mode, or a warning otherwise.In non-strict ANSI mode, 'type' is allowed to be any expression. */
print(vargflt);
break;
case 's':
vargpch = va_arg(vp, char*);
print(vargpch);
break;
case 'b':
case 'B':
vargint = va_arg(vp, int);
printbin(vargint);
break;
case 'x':
case 'X':
vargint = va_arg(vp, int);
printhex(vargint);
break;
case '%':
print('%');
break;
case 'o':
case 'O':
vargint = va_arg(vp, int);
printoct(vargint);
break;
default:
break;
}
pfmt++;
}
else{
print(*pfmt++);
}
}
va_end(vp);
print("\n");
}
void Usart::println(double flt, uint8_t para){
print(flt, para);
print("\n");
}
void Usart::println(int val, Format format){
print(val, format);
print("\n");
}
//////发送数据
void Usart::write(u8 val){
print((char)val);
}
//请注意 int8_t,vs8 原型都是 int(32位的) 并不是char(8位的)
void Usart::write(char val){
print((char)val);
}
void Usart::write(u16 val){
print((char)BYTE1(val));
print((char)BYTE0(val));
}
void Usart::write(vs16 val){
print((char)BYTE1(val));
print((char)BYTE0(val));
}
void Usart::write(u32 val){
print((char)BYTE3(val));
print((char)BYTE2(val));
print((char)BYTE1(val));
print((char)BYTE0(val));
}
void Usart::write(vs32 val){
print((char)BYTE3(val));
print((char)BYTE2(val));
print((char)BYTE1(val));
print((char)BYTE0(val));
}
//_________发送部分end______________________
unsigned char Usart::read(){
unsigned char ch;
if(USART_GetITStatus(usartx, USART_IT_RXNE) != RESET){
ch = USART_ReceiveData(usartx);
print("%c",ch);
}
return ch;
}
Usart.h
#ifndef __USART_H_
#define __USART_H_
#include "stm32f10x.h"
#include <stdio.h>
#include <stdarg.h>
namespace stm32f10x
{
enum Format
{//2, 10 , 8, 16 进制
BIN=1, DEC, OCT, HEX,
};
#define BYTE0(dwTemp) (*(char *)(&dwTemp))
#define BYTE1(dwTemp) (*((char *)(&dwTemp) + 1))
#define BYTE2(dwTemp) (*((char *)(&dwTemp) + 2))
#define BYTE3(dwTemp) (*((char *)(&dwTemp) + 3))
class Usart{
public:
//初始化部分
Usart(USART_TypeDef* USARTx = USART1,
uint32_t USART_BaudRate = 115200,
uint32_t NVIC_PriorityGroup = NVIC_PriorityGroup_0,
uint8_t NVIC_IRQChannelPreemptionPriority = 0,
uint8_t NVIC_IRQChannelSubPriority = 1
);
void initialize();
//发送字符串部分
void print(const char* ch, ...);
void print(int val, Format format= DEC);
void print(double flt, uint8_t para = 2);
void println(const char* ch = "", ...);
void println(int val, Format format= DEC);
void println(double flt, uint8_t para = 2);
//发送数据部分
void write(u8 val); //unsigned char, uint8_t
void write(char val); //char //请注意 int8_t,vs8 原型都是 int(32位的) 并不是char(8位的)
void write(u16 val); //uint16_t
void write(vs16 val); //int16_t
void write(u32 val); //unsigned int, uint32_t
void write(vs32 val); //int, int32, int8_t, vs8
//接收数据部分
unsigned char read();
private:
USART_TypeDef* usartx;
uint32_t baudRate;
uint32_t nvicPriorityGroup;
uint8_t preemptionPriority;
uint8_t subPriority;
void print(char ch);
void print(const unsigned char *str);
void printdec(int dec);
void printflt(double flt);
void printbin(int bin);
void printhex(int hex);
void printoct(int oct);
int pow(int a, int n);
};
}
#endif
main.cpp
/* Includes ------------------------------------------------------------------*/
#include "stm32f10x.h"
#include "Usart.h"
using namespace stm32f10x;
/* Private functions ---------------------------------------------------------*/
Usart Serial(USART1, 115200);
// Usart Serial;
/**
* @brief Main program.
* @param None
* @retval None
*/
int main(void)
{
// uint8_t val8 = 0x33;
// uint32_t val32 = 0x21122112;
while(1){
Serial.println("1.%f",-123.4545);
Serial.println("2.%o",123);
Serial.println("3.print: %c", 'c');
Serial.println("4.print: %s", "string test");
Serial.println("5.print: %b, %d", 0x12345ff, 4343);
Serial.println("%d", -4343);
Serial.println("6.print: %x", 0xa1d);
// Serial.println("7.print: %%");
// Serial.println(1234, BIN);
// Serial.println(12.3434, 4);
// Serial.write(val8);
// Serial.write(val32);
// Serial.println();
}
}
搞定
你可以到这里下载我已经做好的 STM32 C++ Usart类:
百度云 链接:http://pan.baidu.com/s/1bpbZ2MV 密码:esam
也可以在CSDN里面下载:http://download.csdn.net/detail/github_35160620/9623335
小结:
下一讲,我们来使用 C++ 语言,创建一个 STM32 的 Adc 类。
STM32 C++编程 003 USART(串口)类的更多相关文章
- STM32(6)——USART串口的使用
1. 串口的基本概念 在STM32的参考手册中,串口被描述成通用同步异步收发器(USART),它提供了一种灵活的方法与使用工业标准NRZ异步串行数据格式的外部设备之间进行全双工数据交换.USART利用 ...
- STM32 C++编程 004 Adc (数模转换)类
使用 C++ 语言给 STM32 编写一个 Adc 类 我使用的STM32芯片:STM32F103ZET6 我们使用的STM32库版本:V3.5.0 注意: 想学习本套 STM32 C++编程 的专栏 ...
- STM32 C++编程 005 I2c(Soft)类
使用 C++ 语言给 STM32 编写一个 I2c(Soft)类 我使用的STM32芯片:STM32F103ZET6 我们使用的STM32库版本:V3.5.0 注意: 想学习本套 STM32 C++编 ...
- STM32之旅4——USART
STM32之旅4--USART 串口也是用的比较多的,在STM32CubeMX中生成代码后,需要添加一些代码才可以用. drv_usart.h: #ifndef __DRV_USART_H #defi ...
- STM32 C++编程 002 GPIO类
使用 C++ 语言给 STM32 编写一个 Gpio 类 我使用的STM32芯片:STM32F103ZET6 我们使用的STM32库版本:V3.5.0 注意: 想学习本套 STM32 C++编程 的专 ...
- 单片机stm32 USART串口实际应用解析
stm32作为现在嵌入式物联网单片机行业中经常要用多的技术,相信大家都有所接触,今天这篇就给大家详细的分析下有关于stm32的出口,还不是很清楚的朋友要注意看看了哦,在最后还会为大家分享有些关于stm ...
- stm32 usart 串口
比特率是每秒钟传输二进制代码的位数,单位是:位/秒(bps).如每秒钟传送240个字符, 而每个字符格式包含10位(1个起始位.1个停止位.8个数据位),这时的比特率为: 10位 × 240个/秒 = ...
- 第20章 USART—串口通讯—零死角玩转STM32-F429系列
第20章 USART—串口通讯 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.com/fi ...
- 【STM32H7教程】第29章 STM32H7的USART串口基础知识和HAL库API
完整教程下载地址:http://www.armbbs.cn/forum.php?mod=viewthread&tid=86980 第29章 STM32H7的USART串口基础知识和 ...
随机推荐
- Hash Join 一定是选择小表作为驱动表吗
原来自己也是一直认为oralce会选择小表作为驱动表,以前一直也没注意,今天看了落落大神的实验,才发现,oralce查询时不一定选择小表作为驱动表. 如果对大表增加了约束,大表也会作为驱动表. 实验见 ...
- 分布式事务_02_2PC框架raincat源码解析-启动过程
一.前言 上一节已经将raincat demo工程运行起来了,这一节来分析下raincat启动过程的源码 主要包括: 事务协调者启动过程 事务参与者启动过程 二.协调者启动过程 主要就是在启动类中通过 ...
- 基于zepto移动4*3九宫格转奖
最近根据公司需求,要把移动端的圆形转盘抽奖,改为九宫格的形式,查找资料搞定了,纪录下demo代码. 页面的展现样式,如下 比较简单,就是红色的背景图,在这10个格子里转动 具体代码如下 html &l ...
- 普通方法实现——远程方法调用RMI代码演示
1.spring_RMI01_server服务端 package com.wisezone.service; import java.rmi.Remote; import java.rmi.Remot ...
- 【转】深入剖析Java中的装箱和拆箱
深入剖析Java中的装箱和拆箱 自动装箱和拆箱问题是Java中一个老生常谈的问题了,今天我们就来一些看一下装箱和拆箱中的若干问题.本文先讲述装箱和拆箱最基本的东西,再来看一下面试笔试中经常遇到的与装箱 ...
- 一个Bug 差点让服务器的文件系统崩溃
昨天,公司的美国客户发邮件给我,说我的软件出问题了,我查来查去,发现居然是服务器上一个目录无法删除,一删除就报 cannot read from the source file or disk. 如果 ...
- touch: cannot touch '/usr/local/tomcat/logs/catalina.out': Permission denied解决方法
一.报以下错误: ./startup.sh Using CATALINA_BASE: /usr/local/tomcat702 Using CATALINA_HOME: /usr/local/tomc ...
- 基于TCP协议 I/O多路转接(select) 的高性能回显服务器客户端模型
服务端代码: myselect.c #include <stdio.h> #include <netinet/in.h> #include <arpa/inet.h> ...
- IEEE1588精密网络同步协议(PTP)
1 引言 以太网技术由于其开放性好.价格低廉和使用方便等特点,已经广泛应用于电信级别的网络中,以太网的数据传输速度也从早期的10M提高到100M,GE,10GE.40GE,100GE正式产品也于20 ...
- 推荐几个MySQL大牛的博客
1.淘宝丁奇 http://dinglin.iteye.com/ 2.周振兴@淘宝 花名:苏普 http://www.orczhou.com/ 3. 阿里云数据库高级专家彭立勋为 MariaDB Fo ...