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("
");
}

void Usart::println(double flt, uint8_t  para){
    print(flt, para);
    print("
");
}

void Usart::println(int val, Format format){
    print(val, format);
    print("
");
}

//////发送数据
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 类。

原文地址:https://www.cnblogs.com/aobosir/p/5928568.html