中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁(yè) > news >正文

企業(yè)網(wǎng)站哪里可以做廣告外鏈購(gòu)買交易平臺(tái)

企業(yè)網(wǎng)站哪里可以做,廣告外鏈購(gòu)買交易平臺(tái),集約化模式建設(shè)黨政機(jī)關(guān)網(wǎng)站,手機(jī)app可以做網(wǎng)站嗎上一節(jié)我們學(xué)習(xí)了串口通信的基本理論,串口通信是學(xué)習(xí)單片機(jī)的一個(gè)重要的一步,非常重要,這一節(jié)我們通過(guò)實(shí)驗(yàn)來(lái)學(xué)習(xí)串口通信的使用,以及串口的接收中斷的使用。 一、發(fā)送單個(gè)字節(jié)uint8_t數(shù)據(jù)或者字符型數(shù)據(jù) 實(shí)現(xiàn)的功能:…

? ? ? ?上一節(jié)我們學(xué)習(xí)了串口通信的基本理論,串口通信是學(xué)習(xí)單片機(jī)的一個(gè)重要的一步,非常重要,這一節(jié)我們通過(guò)實(shí)驗(yàn)來(lái)學(xué)習(xí)串口通信的使用,以及串口的接收中斷的使用。

一、發(fā)送單個(gè)字節(jié)uint8_t數(shù)據(jù)或者字符型數(shù)據(jù)

實(shí)現(xiàn)的功能:

? ? ? ?STM32F4 通過(guò)串口和上位機(jī)通信,發(fā)送單個(gè)字節(jié)數(shù)據(jù)(0-255)或者字符給上位機(jī),然后顯示在電腦串口助手上。

my_usart.h文件內(nèi)容

#ifndef  __MY_USART1_H__
#define  __MY_USART1_H__
#include <stdint.h>void My_UsartInit(void);           //串口初始化
void Usart_SendByte(uint8_t date);  //發(fā)送一字節(jié)函數(shù)#endif

my_usart.c文件內(nèi)容

