使用 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++ 语言,创建一个 STM32Adc 类。

STM32 C++编程 003 USART(串口)类的更多相关文章

  1. STM32(6)——USART串口的使用

    1. 串口的基本概念 在STM32的参考手册中,串口被描述成通用同步异步收发器(USART),它提供了一种灵活的方法与使用工业标准NRZ异步串行数据格式的外部设备之间进行全双工数据交换.USART利用 ...

  2. STM32 C++编程 004 Adc (数模转换)类

    使用 C++ 语言给 STM32 编写一个 Adc 类 我使用的STM32芯片:STM32F103ZET6 我们使用的STM32库版本:V3.5.0 注意: 想学习本套 STM32 C++编程 的专栏 ...

  3. STM32 C++编程 005 I2c(Soft)类

    使用 C++ 语言给 STM32 编写一个 I2c(Soft)类 我使用的STM32芯片:STM32F103ZET6 我们使用的STM32库版本:V3.5.0 注意: 想学习本套 STM32 C++编 ...

  4. STM32之旅4——USART

    STM32之旅4--USART 串口也是用的比较多的,在STM32CubeMX中生成代码后,需要添加一些代码才可以用. drv_usart.h: #ifndef __DRV_USART_H #defi ...

  5. STM32 C++编程 002 GPIO类

    使用 C++ 语言给 STM32 编写一个 Gpio 类 我使用的STM32芯片:STM32F103ZET6 我们使用的STM32库版本:V3.5.0 注意: 想学习本套 STM32 C++编程 的专 ...

  6. 单片机stm32 USART串口实际应用解析

    stm32作为现在嵌入式物联网单片机行业中经常要用多的技术,相信大家都有所接触,今天这篇就给大家详细的分析下有关于stm32的出口,还不是很清楚的朋友要注意看看了哦,在最后还会为大家分享有些关于stm ...

  7. stm32 usart 串口

    比特率是每秒钟传输二进制代码的位数,单位是:位/秒(bps).如每秒钟传送240个字符, 而每个字符格式包含10位(1个起始位.1个停止位.8个数据位),这时的比特率为: 10位 × 240个/秒 = ...

  8. 第20章 USART—串口通讯—零死角玩转STM32-F429系列

    第20章      USART—串口通讯 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.com/fi ...

  9. 【STM32H7教程】第29章 STM32H7的USART串口基础知识和HAL库API

    完整教程下载地址:http://www.armbbs.cn/forum.php?mod=viewthread&tid=86980 第29章       STM32H7的USART串口基础知识和 ...

随机推荐

  1. 解决让浏览器兼容ES6特性

    为什么ES6会有兼容性问题? 由于广大用户使用的浏览器版本在发布的时候也许早于ES6的定稿和发布,而到了今天,我们在编程中如果使用了ES6的新特性,浏览器若没有更新版本,或者新版本中没有对ES6的特性 ...

  2. SVN服务器端客户端配置, 及对比VSS的优势

    SVN 版本服务器搭配全过程详解(含服务端.客户端) SVN服务器端及客户端全套软件 SVN对比VSS的优势 两者区别:http://www.cnblogs.com/zxjyuan/archive/2 ...

  3. java学习笔记 --- 多线程(1)

    1:要想了解多线程,必须先了解线程,而要想了解线程,必须先了解进程,因为线程是依赖于进程而存在. 2:什么是进程? 通过任务管理器我们就看到了进程的存在. 而通过观察,我们发现只有运行的程序才会出现进 ...

  4. python编程实例-统计apache进程占用的物理内存

    #!/usr/bin/env python import os from subprocess import PIPE,Popen def getPids(): p = Popen(['pidof', ...

  5. sql-多表查询JOIN与分组GROUP BY

    一.内部连接:两个表的关系是平等的,可以从两个表中获取数据.用ON表示连接条件 SELECT A.a,B.b FROM At AS A  INNER JOINT Bt AS B ON  A.m=B.n ...

  6. nginx location配置与rewrite配置

    注:原文出处 www.linuxidc.com/Linux/2015-06/119398.htm 1. location正则写法 一个示例: location =/{ # 精确匹配 / ,主机名后面不 ...

  7. [HDU5324]Boring Class

    vjudge sol 字典序最小可以通过倒着\(dp\)解决.对每个\(i\)记录它可以转移到的\(dp\)值最大且字典序最小的\(nxt_i\). 尝试着写一下\(dp\)式子. \[dp_i=ma ...

  8. LeetCode 315. Count of Smaller Numbers After Self

    原题链接在这里:https://leetcode.com/problems/count-of-smaller-numbers-after-self/ 题目: You are given an inte ...

  9. 基于Python语言使用RabbitMQ消息队列(二)

    工作队列 在第一节我们写了程序来向命名队列发送和接收消息 .在本节我们会创建一个工作队列(Work Queue)用来在多个工人(worker)中分发时间消耗型任务(time-consuming tas ...

  10. Vue forms

    Vue forms Vue 的表单. 表单中的数据和是双向绑定的. 你可以使用 v-model 对控件元素进行数据双向绑定. 比较有用的修饰符 .lazy .number .trim