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串口基础知识和 ...
随机推荐
- 解决让浏览器兼容ES6特性
为什么ES6会有兼容性问题? 由于广大用户使用的浏览器版本在发布的时候也许早于ES6的定稿和发布,而到了今天,我们在编程中如果使用了ES6的新特性,浏览器若没有更新版本,或者新版本中没有对ES6的特性 ...
- SVN服务器端客户端配置, 及对比VSS的优势
SVN 版本服务器搭配全过程详解(含服务端.客户端) SVN服务器端及客户端全套软件 SVN对比VSS的优势 两者区别:http://www.cnblogs.com/zxjyuan/archive/2 ...
- java学习笔记 --- 多线程(1)
1:要想了解多线程,必须先了解线程,而要想了解线程,必须先了解进程,因为线程是依赖于进程而存在. 2:什么是进程? 通过任务管理器我们就看到了进程的存在. 而通过观察,我们发现只有运行的程序才会出现进 ...
- python编程实例-统计apache进程占用的物理内存
#!/usr/bin/env python import os from subprocess import PIPE,Popen def getPids(): p = Popen(['pidof', ...
- sql-多表查询JOIN与分组GROUP BY
一.内部连接:两个表的关系是平等的,可以从两个表中获取数据.用ON表示连接条件 SELECT A.a,B.b FROM At AS A INNER JOINT Bt AS B ON A.m=B.n ...
- nginx location配置与rewrite配置
注:原文出处 www.linuxidc.com/Linux/2015-06/119398.htm 1. location正则写法 一个示例: location =/{ # 精确匹配 / ,主机名后面不 ...
- [HDU5324]Boring Class
vjudge sol 字典序最小可以通过倒着\(dp\)解决.对每个\(i\)记录它可以转移到的\(dp\)值最大且字典序最小的\(nxt_i\). 尝试着写一下\(dp\)式子. \[dp_i=ma ...
- LeetCode 315. Count of Smaller Numbers After Self
原题链接在这里:https://leetcode.com/problems/count-of-smaller-numbers-after-self/ 题目: You are given an inte ...
- 基于Python语言使用RabbitMQ消息队列(二)
工作队列 在第一节我们写了程序来向命名队列发送和接收消息 .在本节我们会创建一个工作队列(Work Queue)用来在多个工人(worker)中分发时间消耗型任务(time-consuming tas ...
- Vue forms
Vue forms Vue 的表单. 表单中的数据和是双向绑定的. 你可以使用 v-model 对控件元素进行数据双向绑定. 比较有用的修饰符 .lazy .number .trim