99久久全国免费观看_国产一区二区三区四区五区VM_久久www人成免费看片中文_国产高清在线a视频大全_深夜福利www_日韩一级成人av

  • 回復(fù)
  • 收藏
  • 點贊
  • 分享
  • 發(fā)新帖

STM32串口USART1的使用方法和程序

通用同步異步收發(fā)器(USART)提供了一種靈活的方法來與使用工業(yè)標準NR 異步串行數(shù)據(jù)格式的外部設(shè)備之間進行全雙工數(shù)據(jù)交換。 USART利用分數(shù)波特率發(fā)生器提供寬范圍的波特率選擇,支持同步單向通信和半雙工單線通信。

1、STM32固件庫使用外圍設(shè)備的主要思路

在STM32中,外圍設(shè)備的配置思路比較固定。首先是使能相關(guān)的時鐘,一方面是設(shè)備本身的時鐘,另一方面如果設(shè)備通過IO口輸出還需要使能IO口的時鐘;最后如果對應(yīng)的IO口是復(fù)用功能的IO口,則還必須使能AFIO的時鐘。

其次是配置GPIO,GPIO的各種屬性由硬件手冊的AFIO一章詳細規(guī)定,較為簡單。

接著相關(guān)設(shè)備需要如果需要使用中斷功能,必須先配置中斷優(yōu)先級,后文詳述。

然后是配置外圍設(shè)備的相關(guān)屬性,視具體設(shè)備而定,如果設(shè)備需要使用中斷方式,必須使能相應(yīng)設(shè)備的中斷,之后需要使能相關(guān)設(shè)備。

最后如果設(shè)備使用了中斷功能,則還需要填寫相應(yīng)的中斷服務(wù)程序,在服務(wù)程序中進行相應(yīng)操作。

2、UART的配置步驟(查詢方式)

2.1、打開時鐘

由于UART的TX和RX和AFIO都掛在APB2橋上,因此采用固件庫函數(shù)RCC_APB2PeriphClockCmd()進行初始化。UARTx需要分情況討論,如果是UART1,則掛在APB2橋上,因此采用RCC_APB2PeriphClockCmd()進行初始化,其余的UART2~5均掛在APB1上。

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1, ENABLE);

2.2、GPIO初始化

GPIO的屬性包含在結(jié)構(gòu)體GPIO_InitTypeDef,其中對于TX引腳,GPIO_Mode字段設(shè)置為GPIO_Mode_AF_PP(復(fù)用推挽輸出),GPIO_Speed切換速率設(shè)置為GPIO_Speed_50MHz;對于RX引腳,GPIO_Mode字段設(shè)置為GPIO_Mode_IN_FLOATING(浮空輸入),不需要設(shè)置切換速率。最后通過GPIO_Init()使能IO口。

以下是GPIO設(shè)置的實例代碼:

復(fù)制代碼
 GPIO_InitTypeDef GPIO_InitStructure; //USART1 Tx(PA.09)  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; 
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; 
    GPIO_Init(GPIOA, &GPIO_InitStructure); //USART1 Rx(PA.10)  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; 
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; 
    GPIO_Init(GPIOA, &GPIO_InitStructure);
復(fù)制代碼

2.3、配置UART相關(guān)屬性

通過結(jié)構(gòu)體USART_InitTypeDef來確定。UART模式下的字段如下

USART_BaudRate:波特率,視具體設(shè)備而定

USART_WordLength:字長

USART_StopBits:停止位

USART_Parity:校驗方式

USART_HardwareFlowControl:硬件流控制

USART_Mode:單/雙工

最后設(shè)置。實例代碼為:

復(fù)制代碼
   //USART1配置
  USART_InitTypeDef USART_InitStructure;

   USART_InitStructure.USART_BaudRate = 9600; 
    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);
    USART_Cmd(USART1, ENABLE); 
復(fù)制代碼

別忘了最后要使用USART_Cmd()來啟動設(shè)備UART1。

2.4、重定向print()函數(shù)。

復(fù)制代碼
int fputc(int ch,FILE *f)
{
    USART1->SR; //USART_GetFlagStatus(USART1, USART_FLAG_TC) 解決第一個字符發(fā)送失敗的問題 //一個一個發(fā)送字符 USART_SendData(USART1, (unsigned char) ch); //等待發(fā)送完成 while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET); return(ch);
}
復(fù)制代碼

