使用 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 类。

最新文章

  1. Unity 延迟执行一段代码的较为优雅的方式
  2. Innodb Read IO 相关参数源代码解析
  3. POP3,全名为“Post Office Protocol - Version 3”,即“邮局协议版本3”
  4. hdoj 5391 Zball in Tina Town
  5. js之createTextRange方法
  6. 第五章 HID设备
  7. jQuery实现checkbox全选反选及删除等操作
  8. android图片加水印,文字
  9. volt问题
  10. WebAssembly让你的Javascript计算性能提升70%
  11. 精选 TOP45 值得学习的Python项目
  12. websocket Tomcat JSP Demo
  13. vue props的理解
  14. DBCP连接数据库了解一下
  15. 红帽子系统链接加vm15秘钥一份
  16. 在vue项目中使用swiper2.7.6
  17. WPF 事件触发命令
  18. 安装、启动consul
  19. coreseek mmseg分词配置和创建
  20. codeforces Gravity Flip 题解

热门文章

  1. Mybatis 接口方式对数据的增删改查 一对一关联查询
  2. android中shape的属性
  3. github 第一次使用及出现的问题解决
  4. hdoj-2141-Can you find it?(二分查找)
  5. C# XML反序列化与序列化举例:XmlSerializer
  6. BZOJ2038:[2009国家集训队]小Z的袜子
  7. Road to OI
  8. mysql 查找表的auto_increment和修改
  9. ABP 学习系列 - 目录
  10. PHP7卓越性能背后的原理有哪些?