功能:PC端發(fā)送一個特定的字符:0x0d0x0a,單片機則返回一句話,如圖:
>_
1、復用功能I/O和調(diào)試配置(AFIO)
為了優(yōu)化外設數(shù)目,可以把一些復用功能重新映射到其他引腳上。設置復用重映射和調(diào)試I/O配置寄存器(AFIO_MAPR)(參見0節(jié))實現(xiàn)引腳的重新映射。這時,復用功能不再映射到它們的原始分配上。
2、嵌套向量中斷控制器(NVIC)
l43個可屏蔽中斷通道(不包含16個Cortex-M3的中斷線);
l16個可編程的優(yōu)先等級;
l低延遲的異常和中斷處理;
l電源管理控制;
l系統(tǒng)控制寄存器的實現(xiàn);
l嵌套向量中斷控制器(NVIC)和處理器核的接口緊密相連,可以實現(xiàn)低延遲的中斷處理和有效處理地處理晚到的中斷。
PS:
a、SysTick:系統(tǒng)嘀嗒校準值固定到9000,當系統(tǒng)嘀嗒時鐘設定為9兆赫,產(chǎn)生1ms時基。
b、中斷和異常向量:【中斷向量表】
3、USART通用同步異步收發(fā)器(USART)
它支持同步單向通信和半雙工單線通信
任何USART雙向通信至少需要兩個腳:接收數(shù)據(jù)輸入(RX)和發(fā)送數(shù)據(jù)輸出(TX)。
a、RX:接收數(shù)據(jù)串行輸。通過過采樣技術來區(qū)別數(shù)據(jù)和噪音,從而恢復數(shù)據(jù)。
b、TX:發(fā)送數(shù)據(jù)輸出。當發(fā)送器被禁止時,輸出引腳恢復到它的I/O端口配置。當發(fā)送器被激活,并且沒東西發(fā)送時,TX引腳處于高電平。
>_
a、USART設置,這個要看固件庫!首先用結構體把參數(shù)配置好,然后調(diào)用初始化函數(shù);接著使能接收中斷和發(fā)送緩沖中斷;最后使能USART1。
1 void USART_Config(USART_TypeDef* USARTx){
2 USART_InitStructure.USART_BaudRate = 19200; //速率19200bps
3 USART_InitStructure.USART_WordLength = USART_WordLength_8b; //數(shù)據(jù)位8位
4 USART_InitStructure.USART_StopBits = USART_StopBits_1; //停止位1位
5 USART_InitStructure.USART_Parity = USART_Parity_No; //無校驗位
6 USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //無硬件流控
7 USART_InitStructure.USART_Mode = USART_Mode_Rx " USART_Mode_Tx; //收發(fā)模式
8 /* Configure USART1 */
9 USART_Init(USARTx, &USART_InitStructure); //配置串口參數(shù)函數(shù)
10 /* Enable USART1 Receive and Transmit interrupts */
11 USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); //使能接收中斷
12 USART_ITConfig(USART1, USART_IT_TXE, ENABLE); //使能發(fā)送緩沖空中斷
13 /* Enable the USART1 */
14 USART_Cmd(USART1, ENABLE);
15 }
b、配置系統(tǒng)時鐘72MHz+外設時鐘使能。注意這里有復用,所以要使能復用時鐘。
1 void RCC_Configuration(void){
2 SystemInit();
3 RCC_APB2PeriphClockCmd( RCC_APB2Periph_USART1 |RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB |RCC_APB2Periph_AFIO , ENABLE);
4 }
c、 LED的GPIO口配置和復用的A9,A10用于數(shù)據(jù)收發(fā)
1 void GPIO_Configuration(void){
2 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //LED1控制--PB5
3 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽輸出
4 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
5 GPIO_Init(GPIOB, &GPIO_InitStructure);
6
7 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //USART1 TX
8 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //復用推挽輸出
9 GPIO_Init(GPIOA, &GPIO_InitStructure); //A端口
10
11 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //USART1 RX
12 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //復用開漏輸入
13 GPIO_Init(GPIOA, &GPIO_InitStructure); //A端口
14 }
d、中斷向量初始化,看固件庫!
1 void NVIC_Configuration(void){
2 /* 結構聲明*/
3 NVIC_InitTypeDef NVIC_InitStructure;
4
5 /* Configure the NVIC Preemption Priority Bits */
6 /* Configure one bit for preemption priority */
7 /* 優(yōu)先級組 說明了搶占優(yōu)先級所用的位數(shù),和子優(yōu)先級所用的位數(shù) 在這里是1, 7 */
8 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
9 NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; //設置串口1中斷
10 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //搶占優(yōu)先級 0
11 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //子優(yōu)先級為0
12 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能
13 NVIC_Init(&NVIC_InitStructure);
14 }
e、Main函數(shù):rec_f為有效幀標志位
1 int main(void){
2 uint8_t a=0;//LED高低電壓控制
3 RCC_Configuration(); //系統(tǒng)時鐘設置
4 NVIC_Configuration(); //中斷源配置
5 GPIO_Configuration(); //端口初始化
6 USART_Config(USART1); //串口1初始化
7
8 while (1){
9 if(rec_f==1){ //判斷是否收到一幀有效數(shù)據(jù)
10 rec_f=0;
11 for(i=0;i 12 { 13 USART_SendChar(USART1,TxBuffer1[i]); 14 Delay(0x0000ff00); 15 } 16 if(a==0){GPIO_SetBits(GPIOB, GPIO_Pin_5);a=1;} //LED1 明暗閃爍 17 else{GPIO_ResetBits(GPIOB, GPIO_Pin_5);a=0;} 18 } 19 } 20 } 這里發(fā)送函數(shù)封裝為: 1 void USART_SendChar(USART_TypeDef* USARTx,uint8_t data){ 2 USART_SendData(USARTx,data); 3 while(USART_GetFlagStatus(USARTx,USART_FLAG_TC)==RESET); 4 } 接收函數(shù)在中斷函數(shù)中,當上位機發(fā)送數(shù)據(jù)給單片機時,單片機將進入該中斷服務程序,進行數(shù)據(jù)接收,這里上位機發(fā)送的數(shù)據(jù)必須以0x0d和0x0a結尾,如果不是以這兩個結尾說明不是有效幀,則不處理: 1 void USART1_IRQHandler(void) //串口1 中斷服務程序 2 { 3 unsigned int i; 4 if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //判斷讀寄存器是否非空 5 { 6 RxBuffer1[RxCounter1++] = USART_ReceiveData(USART1); //將讀寄存器的數(shù)據(jù)緩存到接收緩沖區(qū)里 7 if(RxBuffer1[RxCounter1-2]==0x0d&&RxBuffer1[RxCounter1-1]==0x0a)//判斷結束標志是否是0x0d 0x0a 8 { 9 for(i=0; i< RxCounter1; i++) TxBuffer1[i] = RxBuffer1[i]; //將接收緩沖器的數(shù)據(jù)轉(zhuǎn)到發(fā)送緩沖區(qū),準備轉(zhuǎn)發(fā) 10 rec_f=1; //接收成功標志 11 TxBuffer1[RxCounter1]=0; //發(fā)送緩沖區(qū)結束符 12 TxCounter1=RxCounter1; 13 RxCounter1=0; 14 } 15 } 16 if(USART_GetITStatus(USART1, USART_IT_TXE) != RESET) //這段是為了避免STM32 USART 第一個字節(jié)發(fā)不出去的BUG 17 { 18 USART_ITConfig(USART1, USART_IT_TXE, DISABLE); //禁止發(fā)緩沖器空中斷, 19 } 20 }