最后通過主函數(shù)直接輸出即可。

復(fù)制代碼
int main(void)
{ // USART1 config 9600 8-N-1   USART1_Config();
    
    printf("hello world!");
}
復(fù)制代碼

全部回復(fù)(3)
正序查看
倒序查看
2019-03-04 10:08
學(xué)習(xí)
0
回復(fù)
2019-03-04 21:42
@虎虎虎123
學(xué)習(xí)

3、UART的配置步驟(中斷方式)

打開時鐘、GPIO初始化、配置UART相關(guān)屬性、重定向print()函數(shù) 與上面的相同。

3.1、中斷優(yōu)先級的配置

這是STM32比較奇怪的地方,在只有一個中斷的情況下,仍然需要配置優(yōu)先級,其作用是使能某條中斷的觸發(fā)通道。STM32的中斷有至多兩個層次,分別是先占優(yōu)先級和從優(yōu)先級,而整個優(yōu)先級設(shè)置參數(shù)的長度為4位,因此需要首先劃分先占優(yōu)先級位數(shù)和從優(yōu)先級位數(shù),通過NVIC_PriorityGroupConfig()實現(xiàn);

特定設(shè)備的中斷優(yōu)先級NVIC的屬性包含在結(jié)構(gòu)體NVIC_InitTypeDef中,其中字段NVIC_IRQChannel包含了設(shè)備的中斷向量,保存在啟動代碼中;字段NVIC_IRQChannelPreemptionPriority為主優(yōu)先級,NVIC_IRQChannelSubPriority為從優(yōu)先級,取值的范圍應(yīng)根據(jù)位數(shù)劃分的情況而定;最后NVIC_IRQChannelCmd字段是是否使能,一般定位ENABLE。最后通過NVIC_Init()來使能這一中斷向量。實例代碼如下:

//配置UART1接收中斷 void NVIC_Configuration(void)
{
    NVIC_InitTypeDef NVIC_InitStructure; /* Configure the NVIC Preemption Priority Bits */ NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); /* Enable the USARTy Interrupt */ NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;     
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
}

 

3.2、中斷的服務(wù)程序的設(shè)計

目前使用了UART的兩個中斷USART_IT_RXNE(接收緩存補空中斷)和USART_IT_TXE(發(fā)送緩存空中斷),前一個中斷保證了一旦有數(shù)據(jù)接收到就進入中斷以接收特定長度的數(shù)據(jù),后一個中斷表示一旦發(fā)完一個數(shù)據(jù)就進入中斷函數(shù),保證連續(xù)發(fā)送一段數(shù)據(jù)。一個設(shè)備的所有中斷都包含在一個中斷服務(wù)程序中,因此必須首先分清楚這次響應(yīng)的是哪一個中斷,使用USART_GetITStatus()函數(shù)確定;采用USART_ReceiveData()函數(shù)接收一個字節(jié)數(shù)據(jù),采用USART_SendData()函數(shù)發(fā)送一個字節(jié)數(shù)據(jù),當關(guān)閉中斷時采用USART_ITConfig()失能響應(yīng)的中斷。實例程序:

