STM32 C++编程 003 USART(串口)类

来源:互联网 发布:泰达网络wifi 编辑:程序博客网 时间:2024/06/04 18:48

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

0 0
原创粉丝点击