1. 程式人生 > >STM32F4之串列埠(三)

STM32F4之串列埠(三)

實現STM32開發板向計算機傳送資料就需要準備好STM32開發板和上位接收程式。
上位機部分使用QT開發,版本為5.8.0
STM32部分使用STM32F429晶片,開發環境為uVision V5.24.2.0

上位機效果為:
在這裡插入圖片描述

程式碼如下:
mainwindow.h檔案:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QDebug>
#include <QtSerialPort/QSerialPort>
#include <QtSerialPort/QSerialPortInfo>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private slots:
    void on_clearButton_clicked();

    void on_sendButton_clicked();

    void on_openButton_clicked();

    void Read_Data();
private:
    Ui::MainWindow *ui;
    QSerialPort *serial;
};

#endif // MAINWINDOW_H

mainwindow.cpp檔案:

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    //查詢可用的串列埠
    foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
    {
        QSerialPort serial;
        serial.setPort(info);
        if(serial.open(QIODevice::ReadWrite))
        {
            ui -> PortBox ->addItem(serial.portName());
            serial.close();
        }
    }

    //設定波特率下拉選單預設顯示第三項
    ui -> BaudBox -> setCurrentIndex(3);
    //關閉傳送按鈕的使能
    ui -> sendButton -> setEnabled(false);
    qDebug() << tr("介面設定成功!");
}

MainWindow::~MainWindow()
{
    delete ui;
}

//清空接收視窗
void MainWindow::on_clearButton_clicked()
{
    ui -> textEdit -> clear();
}

void MainWindow::on_sendButton_clicked()
{
    serial -> write(ui -> textEdit_2 -> toPlainText().toLatin1());
}

void MainWindow::Read_Data()
{
    QByteArray buf;
    buf = serial -> readAll();
    if(!buf.isEmpty())
    {
        QString str = ui -> textEdit -> toPlainText();
        str += tr(buf);
        ui -> textEdit -> clear();
        ui -> textEdit -> append(str);
    }
    buf.clear();
}

void MainWindow::on_openButton_clicked()
{
    if(ui -> openButton -> text() == tr("開啟串列埠"))
    {
        serial = new QSerialPort;
        //設定串列埠名
        serial -> setPortName(ui -> PortBox -> currentText());
        //開啟串列埠
        serial -> open(QIODevice::ReadWrite);
        //設定波特率
        serial -> setBaudRate(ui -> BaudBox -> currentText().toInt());
        //設定資料位
        switch(ui -> BitNumBox -> currentIndex())
        {
        case 8:
            serial -> setDataBits(QSerialPort::Data8);
            break;
        default:
            break;
        }
        //設定奇偶校驗位
        switch(ui -> ParityBox -> currentIndex())
        {
        case 0:
            serial -> setParity(QSerialPort::NoParity);
            break;
        default:
            break;
        }
        //設定停止位
        switch(ui -> StopBox -> currentIndex())
        {
        case 1:
            serial -> setStopBits(QSerialPort::OneStop);
            break;
        case 2:
            serial -> setStopBits(QSerialPort::TwoStop);
            break;
        default:
            break;
        }

        //設定控制流
        serial -> setFlowControl(QSerialPort::NoFlowControl);
        //關閉設定選單使能
        ui -> PortBox -> setEnabled(false);
        ui -> BaudBox -> setEnabled(false);
        ui -> BitNumBox -> setEnabled(false);
        ui -> ParityBox -> setEnabled(false);
        ui -> StopBox -> setEnabled(false);
        ui -> openButton -> setText(tr("關閉串列埠"));
        ui -> sendButton -> setEnabled(false);
    }
    else
    {
        //關閉串列埠
        serial -> clear();
        serial -> close();
        serial -> deleteLater();
        //恢復設定使能
        ui -> PortBox -> setEnabled(true);
        ui -> BaudBox -> setEnabled(true);
        ui -> BitNumBox -> setEnabled(true);
        ui -> ParityBox -> setEnabled(true);
        ui -> StopBox -> setEnabled(true);
        ui -> openButton -> setText(tr("開啟串列埠"));
        ui -> sendButton -> setEnabled(true);
    }

    //連線訊號槽
    QObject::connect(serial, &QSerialPort::readyRead, this, &MainWindow::Read_Data);
}

main.c檔案為:

#include "mainwindow.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();

    return a.exec();
}

mainwidow.ui為:
在這裡插入圖片描述

STM32硬體驅動程式程式碼如下:
main.c檔案:

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"

int main(void)
{
	u8 t;	
	u8 len;
	u16 times = 0;
	Stm32_Clock_Init(360, 25, 2, 8);
	delay_init(180);
	uart_init(90, 115200);
	LED_Init();
	
	while(1)
	{
		if(USART_RX_STA & 0x8000)
		{
			len = USART_RX_STA & 0x3fff;
			printf("\r\n You send information is: \r\n");
			for(t = 0; t < len; t++)
			{
				USART1 -> DR = USART_RX_BUF[t];
				while(0 == (USART1 -> SR & 0x40));
			}
			printf("\r\n\r\n");
			USART_RX_STA = 0;
		}
		else
		{
			times++;
			if(0 == times % 5000)
			{
				printf("\r\nALIENTEK MXX STM32F4/F7 develop board Serial test\r\n");
				printf("
[email protected]
\r\n\r\n\r\n"); } if(0 == times % 200) { printf("Please input data and end with ENTER\r\n"); } if(0 == times % 30) { LED0 = !LED0; } delay_ms(10); } } }

串列埠初始化程式碼:

void uart_init(u32 pclk2,u32 bound)
{  	 
	float temp;
	u16 mantissa;
	u16 fraction;	   
	temp=(float)(pclk2*1000000)/(bound*16);
	mantissa=temp;				
	fraction=(temp-mantissa)*16;
    mantissa<<=4;
	mantissa+=fraction; 
	RCC->AHB1ENR|=1<<0;   	
	RCC->APB2ENR|=1<<4;  
	GPIO_Set(GPIOA,PIN9|PIN10,GPIO_MODE_AF,GPIO_OTYPE_PP,GPIO_SPEED_50M,GPIO_PUPD_PU);
 	GPIO_AF_Set(GPIOA,9,7);	//PA9,AF7
	GPIO_AF_Set(GPIOA,10,7);//PA10,AF7  	   
	//²¨ÌØÂÊÉèÖÃ
 	USART1->BRR=mantissa; 	
	USART1->CR1&=~(1<<15); 	
	USART1->CR1|=1<<3;  	
#if EN_USART1_RX		  
	USART1->CR1|=1<<2;  	
	USART1->CR1|=1<<5;    		    	
	MY_NVIC_Init(3,3,USART1_IRQn,2);
#endif
	USART1->CR1|=1<<13;  	
}

由此變簡單的實現了STM32向PC機發送資料程式。