void USART1_IRQHandler(void)
{
    uint8_t ch; if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
    { //ch = USART1->DR; ch = USART_ReceiveData(USART1); //接受數(shù)據(jù) printf( "%c", ch ); //返回打印  } 
     
}

 

3.3、接收數(shù)據(jù)函數(shù):

//重定向scanf函數(shù)到USART1 int fgetc(FILE *f)
{ /*等待串口1輸入數(shù)據(jù)*/ while (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET); return (int)USART_ReceiveData(USART1);
}
0
回復(fù)
2019-03-04 21:43
@lihui710884923
3、UART的配置步驟(中斷方式)打開時鐘、GPIO初始化、配置UART相關(guān)屬性、重定向print()函數(shù)與上面的相同。3.1、中斷優(yōu)先級的配置這是STM32比較奇怪的地方,在只有一個中斷的情況下,仍然需要配置優(yōu)先級,其作用是使能某條中斷的觸發(fā)通道。STM32的中斷有至多兩個層次,分別是先占優(yōu)先級和從優(yōu)先級,而整個優(yōu)先級設(shè)置參數(shù)的長度為4位,因此需要首先劃分先占優(yōu)先級位數(shù)和從優(yōu)先級位數(shù),通過NVIC_PriorityGroupConfig()實現(xiàn);特定設(shè)備的中斷優(yōu)先級NVIC的屬性包含在結(jié)構(gòu)體NVIC_InitTypeDef中,其中字段NVIC_IRQChannel包含了設(shè)備的中斷向量,保存在啟動代碼中;字段NVIC_IRQChannelPreemptionPriority為主優(yōu)先級,NVIC_IRQChannelSubPriority為從優(yōu)先級,取值的范圍應(yīng)根據(jù)位數(shù)劃分的情況而定;最后NVIC_IRQChannelCmd字段是是否使能,一般定位ENABLE。最后通過NVIC_Init()來使能這一中斷向量。實例代碼如下:[圖片]voidUSART1_IRQHandler(void){uint8_tch;if(USART_GetITStatus(USART1,USART_IT_RXNE)!=RESET){//ch=USART1->DR;ch=USART_ReceiveData(USART1);//接受數(shù)據(jù)printf("%c",ch);//返回打印}}[圖片] 3.3、接收數(shù)據(jù)函數(shù):

4、 STM32串口在首次發(fā)送字符的時候,首字符丟失解決辦法

網(wǎng)上關(guān)于發(fā)送字符的代碼大多如下:

USART_SendData(USART1, (uint8_t)ch);
while( USART_GetFlagStatus(USART1, USART_FLAG_TC) != SET);

其實咋一看是說的通的,但是在仔細看手冊的時候發(fā)現(xiàn) TC 和 TXE 標志位在復(fù)位的時候被置1 ,這樣第一次while循環(huán)就是沒有用的。這樣導(dǎo)致了首次第一個字符還沒有被輸出,就被后面的字符覆蓋掉,造成實際看到的丟失現(xiàn)象。解決辦法就很簡單:在前面加上一句 USART1->SR;

具體代碼如下:

USART1->SR;
USART_SendData(USART1, (uint8_t)ch);
while( USART_GetFlagStatus(USART1, USART_FLAG_TC) != SET);

下面我來說說原因: 第一句讀取SR寄存器,第二句寫DR寄存器 剛好清除了TC標志位 。第一次while循環(huán)就起作用了。

也可將USART1->SR;替換為USART_GetFlagStatus(USART1, USART_FLAG_TC)

0
回復(fù)
發(fā)
主站蜘蛛池模板: 91琪琪 | 中文字幕日韩高清2024 | 中国精品视频久久久久久 | 九九九九网站 | 欧美xxxxxx片免费播放软件 | 欧美bbw极品另类 | 精品精品国产高清a毛片 | 国产精品久久久久久久久久了 | gogogo高清在线观看中文 | 国产一区二区免费在线观看 | 我要看免费的黄色片 | 草莓福利社区在线 | 免费黄色成年网站 | www私房写真在线观看 | 国产欧美日韩在线观看一区二区 | 精品麻豆一卡2卡三卡4卡乱码 | 亚洲www| 中国性感美女一级黄色影片 | 密桃av| 97视频久久| 高清无码免费视频专区 | 尤物国精品午夜福利视频 | 任我爽橹在线视频精品583 | 波多野结衣先锋在线 | 日韩国产一区二区三区 | 国产精品免费一区二区三区观看 | 国产精品日韩AV在线播放 | 欧美受xxxx黑人xyx爽 | 熟妇人妻无乱码中文字幕真矢织江 | 狠狠躁日日躁狂躁夜夜躁 | 蜜臀色欲AV无码国产精品 | 欧美精品videofree | 国产成人综合激情视频在线观看 | 少妇丰满大乳被男人揉捏视频 | 国产传媒第一页 | 亚洲高清免费观看在线视频 | 91视频专区 | jjzzjjzz亚洲 | 无码人妻丰满熟妇区毛片 | 日韩免费在线 | 日韩一区二区三区四区区区 |