zoukankan      html  css  js  c++  java
  • 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 类。

  • 相关阅读:
    《一线架构师》之Refined Architecture阶段
    可修改性战术分析
    上周学习总结
    软件质量属性之可修改性
    《信息领域热词分析》实现六种质量属性
    质量属性的六个常见属性应用场景(淘宝篇)
    软件架构师如何工作
    信息领域热词分析
    结合ssh谈MVC架构模式
    PythonCPPJava的异同
  • 原文地址:https://www.cnblogs.com/aobosir/p/5928568.html
Copyright © 2011-2022 走看看