#include "stm32f4xx.h"
#include "myusart.h"
#include<stdio.h>   //對(duì)printf()函數(shù)進(jìn)行重定向引入頭文件/******************************第一步:串口時(shí)鐘使能,GPIO 時(shí)鐘使能。第二步:設(shè)置引腳復(fù)用器映射:調(diào)用 GPIO_PinAFConfig 函數(shù)第三步:GPIO 初始化設(shè)置:要設(shè)置模式為復(fù)用功能第四步:串口初始化:設(shè)置波特率,字長(zhǎng),奇偶校驗(yàn)等參數(shù)。第五步:使能串口*/void My_UsartInit(void)
{//1.第一步:串口時(shí)鐘使能,GPIO 時(shí)鐘使能RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//2.第二步:設(shè)置引腳復(fù)用器映射:調(diào)用 GPIO_PinAFConfig 函數(shù)GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1);GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_USART1);//3.第三步:GPIO 初始化設(shè)置:要設(shè)置模式為復(fù)用功能GPIO_InitTypeDef Struct1;Struct1.GPIO_Mode=GPIO_Mode_AF;Struct1.GPIO_Pin=GPIO_Pin_9 |GPIO_Pin_10;Struct1.GPIO_Speed=GPIO_Speed_100MHz;GPIO_Init(GPIOA,&Struct1);//4.第四步:串口初始化:設(shè)置波特率,字長(zhǎng),奇偶校驗(yàn)等參數(shù)。USART_InitTypeDef Struct2;Struct2.USART_BaudRate=115200;                                        //設(shè)置波特率Struct2.USART_WordLength=USART_WordLength_8b;                        //數(shù)據(jù)位8位Struct2.USART_Parity=USART_Parity_No;                               //無(wú)校驗(yàn)位Struct2.USART_StopBits=USART_StopBits_1;                           //1位停止位Struct2.USART_HardwareFlowControl=USART_HardwareFlowControl_None; //不需要硬件流控Struct2.USART_Mode=	USART_Mode_Rx |USART_Mode_Tx;                //設(shè)置usart1既可以接收也可以發(fā)送USART_Init(USART1,&Struct2);//5.第五步:使能串口USART_Cmd(USART1,ENABLE);}//發(fā)送一字節(jié)(一個(gè)字符)函數(shù)
void Usart_SendByte(uint8_t data)
{USART_SendData(USART1,data);       //這是一個(gè)庫(kù)函數(shù),用于將一個(gè)字節(jié)的數(shù)據(jù)寫入U(xiǎn)SART的數(shù)據(jù)寄存器                               while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);    //等待發(fā)送完畢}//對(duì)printf()函數(shù)進(jìn)行重定向
int fputc(int ch, FILE *f)
{USART_SendData(USART1,ch);                                    //通過(guò)串口發(fā)送數(shù)據(jù),每次發(fā)送一個(gè)字符while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);    //等待發(fā)送完畢return ch;
}

?main.c代碼

#include <stdio.h>
#include "myusart.h"int main(void)
{My_UsartInit();printf("發(fā)送一個(gè)字節(jié):\n");Usart_SendByte('a');printf("\n");Usart_SendByte(97);printf("\n");while(1){}}

關(guān)鍵部分解讀:

? ? ?發(fā)送過(guò)程:調(diào)用串口發(fā)送函數(shù)USART_SendData(),但是需要保證在發(fā)送下一個(gè)字節(jié)之前,必須確保當(dāng)前字節(jié)已被成功發(fā)送。否則可能會(huì)導(dǎo)致新數(shù)據(jù)寫入時(shí)覆蓋未發(fā)送完的數(shù)據(jù),造成通信錯(cuò)誤。因此,內(nèi)部使用死循環(huán)來(lái)控制,調(diào)用庫(kù)函數(shù)USART_GetFlagStatus()檢查標(biāo)志位來(lái)判斷發(fā)送的狀態(tài)!

  • 這個(gè)while循環(huán)的作用是等待USART的數(shù)據(jù)寄存器空標(biāo)志(TXE)被置位。當(dāng)發(fā)送數(shù)據(jù)寄存器(TDR)中有數(shù)據(jù)時(shí),TXE標(biāo)志為RESET。只有當(dāng)TDR中的數(shù)據(jù)已被移到移位寄存器中,TXE標(biāo)志才會(huì)被置位。當(dāng)TXE標(biāo)志為SET時(shí),表示發(fā)送數(shù)據(jù)寄存器已空,可以發(fā)送下一個(gè)字節(jié)
  • 具體來(lái)說(shuō),發(fā)送數(shù)據(jù)過(guò)程包括:
    1. 將數(shù)據(jù)寫入TDR。
    2. 數(shù)據(jù)從TDR移到移位寄存器。
    3. 當(dāng)移位寄存器開(kāi)始發(fā)送數(shù)據(jù)時(shí),TDR變空,TXE標(biāo)志被置位。
  • while循環(huán)確保在TDR變空之前不會(huì)發(fā)送新的數(shù)據(jù),從而避免數(shù)據(jù)丟失或覆蓋。

?

二、發(fā)送一個(gè)16位的數(shù)據(jù)uint16_t

實(shí)現(xiàn)的功能:

? ? ? ?STM32F4 通過(guò)串口和上位機(jī)通信,發(fā)送兩個(gè)字節(jié)數(shù)據(jù)(16位)給上位機(jī),然后顯示在電腦串口助手上。我們知道串口通信一次只能發(fā)送8位的數(shù)據(jù),那么如何實(shí)現(xiàn)一次發(fā)16位呢?

my_usart.h文件內(nèi)容

#ifndef  __MY_USART1_H__
#define  __MY_USART1_H__
#include <stdint.h>void My_UsartInit(void);           //串口初始化
void USART_SendHalfWord(uint16_t data);  //發(fā)送兩個(gè)字節(jié)函數(shù)#endif

my_usart.c

#include "stm32f4xx.h"
#include "myusart.h"
#include <stdio.h>   //對(duì)printf()函數(shù)進(jìn)行重定向引入頭文件/******************************第一步:串口時(shí)鐘使能,GPIO 時(shí)鐘使能。第二步:設(shè)置引腳復(fù)用器映射:調(diào)用 GPIO_PinAFConfig 函數(shù)第三步:GPIO 初始化設(shè)置:要設(shè)置模式為復(fù)用功能第四步:串口初始化:設(shè)置波特率,字長(zhǎng),奇偶校驗(yàn)等參數(shù)。第五步:使能串口*/void My_UsartInit(void)
{//1.第一步:串口時(shí)鐘使能,GPIO 時(shí)鐘使能RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//2.第二步:設(shè)置引腳復(fù)用器映射:調(diào)用 GPIO_PinAFConfig 函數(shù)GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1);GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_USART1);//3.第三步:GPIO 初始化設(shè)置:要設(shè)置模式為復(fù)用功能GPIO_InitTypeDef Struct1;Struct1.GPIO_Mode=GPIO_Mode_AF;Struct1.GPIO_Pin=GPIO_Pin_9 |GPIO_Pin_10;Struct1.GPIO_Speed=GPIO_Speed_100MHz;GPIO_Init(GPIOA,&Struct1);//4.第四步:串口初始化:設(shè)置波特率,字長(zhǎng),奇偶校驗(yàn)等參數(shù)。USART_InitTypeDef Struct2;Struct2.USART_BaudRate=115200;                                        //設(shè)置波特率Struct2.USART_WordLength=USART_WordLength_8b;                        //數(shù)據(jù)位8位Struct2.USART_Parity=USART_Parity_No;                               //無(wú)校驗(yàn)位Struct2.USART_StopBits=USART_StopBits_1;                           //1位停止位Struct2.USART_HardwareFlowControl=USART_HardwareFlowControl_None; //不需要硬件流控Struct2.USART_Mode=	USART_Mode_Rx |USART_Mode_Tx;                //設(shè)置usart1既可以接收也可以發(fā)送USART_Init(USART1,&Struct2);//5.第五步:使能串口USART_Cmd(USART1,ENABLE);}//發(fā)送兩個(gè)字節(jié)(16位)數(shù)據(jù)函數(shù)
void USART_SendHalfWord(uint16_t data) 
{// 分離高8位和低8位uint8_t tmp_h = data >>0x08;//將date右移8位,取得高8位數(shù)據(jù)并賦值給tmp_h。右移8位相當(dāng)于將高8位移到低8位的位置,高8位的原位置被0填充。uint8_t tmp_l = data & 0xFF;//將date和0xff(255,二進(jìn)制為11111111)高八位為0,進(jìn)行按位與運(yùn)算,取得低8位數(shù)據(jù)并賦值給tmp_l。按位與運(yùn)算將高8位清零,僅保留低8位。// 發(fā)送高8位USART_SendData(USART1, tmp_h);  while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);// 發(fā)送低8位USART_SendData(USART1, tmp_l);while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);}//對(duì)printf()函數(shù)進(jìn)行重定向
int fputc(int ch, FILE *f)
{USART_SendData(USART1,ch);                                    //通過(guò)串口發(fā)送數(shù)據(jù),每次發(fā)送一個(gè)字符while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);    //等待發(fā)送完畢return ch;
}

main.c

#include <stdio.h>
#include "myusart.h"int main(void)
{My_UsartInit();//發(fā)送兩個(gè)字節(jié)的數(shù)據(jù)USART_SendHalfWord(0xffee);while(1){}}

關(guān)鍵部分解讀:

? ? ? ?串行通信接口通常一次只能處理8位數(shù)據(jù),那么,我們就可以通過(guò)位運(yùn)算拿到數(shù)據(jù)的高八位和低八位分別發(fā)送,Usart_SendHalfWord函數(shù)將16位數(shù)據(jù)分成兩個(gè)8位數(shù)據(jù)(高8位和低8位),然后分別通過(guò)Usart_SendByte函數(shù)發(fā)送出去。這種方式在串行通信中很常見(jiàn)。

使用示例

假設(shè)我們有一個(gè)要發(fā)送的16位數(shù)據(jù)0x1234

  1. tmp_h = 0x120x1234右移8位得到高8位0x12
  2. tmp_l = 0x340x12340xff按位與得到低8位0x34
  3. 調(diào)用Usart_SendByte(pUSARTx, 0x12)發(fā)送高8位。
  4. 調(diào)用Usart_SendByte(pUSARTx, 0x34)發(fā)送低8位。

這確保16位數(shù)據(jù)能夠通過(guò)支持8位傳輸?shù)腢SART接口完整發(fā)送。

三、發(fā)送8位的數(shù)組(uint8_t)

實(shí)現(xiàn)的功能:

? ? ? ?STM32F4 通過(guò)串口和上位機(jī)通信,發(fā)送一個(gè)數(shù)組(每個(gè)元素都是uint8_t類型)或者字符數(shù)組給上位機(jī),然后顯示在電腦串口助手上。

my_usart.h

#ifndef  __MY_USART1_H__
#define  __MY_USART1_H__
#include <stdint.h>void My_UsartInit(void);           //串口初始化
void Usart_SendByte(uint8_t date);  //發(fā)送一字節(jié)函數(shù)
void USART1_SendArray(uint8_t *array, uint16_t length);//發(fā)送一個(gè)數(shù)組
#endif

my_usart.c

#include "stm32f4xx.h"
#include "myusart.h"
#include<stdio.h>   //對(duì)printf()函數(shù)進(jìn)行重定向引入頭文件/******************************第一步:串口時(shí)鐘使能,GPIO 時(shí)鐘使能。第二步:設(shè)置引腳復(fù)用器映射:調(diào)用 GPIO_PinAFConfig 函數(shù)第三步:GPIO 初始化設(shè)置:要設(shè)置模式為復(fù)用功能第四步:串口初始化:設(shè)置波特率,字長(zhǎng),奇偶校驗(yàn)等參數(shù)。第五步:使能串口*/void My_UsartInit(void)
{//1.第一步:串口時(shí)鐘使能,GPIO 時(shí)鐘使能RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//2.第二步:設(shè)置引腳復(fù)用器映射:調(diào)用 GPIO_PinAFConfig 函數(shù)GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1);GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_USART1);//3.第三步:GPIO 初始化設(shè)置:要設(shè)置模式為復(fù)用功能GPIO_InitTypeDef Struct1;Struct1.GPIO_Mode=GPIO_Mode_AF;Struct1.GPIO_Pin=GPIO_Pin_9 |GPIO_Pin_10;Struct1.GPIO_Speed=GPIO_Speed_100MHz;GPIO_Init(GPIOA,&Struct1);//4.第四步:串口初始化:設(shè)置波特率,字長(zhǎng),奇偶校驗(yàn)等參數(shù)。USART_InitTypeDef Struct2;Struct2.USART_BaudRate=115200;                                        //設(shè)置波特率Struct2.USART_WordLength=USART_WordLength_8b;                        //數(shù)據(jù)位8位Struct2.USART_Parity=USART_Parity_No;                               //無(wú)校驗(yàn)位Struct2.USART_StopBits=USART_StopBits_1;                           //1位停止位Struct2.USART_HardwareFlowControl=USART_HardwareFlowControl_None; //不需要硬件流控Struct2.USART_Mode=	USART_Mode_Rx |USART_Mode_Tx;                //設(shè)置usart1既可以接收也可以發(fā)送USART_Init(USART1,&Struct2);//5.第五步:使能串口USART_Cmd(USART1,ENABLE);}//發(fā)送一字節(jié)函數(shù)
void Usart_SendByte(uint8_t data)
{USART_SendData(USART1,data);                                   while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);    //等待發(fā)送完畢}//發(fā)送一個(gè)數(shù)組
void USART1_SendArray(uint8_t *array, uint16_t len)
{for (uint16_t i = 0; i < len; i++){Usart_SendByte(array[i]);}
}//對(duì)printf()函數(shù)進(jìn)行重定向
int fputc(int ch, FILE *f)
{USART_SendData(USART1,ch);                                    //通過(guò)串口發(fā)送數(shù)據(jù),每次發(fā)送一個(gè)字符while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);    //等待發(fā)送完畢return ch;
}

main.c

#include <stdio.h>
#include "myusart.h"int main(void)
{My_UsartInit();// 要發(fā)送的字節(jié)數(shù)組uint8_t dataArray1[] = {1,2,3,4,5,6,7,8,9,10};int len =sizeof(dataArray1) / sizeof(dataArray1[0]);// 發(fā)送一個(gè)數(shù)組	USART1_SendArray(dataArray1, len);while (1){}}

四、發(fā)送字符串?dāng)?shù)據(jù)

實(shí)現(xiàn)的功能:

? ? ? ?STM32F4 通過(guò)串口和上位機(jī)通信,發(fā)送字符串給電腦,然后顯示在電腦串口助手上。

my_usart.h文件內(nèi)容

#ifndef  __MY_USART1_H__
#define  __MY_USART1_H__
#include <stdint.h>void My_UsartInit(void);           //串口初始化
void USART1_SendString(char *str);  //發(fā)送一個(gè)字符串
#endif

my_usart.c文件內(nèi)容

#include "stm32f4xx.h"
#include "myusart.h"
#include<stdio.h>   //對(duì)printf()函數(shù)進(jìn)行重定向引入頭文件/******************************第一步:串口時(shí)鐘使能,GPIO 時(shí)鐘使能。第二步:設(shè)置引腳復(fù)用器映射:調(diào)用 GPIO_PinAFConfig 函數(shù)第三步:GPIO 初始化設(shè)置:要設(shè)置模式為復(fù)用功能第四步:串口初始化:設(shè)置波特率,字長(zhǎng),奇偶校驗(yàn)等參數(shù)。第五步:使能串口*/void My_UsartInit(void)
{//1.第一步:串口時(shí)鐘使能,GPIO 時(shí)鐘使能RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//2.第二步:設(shè)置引腳復(fù)用器映射:調(diào)用 GPIO_PinAFConfig 函數(shù)GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1);GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_USART1);//3.第三步:GPIO 初始化設(shè)置:要設(shè)置模式為復(fù)用功能GPIO_InitTypeDef Struct1;Struct1.GPIO_Mode=GPIO_Mode_AF;Struct1.GPIO_Pin=GPIO_Pin_9 |GPIO_Pin_10;Struct1.GPIO_Speed=GPIO_Speed_100MHz;GPIO_Init(GPIOA,&Struct1);//4.第四步:串口初始化:設(shè)置波特率,字長(zhǎng),奇偶校驗(yàn)等參數(shù)。USART_InitTypeDef Struct2;Struct2.USART_BaudRate=115200;                                        //設(shè)置波特率Struct2.USART_WordLength=USART_WordLength_8b;                        //數(shù)據(jù)位8位Struct2.USART_Parity=USART_Parity_No;                               //無(wú)校驗(yàn)位Struct2.USART_StopBits=USART_StopBits_1;                           //1位停止位Struct2.USART_HardwareFlowControl=USART_HardwareFlowControl_None; //不需要硬件流控Struct2.USART_Mode=	USART_Mode_Rx |USART_Mode_Tx;                //設(shè)置usart1既可以接收也可以發(fā)送USART_Init(USART1,&Struct2);//5.第五步:使能串口USART_Cmd(USART1,ENABLE);}//發(fā)送一個(gè)字符串
void USART1_SendString(char *str)
{while (*str!='\0'){USART_SendData(USART1,*str);while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);    //等待發(fā)送完畢str++;}
}//對(duì)printf()函數(shù)進(jìn)行重定向
int fputc(int ch, FILE *f)
{USART_SendData(USART1,ch);                                    //通過(guò)串口發(fā)送數(shù)據(jù),每次發(fā)送一個(gè)字符while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);    //等待發(fā)送完畢return ch;
}

main.c內(nèi)容:

#include <stdio.h>
#include "myusart.h"int main(void)
{My_UsartInit();// 要發(fā)送的字符串char *dataString = "Hello World!";// 發(fā)送字符串printf("發(fā)送一個(gè)字符串:\n");USART1_SendString(dataString);printf("\n");while (1){  }}

五、單片機(jī)接收電腦發(fā)送的數(shù)據(jù)顯示在串口助手上(接收中斷)

? ? ? ?使用串口接收中斷可以讓CPU在沒(méi)有數(shù)據(jù)到達(dá)時(shí)執(zhí)行其他任務(wù),而不需要浪費(fèi)時(shí)間輪詢接收寄存器。這提高了CPU利用率和系統(tǒng)效率,檢查標(biāo)志位判斷是否發(fā)生接收中斷(USART_IT_RXNE),如果是,讀取接收到的數(shù)據(jù),然后通過(guò)清除接收中斷標(biāo)志以準(zhǔn)備接收下一個(gè)字節(jié)。

實(shí)現(xiàn)的功能:

? ? ? 將接收數(shù)據(jù)設(shè)置為接收中斷當(dāng)上位機(jī)發(fā)送數(shù)據(jù)到STM32F407的USART1時(shí),STM32會(huì)接收這個(gè)數(shù)據(jù)并通過(guò)中斷處理函數(shù)將數(shù)據(jù)發(fā)送回上位機(jī)。上位機(jī)的串口助手會(huì)顯示發(fā)送和接收的數(shù)據(jù)。

my_usart.h

#ifndef  __MY_USART1_H__
#define  __MY_USART1_H__
#include <stdint.h>void USART1_Config(void);        //串口配置
void USART1_SendByte(uint8_t data); //發(fā)送一個(gè)字節(jié)函數(shù)
void USART1_IRQHandler(void);      //中斷服務(wù)函數(shù)
#endif

my_usart.c

#include "stm32f4xx.h"
#include "myusart.h"
#include<stdio.h>   //對(duì)printf()函數(shù)進(jìn)行重定向引入頭文件/******************************第一步:串口時(shí)鐘使能,GPIO 時(shí)鐘使能。第二步:設(shè)置引腳復(fù)用器映射:調(diào)用 GPIO_PinAFConfig 函數(shù)。第三步:GPIO 初始化設(shè)置:要設(shè)置模式為復(fù)用功能。第四步:串口初始化:設(shè)置波特率,字長(zhǎng),奇偶校驗(yàn)等參數(shù)。第五步:開(kāi)啟中斷并且初始化 NVIC,使能中斷(如果需要開(kāi)啟中斷才需要這個(gè)步驟)。第六步:使能串口。第七步:編寫中斷處理函數(shù):函數(shù)名格式為 USARTxIRQHandler(x 對(duì)應(yīng)串口號(hào))。*/void USART1_Config(void)
{//第一步:串口時(shí)鐘使能,GPIO 時(shí)鐘使能RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);//第二步:設(shè)置引腳復(fù)用器映射:調(diào)用 GPIO_PinAFConfig 函數(shù)。GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_USART1);GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_USART1);// 第三步:GPIO 初始化設(shè)置:要設(shè)置模式為復(fù)用功能。GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9|GPIO_Pin_10;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;GPIO_Init(GPIOA, &GPIO_InitStructure);// 第四步:串口初始化:設(shè)置波特率,字長(zhǎng),奇偶校驗(yàn)等參數(shù)。USART_InitTypeDef   USART_InitStructure;USART_InitStructure.USART_BaudRate = 115200;USART_InitStructure.USART_WordLength = USART_WordLength_8b;USART_InitStructure.USART_StopBits = USART_StopBits_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(USART1, &USART_InitStructure);// 第五步:開(kāi)啟中斷并且初始化 NVIC,使能USART1接收中斷USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);NVIC_InitTypeDef NVIC_InitStructure;NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);// 第六步:使能串口USART_Cmd(USART1, ENABLE);}//發(fā)送一字節(jié)函數(shù)
void USART1_SendByte(uint8_t data)
{USART_SendData(USART1,data);                                   while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);    //等待發(fā)送完畢}// 第七步:編寫中斷處理函數(shù):函數(shù)名格式為 USARTxIRQHandler(x 對(duì)應(yīng)串口號(hào))
void USART1_IRQHandler(void)
{if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET){// 讀取接收到的數(shù)據(jù)uint8_t receivedData = USART_ReceiveData(USART1);// 將接收到的數(shù)據(jù)發(fā)送回電腦USART1_SendByte(receivedData);// 清除中斷標(biāo)志USART_ClearITPendingBit(USART1, USART_IT_RXNE);}
}//對(duì)printf()函數(shù)進(jìn)行重定向
int fputc(int ch, FILE *f)
{USART_SendData(USART1,ch);                                    //通過(guò)串口發(fā)送數(shù)據(jù),每次發(fā)送一個(gè)字符while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);    //等待發(fā)送完畢return ch;
}

main.c

#include "myusart.h"int main(void)
{// 配置USART1USART1_Config();while (1){// 主循環(huán)中無(wú)需處理接收數(shù)據(jù),接收數(shù)據(jù)在中斷中處理}
}

六、向單片機(jī)發(fā)送指令點(diǎn)亮LED

實(shí)現(xiàn)的功能:

? ??STM32F4 通過(guò)串口和上位機(jī)通信,發(fā)送字符串(指令):?open(通過(guò)串口助手),然后單片機(jī)接收,點(diǎn)亮LED燈;

本實(shí)驗(yàn)主要是串口通信的控制功能,演示串口通信可以增強(qiáng)硬件的能力!

my_led..h

#ifndef __MYLED_H
#define __MYLED_Hvoid LED_Init(void);#endif

my_led.c

#include "stm32f4xx.h"                  // Device header
#include "myled.h"/*開(kāi)時(shí)鐘  打開(kāi)外設(shè)對(duì)應(yīng)的時(shí)鐘(查看參考手冊(cè),該外設(shè)掛在哪個(gè)數(shù)據(jù)總線上),對(duì)應(yīng)GPIO在哪條總線開(kāi)哪條GPIOF外設(shè) 掛在AHB1總線上,所以要打開(kāi)AHB1的時(shí)鐘,雙擊函數(shù),右鍵->go to definition*/void LED_Init(void)
{//第一步:使能GPIOF的時(shí)鐘 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);//使能 GPIOF 時(shí)鐘//第二步:GPIOF9,F10 初始化設(shè)置GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;//LED0 和 LED1 對(duì)應(yīng) IO 口GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通輸出模式GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽輸出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHzGPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉GPIO_Init(GPIOF, &GPIO_InitStructure);//初始化 GPIO//第三步:設(shè)置燈的初始狀態(tài)GPIO_SetBits(GPIOF,GPIO_Pin_9 | GPIO_Pin_10);//GPIOF9,F10 設(shè)置高電平,燈滅
}

my_usart.h

#ifndef  __MY_USART1_H__
#define  __MY_USART1_H__
#include <stdint.h>void USART1_Config(void);        //串口配置
void USART1_IRQHandler(void);  
#endif

my_usart.c

#include "stm32f4xx.h"
#include "myusart.h"
#include "myled.h"
#include "string.h"
#include <stdio.h>   /******************************第一步:串口時(shí)鐘使能,GPIO 時(shí)鐘使能。第二步:設(shè)置引腳復(fù)用器映射:調(diào)用 GPIO_PinAFConfig 函數(shù)。第三步:GPIO 初始化設(shè)置:要設(shè)置模式為復(fù)用功能。第四步:串口初始化:設(shè)置波特率,字長(zhǎng),奇偶校驗(yàn)等參數(shù)。第五步:開(kāi)啟中斷并且初始化 NVIC,使能中斷(如果需要開(kāi)啟中斷才需要這個(gè)步驟)。第六步:使能串口。第七步:編寫中斷處理函數(shù):函數(shù)名格式為 USARTxIRQHandler(x 對(duì)應(yīng)串口號(hào))。*********************************/void USART1_Config(void)
{//第一步:串口時(shí)鐘使能,GPIO 時(shí)鐘使能RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);//第二步:設(shè)置引腳復(fù)用器映射:調(diào)用 GPIO_PinAFConfig 函數(shù)。GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_USART1);GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_USART1);// 第三步:GPIO 初始化設(shè)置:要設(shè)置模式為復(fù)用功能。GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9|GPIO_Pin_10;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;GPIO_Init(GPIOA, &GPIO_InitStructure);// 第四步:串口初始化:設(shè)置波特率,字長(zhǎng),奇偶校驗(yàn)等參數(shù)。USART_InitTypeDef   USART_InitStructure;USART_InitStructure.USART_BaudRate = 115200;USART_InitStructure.USART_WordLength = USART_WordLength_8b;USART_InitStructure.USART_StopBits = USART_StopBits_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(USART1, &USART_InitStructure);// 第五步:開(kāi)啟中斷并且初始化 NVIC,使能USART1接收中斷USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);NVIC_InitTypeDef NVIC_InitStructure;NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);// 第六步:使能串口USART_Cmd(USART1, ENABLE);}// 第七步:編寫中斷處理函數(shù):函數(shù)名格式為 USARTxIRQHandler(x 對(duì)應(yīng)串口號(hào))
// USART1中斷服務(wù)程序
void USART1_IRQHandler(void) 
{// 檢查USART1是否接收到數(shù)據(jù)if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) {// 讀取接收到的字符char received_char = USART_ReceiveData(USART1);// 存儲(chǔ)接收到的字符串的緩沖區(qū)static char buffer[10];static uint8_t index = 0;if (received_char != '\n' && received_char != '\r')//接收數(shù)據(jù)的結(jié)束標(biāo)志{// 將字符存儲(chǔ)到緩沖區(qū)buffer[index] = received_char;index++;} else{//將字符串末尾設(shè)置為'\0'buffer[index] = '\0';index = 0;    //置0,為下一次存儲(chǔ)做準(zhǔn)備// 檢查接收到的字符串是否為"open"if (strcmp(buffer, "open") == 0) {// 點(diǎn)亮LED燈GPIO_ResetBits(GPIOF, GPIO_Pin_9| GPIO_Pin_10);    }}}
}//對(duì)printf()函數(shù)進(jìn)行重定向
int fputc(int ch, FILE *f)
{USART_SendData(USART1,ch);                                    //通過(guò)串口發(fā)送數(shù)據(jù),每次發(fā)送一個(gè)字符while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);    //等待發(fā)送完畢return ch;
}

? ? ? 注意:因?yàn)槲覀冊(cè)诔绦蛏厦嬖O(shè)置了必須輸入回車或者換行,串口才認(rèn)可接收到的數(shù)據(jù),所以必須在發(fā)送數(shù)據(jù)后再發(fā)送一個(gè)回車符, 這里 XCOM 提供的發(fā)送方法是通過(guò)勾選發(fā)送新行實(shí)現(xiàn),如圖,只要勾選了這個(gè)選項(xiàng),每次發(fā)送數(shù)據(jù)后,XCOM 都會(huì)自動(dòng)多發(fā)一個(gè)回車(0X0D+0X0A)。設(shè)置好了發(fā)送新行,我們?cè)僭诎l(fā)送區(qū)輸入發(fā)送的命令:open,然后單擊發(fā)送,這樣燈便會(huì)點(diǎn)亮!

?

main.c代碼:?

#include <stdio.h>
#include "myusart.h"
#include "myled.h"int main(void)
{LED_Init();USART1_Config();while (1){// 主循環(huán)中無(wú)需處理接收數(shù)據(jù),接收數(shù)據(jù)在中斷中處理}
}

七、主從機(jī)通信的兩種方式

至此,我們的本次的學(xué)習(xí)就結(jié)束了。通過(guò)以上幾個(gè)實(shí)驗(yàn),相信對(duì)串口通信有了深入的理解,這一節(jié)我們就講解到這里,希望能對(duì)大家的開(kāi)發(fā)有幫助。 如有興趣,感謝點(diǎn)贊、關(guān)注、收藏,若有不正地方,還請(qǐng)各位大佬多多指教!

http://www.risenshineclean.com/news/58984.html

相關(guān)文章:

  • 創(chuàng)新網(wǎng)站建設(shè)工作室營(yíng)銷課程培訓(xùn)哪個(gè)機(jī)構(gòu)好
  • 免費(fèi)一級(jí)a做爰網(wǎng)站河南百度推廣公司
  • 做網(wǎng)站點(diǎn)擊賺取廣告費(fèi)百度關(guān)鍵字排名軟件
  • 提供低價(jià)網(wǎng)站建設(shè)seo5
  • 愛(ài)奇藝做視頻網(wǎng)站的怎么查權(quán)重查詢
  • 網(wǎng)站設(shè)計(jì)維護(hù)員長(zhǎng)沙百度提升排名
  • 個(gè)人網(wǎng)站設(shè)計(jì)實(shí)驗(yàn)原理qq推廣工具
  • vshtml5網(wǎng)站開(kāi)發(fā)提升網(wǎng)站權(quán)重的方法
  • 提供秦皇島網(wǎng)站建設(shè)哪里有國(guó)際軍事新聞最新消息
  • 中山網(wǎng)站建設(shè)前端開(kāi)發(fā)
  • 政府網(wǎng)站建設(shè)的流程因素勞動(dòng)局免費(fèi)培訓(xùn)電工
  • 做網(wǎng)站銷售好做嗎電商推廣聯(lián)盟
  • 網(wǎng)站制作聯(lián)盟廈門百度推廣怎么做
  • 柳市做網(wǎng)站網(wǎng)上賣產(chǎn)品怎么推廣
  • 如何做能切換語(yǔ)言的網(wǎng)站網(wǎng)站建設(shè)公司哪家好?
  • 鄭州做網(wǎng)站價(jià)格微網(wǎng)站建站平臺(tái)
  • 網(wǎng)站結(jié)構(gòu)化數(shù)據(jù)愛(ài)站網(wǎng)關(guān)鍵詞長(zhǎng)尾挖掘
  • 電腦做系統(tǒng)哪個(gè)網(wǎng)站比較好用西安網(wǎng)站外包
  • 有什么網(wǎng)站可以接淘寶設(shè)計(jì)單做淘寶指數(shù)
  • 商城網(wǎng)站制作的教程百度銷售是做什么
  • 免費(fèi)的模板網(wǎng)站廣州網(wǎng)絡(luò)推廣seo
  • 有哪個(gè)網(wǎng)站做正品港貨知乎推廣公司
  • 網(wǎng)站必須做ssl認(rèn)證淘寶店鋪推廣方式有哪些
  • 可做影視網(wǎng)站的服務(wù)器什么文案容易上熱門
  • 深圳龍華網(wǎng)站建設(shè)百度識(shí)圖搜索
  • 中糧我買網(wǎng)是哪個(gè)公司做的網(wǎng)站怎么創(chuàng)建網(wǎng)址
  • 網(wǎng)站服務(wù)器怎么做廣州seo工作
  • 網(wǎng)站底部模板淘寶一個(gè)關(guān)鍵詞要刷多久
  • 做網(wǎng)站用的什么服務(wù)器嗎廣州seo網(wǎng)站優(yōu)化培訓(xùn)
  • 找婚慶公司去什么網(wǎng)站東莞網(wǎng)絡(luò)公司代理