久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 7752|回復: 5
打印 上一主題 下一主題
收起左側

STM32串口通信配置(USART1+USART2+USART3+UART4)

[復制鏈接]
跳轉到指定樓層
樓主
ID:346927 發表于 2019-5-28 10:50 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
一、串口一的配置(初始化+中斷配置+中斷接收函數)
  1.   1 /*===============================================================================
  2.   2 Copyright:
  3.   3 Version:
  4.   4 Author:   
  5.   5 Date: 2017/11/3
  6.   6 Description:
  7.   7     配置獨立看門狗初始化函數,在主函數中運行IWDG_ReloadCounter進行喂狗主函數必須在4s內進行一次喂狗不然系統會復位;
  8.   8     函數功能是將接收固定長度的字符串,并將接收后的字符串通過串口發送出去
  9.   9 revise Description:
  10. 10 ===============================================================================*/
  11. 11 #include "stm32f10x_usart.h"
  12. 12 #include "stm32f10x.h"
  13. 13 #include "stm32f10x_iwdg.h"
  14. 14
  15. 15 u8 USART1_RX_BUF[21];
  16. 16 u8 USART1_RX_CNT=0;
  17. 17
  18. 18 void IWDG_Configuration(void);
  19. 19
  20. 20 void Usart1_Init(u32 bound)
  21. 21 {
  22. 22     //GPIO端口設置
  23. 23     GPIO_InitTypeDef GPIO_InitStructure;
  24. 24     USART_InitTypeDef USART_InitStructure;
  25. 25     NVIC_InitTypeDef NVIC_InitStructure;
  26. 26      
  27. 27     RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOC, ENABLE);//使能USART1,GPIOA,C時鐘
  28. 28      
  29. 29     //USART1_TX   GPIOA.9
  30. 30     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9
  31. 31     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  32. 32     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;    //復用推挽輸出
  33. 33     GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.9
  34. 34
  35. 35     //USART1_RX      GPIOA.10初始化
  36. 36     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10
  37. 37     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空輸入
  38. 38     GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10  
  39. 39
  40. 40     //Usart1 NVIC 配置
  41. 41     NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);    //設置NVIC中斷分組2:2位搶占優先級,2位響應優先級   0-3;
  42. 42     
  43. 43     NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
  44. 44     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//搶占優先級3
  45. 45     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;        //子優先級3
  46. 46     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;            //IRQ通道使能
  47. 47     NVIC_Init(&NVIC_InitStructure);    //根據指定的參數初始化VIC寄存器
  48. 48   
  49. 49    //USART 初始化設置
  50. 50
  51. 51     USART_InitStructure.USART_BaudRate = bound;//串口波特率
  52. 52     USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字長為8位數據格式
  53. 53     USART_InitStructure.USART_StopBits = USART_StopBits_1;//一個停止位
  54. 54     USART_InitStructure.USART_Parity = USART_Parity_No;//無奇偶校驗位
  55. 55     USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//無硬件數據流控制
  56. 56     USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;    //收發模式
  57. 57
  58. 58     USART_Init(USART1, &USART_InitStructure); //初始化串口1
  59. 59     USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//開啟串口接受中斷
  60. 60     USART_Cmd(USART1, ENABLE);                    //使能串口1
  61. 61 }
  62. 62 /**
  63. 63 * USART1發送len個字節.
  64. 64 * buf:發送區首地址
  65. 65 * len:發送的字節數(為了和本代碼的接收匹配,這里建議不要超過64個字節)
  66. 66 **/
  67. 67 void USART1_Send_Data(u8 *buf,u16 len)
  68. 68 {
  69. 69     u16 t;
  70. 70     GPIO_SetBits(GPIOC,GPIO_Pin_9);
  71. 71 //  RS485_TX_EN=1;            //設置為發送模式
  72. 72     for(t=0;t<len;t++)        //循環發送數據
  73. 73     {           
  74. 74         while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET); //循環發送,直到發送完畢   
  75. 75         USART_SendData(USART1,buf[t]);
  76. 76     }     
  77. 77     while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);        
  78. 78     GPIO_ResetBits(GPIOC,GPIO_Pin_9);
  79. 79 //    RS485_TX_EN=0;                //設置為接收模式   
  80. 80 }
  81. 81 void main(void)
  82. 82 {
  83. 83     Usart1_Init(9600);//串口1波特率設置為9600
  84. 84     IWDG_Configuration();
  85. 85     while(1)
  86. 86     {
  87. 87         IWDG_ReloadCounter();//4s內必須喂狗不然復位
  88. 88         if(USART1_RX_CNT==21)//數據接收完成
  89. 89         {
  90. 90             USART1_RX_CNT=0;//指針復位
  91. 91             //將接收到的數據發送出去
  92. 92             USART1_Send_Data(USART1_RX_BUF,21);//通過串口1將接收到的固定長度字符發送出去            
  93. 93         }
  94. 94     }
  95. 95     
  96. 96 }
  97. 97 /**
  98. 98 * 接收指定長度的字符串
  99. 99 * 比如接收固定大小為21個字節的字符串
  100. 100 **/
  101. 101 void USART1_IRQHandler(void)                    //串口1中斷服務程序
  102. 102 {
  103. 103     u8 Res;
  104. 104     if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
  105. 105         {
  106. 106             Res =USART_ReceiveData(USART1);    //讀取接收到的數據     
  107. 107             if(USART1_RX_CNT<21)//對于接收指定長度的字符串
  108. 108             {
  109. 109                 USART1_RX_BUF[USART1_RX_CNT]=Res;        //記錄接收到的值   
  110. 110                 USART1_RX_CNT++;                                        //接收數據增加1
  111. 111             }            
  112. 112      }
  113. 113          //溢出-如果發生溢出需要先讀SR,再讀DR寄存器則可清除不斷入中斷的問題
  114. 114     if(USART_GetFlagStatus(USART1,USART_FLAG_ORE) == SET)
  115. 115     {
  116. 116         USART_ReceiveData(USART1);
  117. 117         USART_ClearFlag(USART1,USART_FLAG_ORE);
  118. 118     }
  119. 119      USART_ClearFlag(UART1,USART_IT_RXNE); //一定要清除接收中斷
  120. 120 }
  121. 121 /*===============================================================================
  122. 122 Copyright:
  123. 123 Version:
  124. 124 Author:   
  125. 125 Date: 2017/11/3
  126. 126 Description:配置獨立看門狗初始化函數,在主函數中運行IWDG_ReloadCounter進行喂狗
  127. 127     主函數必須在4s內進行一次喂狗不然系統會復位
  128. 128 revise Description:
  129. 129 ===============================================================================*/
  130. 130 void IWDG_Configuration(void)
  131. 131 {
  132. 132      /* 寫入0x5555,用于允許狗狗寄存器寫入功能 */
  133. 133     IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);
  134. 134      /* 狗狗時鐘分頻,40K/256=156HZ(6.4ms)*/  
  135. 135     IWDG_SetPrescaler(IWDG_Prescaler_256);    /* 喂狗時間 5s/6.4MS=781 .注意不能大于0xfff*/  
  136. 136     IWDG_SetReload(781);//781(5s時間)
  137. 137     IWDG_SetReload(3125);//781(20s時間)
  138. 138     IWDG_Enable();//啟用定時器
  139. 139     IWDG_ReloadCounter();
  140. 140 }
復制代碼

二、串口二的配置(初始化+中斷配置+中斷接收函數)
  1. 1 /*===============================================================================
  2.   2 Copyright:
  3.   3 Version:
  4.   4 Author:   
  5.   5 Date: 2017/11/3
  6.   6 Description:
  7.   7     函數功能是將接收固定長度的字符串,并將接收后的字符串通過串口發送出去
  8.   8 revise Description:
  9.   9 ===============================================================================*/
  10. 10 #include "stm32f10x_usart.h"
  11. 11 #include "stm32f10x.h"
  12. 12 #include "stm32f10x_iwdg.h"
  13. 13
  14. 14
  15. 15 u8 USART2_RX_BUF[250];
  16. 16 u8 USART2_RX_CNT=0;
  17. 17 u16 USART2_RX_STA=0;       //接收狀態標記   
  18. 18
  19. 19 void Usart2_Init(u32 bound)
  20. 20 {  
  21. 21     GPIO_InitTypeDef GPIO_InitStructure;
  22. 22     USART_InitTypeDef USART_InitStructure;
  23. 23     NVIC_InitTypeDef NVIC_InitStructure;
  24. 24     //|RCC_APB2Periph_AFIO
  25. 25     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//使能GPIOA時鐘
  26. 26     RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);//使能USART2時鐘
  27. 27
  28. 28     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;    //PA2
  29. 29     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;    //復用推挽
  30. 30     GPIO_Init(GPIOA, &GPIO_InitStructure);
  31. 31
  32. 32     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;//PA3
  33. 33     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空輸入
  34. 34     GPIO_Init(GPIOA, &GPIO_InitStructure);  
  35. 35
  36. 36     RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART2,ENABLE);//復位串口2
  37. 37     RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART2,DISABLE);//停止復位
  38. 38
  39. 39     NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);    //設置NVIC中斷分組2:2位搶占優先級,2位響應優先級   0-3;
  40. 40     NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn; //使能串口2中斷
  41. 41     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3; //先占優先級2級
  42. 42     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //從優先級2級
  43. 43     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中斷通道
  44. 44     NVIC_Init(&NVIC_InitStructure); //根據NVIC_InitStruct中指定的參數初始化外設NVIC寄存器
  45. 45
  46. 46     USART_InitStructure.USART_BaudRate = bound;//波特率設置
  47. 47     USART_InitStructure.USART_WordLength = USART_WordLength_8b;//8位數據長度
  48. 48     USART_InitStructure.USART_StopBits = USART_StopBits_1;//一個停止位
  49. 49     USART_InitStructure.USART_Parity = USART_Parity_No;///奇偶校驗位
  50. 50     USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//無硬件數據流控制
  51. 51     USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;//收發模式
  52. 52
  53. 53     USART_Init(USART2, &USART_InitStructure); ; //初始化串口
  54. 54     USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);//開啟中斷
  55. 55     USART_Cmd(USART2, ENABLE);                    //使能串口
  56. 56
  57. 57 }
  58. 58 /**
  59. 59 * USART2發送len個字節.
  60. 60 * buf:發送區首地址
  61. 61 * len:發送的字節數(為了和本代碼的接收匹配,這里建議不要超過64個字節)
  62. 62 **/
  63. 63 void USART2_Send_Data(u8 *buf,u16 len)
  64. 64 {
  65. 65     u16 t;
  66. 66       for(t=0;t<len;t++)        //循環發送數據
  67. 67     {           
  68. 68         while(USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET);      
  69. 69         USART_SendData(USART2,buf[t]);
  70. 70     }     
  71. 71     while(USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET);         
  72. 72 }
  73. 73 /**
  74. 74 * 這也是一個接收函數,可以用,也可以用下面main函數的方法調用
  75. 75 * USART2查詢接收到的數據
  76. 76 * buf:接收緩存首地址
  77. 77 * len:讀到的數據長度
  78. 78 **/
  79. 79 void USART2_Receive_Data(u8 *buf)
  80. 80 {
  81. 81     u8 rxlen=USART2_RX_CNT;
  82. 82     u8 i=0;
  83. 83     delay_ms(10);        //等待10ms,連續超過10ms沒有接收到一個數據,則認為接收結束
  84. 84     while(rxlen!=USART2_RX_CNT)
  85. 85     {
  86. 86         rxlen=USART2_RX_CNT;
  87. 87         delay_ms(10);
  88. 88     }
  89. 89         for(i=0;i<(USART2_RX_CNT);i++)
  90. 90         {
  91. 91             buf[i] = USART2_RX_BUF[i];   
  92. 92             USART2_RX_BUF[i] = 0;
  93. 93         }        
  94. 94         USART2_RX_CNT=0;        //清零
  95. 95     
  96. 96 }
  97. 97
  98. 98 void main(void)
  99. 99 {
  100. 100     Usart2_Init(9600);//串口1波特率設置為9600
  101. 101     while(1)
  102. 102     {
  103. 103         if(USART2_RX_STA)//數據接收完成
  104. 104         {
  105. 105             USART2_RX_STA=0;            
  106. 106             //將接收到的數據發送出去
  107. 107             USART2_Send_Data(USART2_RX_BUF,USART2_RX_CNT);//通過串口1將接收到的固定長度字符發送出去   
  108. 108             USART2_RX_CNT=0;//指針復位
  109. 109         }
  110. 110     }   
  111. 111 }
  112. 112
  113. 113
  114. 114 void USART2_IRQHandler(void)
  115. 115 {
  116. 116     u8 res;        
  117. 117      if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) //接收到數據
  118. 118     {         
  119. 119         res =USART_ReceiveData(USART2);     //讀取接收到的數據        
  120. 120         if(USART2_RX_STA==0)
  121. 121         {
  122. 122             USART2_RX_BUF[USART2_RX_CNT] = res;        //記錄接收到的值   
  123. 123             //當數據結尾收到0xA0和0xA1代表數據接收完成,是一串完整的數據
  124. 124             if(USART2_RX_BUF[USART2_RX_CNT-1]==0xA0&&USART2_RX_BUF[USART2_RX_CNT]==0xA1)
  125. 125                 USART2_RX_STA=1;//表示接收數據結束
  126. 126             USART2_RX_CNT++;                        //接收數據增加1
  127. 127         }
  128. 128         }
  129. 129     }  
  130. 130     //溢出-如果發生溢出需要先讀SR,再讀DR寄存器則可清除不斷入中斷的問題
  131. 131     if(USART_GetFlagStatus(USART2,USART_FLAG_ORE) == SET)
  132. 132     {
  133. 133         USART_ReceiveData(USART2);
  134. 134         USART_ClearFlag(USART2,USART_FLAG_ORE);
  135. 135     }
  136. 136      USART_ClearFlag(UART2,USART_IT_RXNE); //一定要清除接收中斷   
  137. 137 }
復制代碼


三、串口三的配置(初始化+中斷配置+中斷接收函數)
  1.   1 /*===============================================================================
  2.   2 Copyright:
  3.   3 Version:
  4.   4 Author:   
  5.   5 Date: 2017/11/3
  6.   6 Description:
  7.   7     函數功能是將接收固定長度的字符串,并將接收后的字符串通過串口發送出去
  8.   8     通過滴答定時器方式獲取數據
  9.   9 revise Description:
  10. 10 ===============================================================================*/
  11. 11 #include "stm32f10x_usart.h"
  12. 12 #include "stm32f10x.h"
  13. 13
  14. 14 #define USART3_TIMEOUT_Setting 800  //(ms)
  15. 15
  16. 16 u8 USART3_RX_BUF[250];
  17. 17 u16 USART3_RX_CNT=0;
  18. 18 u16 USART3_RX_TIMEOUT=0;       //接收狀態標記   
  19. 19
  20. 20 void Timer1CountInitial(void);
  21. 21
  22. 22 void USART3_Init(u32 baud)   
  23. 23 {  
  24. 24     USART_InitTypeDef USART_InitStructure;  
  25. 25     NVIC_InitTypeDef NVIC_InitStructure;   
  26. 26     GPIO_InitTypeDef GPIO_InitStructure;    //聲明一個結構體變量,用來初始化GPIO  
  27. 27     //使能串口的RCC時鐘  
  28. 28     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB , ENABLE); //使能UART3所在GPIOB的時鐘  
  29. 29     RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);  
  30. 30
  31. 31     //串口使用的GPIO口配置  
  32. 32     // Configure USART3 Rx (PB.11) as input floating   
  33. 33     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;  
  34. 34     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;  
  35. 35     GPIO_Init(GPIOB, &GPIO_InitStructure);  
  36. 36
  37. 37     // Configure USART3 Tx (PB.10) as alternate function push-pull  
  38. 38     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;  
  39. 39     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  
  40. 40     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  
  41. 41     GPIO_Init(GPIOB, &GPIO_InitStructure);  
  42. 42
  43. 43     //配置串口  
  44. 44     USART_InitStructure.USART_BaudRate = baud;  
  45. 45     USART_InitStructure.USART_WordLength = USART_WordLength_8b;  
  46. 46     USART_InitStructure.USART_StopBits = USART_StopBits_1;  
  47. 47     USART_InitStructure.USART_Parity = USART_Parity_No;  
  48. 48     USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;  
  49. 49     USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;  
  50. 50
  51. 51
  52. 52     // Configure USART3   
  53. 53     USART_Init(USART3, &USART_InitStructure);//配置串口3
  54. 54     // Enable USART3 Receive interrupts 使能串口接收中斷  
  55. 55     USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);  
  56. 56     // Enable the USART3   
  57. 57     USART_Cmd(USART3, ENABLE);//使能串口3  
  58. 58
  59. 59     //串口中斷配置  
  60. 60     //Configure the NVIC Preemption Priority Bits     
  61. 61     NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);  
  62. 62
  63. 63     // Enable the USART3 Interrupt   
  64. 64     NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;   
  65. 65     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//搶占優先級3
  66. 66     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;        //子優先級3
  67. 67     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;  
  68. 68     NVIC_Init(&NVIC_InitStructure);      
  69. 69      
  70. 70 }
  71. 71
  72. 72 void USART3_Sned_Char(u8 temp)        
  73. 73 {  
  74. 74     USART_SendData(USART3,(u8)temp);      
  75. 75     while(USART_GetFlagStatus(USART3,USART_FLAG_TXE)==RESET);  
  76. 76      
  77. 77 }
  78. 78
  79. 79 void USART3_Sned_Char_Buff(u8 buf[],u32 len)  
  80. 80 {  
  81. 81     u32 i;  
  82. 82     for(i=0;i<len;i++)  
  83. 83     USART3_Sned_Char(buf[i]);  
  84. 84           
  85. 85 }
  86. 86
  87. 87 void main(void)
  88. 88 {
  89. 89     Timer1CountInitial();
  90. 90     Usart3_Init(9600);//串口1波特率設置為9600
  91. 91     while(1)
  92. 92     {
  93. 93         if(USART3_RX_TIMEOUT==USART3_TIMEOUT_Setting)
  94. 94         {            
  95. 95             USART3_RX_TIMEOUT=0;
  96. 96             USART3_Sned_Char_Buff(USART3_RX_BUF,USART3_RX_CNT);//將接收到的數據發送出去
  97. 97             USART3_RX_CNT=0;
  98. 98         }
  99. 99         
  100. 100     }   
  101. 101 }
  102. 102 void USART3_IRQHandler(void)                    //串口3中斷服務程序
  103. 103 {
  104. 104     u8 Res;
  105. 105     if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET)  
  106. 106     {   
  107. 107         USART3_RX_TIMEOUT=0;
  108. 108         USART3_RX_BUF[USART3_RX_CNT++] = USART_ReceiveData(USART3);    //讀取接收到的數據        
  109. 109     }
  110. 110     //溢出-如果發生溢出需要先讀SR,再讀DR寄存器則可清除不斷入中斷的問題
  111. 111     if(USART_GetFlagStatus(USART3,USART_FLAG_ORE) == SET)
  112. 112     {
  113. 113         USART_ReceiveData(USART3);
  114. 114         USART_ClearFlag(USART3,USART_FLAG_ORE);
  115. 115     }
  116. 116     USART_ClearITPendingBit(USART3, USART_IT_RXNE);
  117. 117
  118. 118 }
  119. 119
  120. 120 //放到主函數的初始化中初始化
  121. 121 void Timer1CountInitial(void)
  122. 122 {
  123. 123     //定時=36000/72000x2=0.001s=1ms;
  124. 124         TIM_TimeBaseInitTypeDef    TIM_TimeBaseStructure;
  125. 125         ///////////////////////////////////////////////////////////////
  126. 126         RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
  127. 127         
  128. 128         TIM_TimeBaseStructure.TIM_Period = 100-1;//自動重裝值(此時改為10ms)
  129. 129         TIM_TimeBaseStructure.TIM_Prescaler = 7200-1;//時鐘預分頻
  130. 130         TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//向上計數
  131. 131         TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;        //時鐘分頻1
  132. 132         TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;            
  133. 133         TIM_TimeBaseInit(TIM1,&TIM_TimeBaseStructure);
  134. 134         
  135. 135         TIM_ClearFlag(TIM1,TIM_FLAG_Update);
  136. 136         TIM_ITConfig(TIM1,TIM_IT_Update,ENABLE);  
  137. 137         TIM_Cmd(TIM1, ENABLE);
  138. 138 }
  139. 139 void TIM1_UP_IRQHandler(void)
  140. 140 {        
  141. 141     //TIM_TimeBaseStructure.TIM_Period = 100-1;//自動重裝值(此時改為10ms)
  142. 142     if (TIM_GetITStatus(TIM1, TIM_IT_Update) != RESET)
  143. 143     {  
  144. 144         if(USART3_RX_TIMEOUT<USART3_TIMEOUT_Setting)
  145. 145                 USART3_RX_TIMEOUT++;        
  146. 146     }
  147. 147     TIM_ClearITPendingBit(TIM1,TIM_IT_Update);
  148. 148 }
復制代碼

四、串口四的配置(初始化+中斷配置+中斷接收函數)

注意串口四的中斷優先級沒有貼出來,和前面的三個一樣的配置,為了不占用過多的篇幅就不貼中斷優先級配置了
  1.   1 /*===============================================================================
  2.   2 Copyright:
  3.   3 Version:
  4.   4 Author:   
  5.   5 Date: 2017/11/3
  6.   6 Description:
  7.   7     函數功能是將接收固定長度的字符串,并將接收后的字符串通過串口發送出去
  8.   8     通過滴答定時器方式獲取數據
  9.   9 revise Description:
  10. 10 ===============================================================================*/
  11. 11 #include "stm32f10x_usart.h"
  12. 12 #include "stm32f10x.h"
  13. 13
  14. 14 #define USART4_TIMEOUT_Setting 800  //(ms)
  15. 15
  16. 16 u8 USART4_RX_BUF[250];
  17. 17 u16 USART4_RX_CNT=0;
  18. 18 u16 USART2_RX_STA=0;       //接收狀態標記
  19. 19
  20. 20 void Systick_delay_init(u8 SYSCLK);
  21. 21 u8 virtual_delay(u32 num,u8 unit);
  22. 22
  23. 23 //通用異步收發器UART4
  24. 24 void UART4_Init(u32 bound)
  25. 25 {
  26. 26     USART_InitTypeDef USART_InitStructure;
  27. 27     GPIO_InitTypeDef GPIO_InitStructure;
  28. 28
  29. 29     //used for USART3 full remap
  30. 30     //GPIO_PinRemapConfig(GPIO_FullRemap_USART3, ENABLE);
  31. 31     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO, ENABLE);
  32. 32     RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART4, ENABLE);//for UART4
  33. 33
  34. 34     //Configure RS485_TX_EN PIN
  35. 35     GPIO_InitStructure.GPIO_Pin = RS485_TX_EN_PIN;                 //PC9端口配置
  36. 36     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;          //推挽輸出
  37. 37     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  38. 38     GPIO_Init(RS485_TX_EN_PORT, &GPIO_InitStructure);
  39. 39
  40. 40     RS485_TX_EN=0;            //設置485默認為接收模式
  41. 41
  42. 42     /* Configure USART Tx as alternate function push-pull */
  43. 43     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
  44. 44     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  45. 45     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  46. 46     GPIO_Init(GPIOC, &GPIO_InitStructure);
  47. 47
  48. 48     /* Configure USART Rx as input floating */
  49. 49     GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_11;
  50. 50     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  51. 51     GPIO_Init(GPIOC, &GPIO_InitStructure);
  52. 52
  53. 53
  54. 54     USART_InitStructure.USART_BaudRate = bound;
  55. 55     USART_InitStructure.USART_WordLength = USART_WordLength_8b;
  56. 56     USART_InitStructure.USART_StopBits = USART_StopBits_1;
  57. 57     USART_InitStructure.USART_Parity = USART_Parity_No ;
  58. 58     USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
  59. 59     USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
  60. 60
  61. 61     USART_Init(UART4, &USART_InitStructure);
  62. 62     //USART_Init(USART3, &USART_InitStructure);
  63. 63     /* Enable the USART */
  64. 64     USART_Cmd(UART4, ENABLE);
  65. 65     USART_ITConfig(UART4, USART_IT_RXNE, ENABLE);//開啟串口接受中斷
  66. 66     USART_ClearFlag(UART4,USART_FLAG_TC);   
  67. 67 }
  68. 68 //USART1查詢接收到的數據
  69. 69 //buf:接收緩存首地址
  70. 70 //len:讀到的數據長度
  71. 71 void UART4_Receive_Data(u8 *buf)
  72. 72 {
  73. 73     u8 rxlen=21;
  74. 74     u8 i=0;
  75. 75     delay_ms(10);        //等待10ms,連續超過10ms沒有接收到一個數據,則認為接收結束
  76. 76     
  77. 77     RS485_RX_FLAG = 0;
  78. 78     if((UART4_RX_BUF[0]==0x01)&&(UART4_RX_BUF[1]==0x03))
  79. 79     {
  80. 80         for(i=0;i<rxlen;i++)
  81. 81         {
  82. 82             buf[i]=UART4_RX_BUF[i];   
  83. 83             UART4_RX_BUF[i] = 0;
  84. 84         }   
  85. 85         RS485_RX_FLAG = 1;
  86. 86     }
  87. 87         UART4_RX_CNT=0;        //清零
  88. 88 }
  89. 89
  90. 90
  91. 91 //USART1發送len個字節.
  92. 92 //buf:發送區首地址
  93. 93 //len:發送的字節數(為了和本代碼的接收匹配,這里建議不要超過64個字節)
  94. 94 void UART4_Send_Data(u8 *buf,u16 len)
  95. 95 {
  96. 96     u16 t;
  97. 97     RS485_TX_EN=1;            //設置為發送模式
  98. 98     for(t=0;t<len;t++)        //循環發送數據
  99. 99     {           
  100. 100         while(USART_GetFlagStatus(UART4,USART_FLAG_TC)==RESET); //循環發送,直到發送完畢   
  101. 101         USART_SendData(UART4,buf[t]);
  102. 102     }     
  103. 103     while(USART_GetFlagStatus(UART4, USART_FLAG_TC) == RESET);        
  104. 104     RS485_TX_EN=0;                //設置為接收模式   
  105. 105 }
  106. 106
  107. 107 void main(void)
  108. 108 {
  109. 109     Systick_delay_init(72);
  110. 110     Usart4_Init(9600);//串口1波特率設置為9600
  111. 111     while(1)
  112. 112     {
  113. 113         if(USART2_RX_STA)
  114. 114         {
  115. 115             if(virtual_delay(USART4_TIMEOUT_Setting,MS))//超過800ms空閑則可以讀取數據
  116. 116             {
  117. 117                 UART4_Send_Data(UART4_RX_BUF,UART4_RX_CNT);
  118. 118                 USART2_RX_STA=0;
  119. 119                 UART4_RX_CNT=0;               
  120. 120             }
  121. 121            
  122. 122         }
  123. 123         
  124. 124     }   
  125. 125 }
  126. 126 void UART4_IRQHandler(void)                    //UART4 Receive Interrupt
  127. 127 {
  128. 128     u8 Res;
  129. 129     
  130. 130     if(USART_GetITStatus(UART4, USART_IT_RXNE) != RESET)  //接收中斷(接收到的數據必須是0x0d 0x0a結尾)
  131. 131     {   
  132. 132         Res =USART_ReceiveData(UART4);//(USART1->DR);    //讀取接收到的數據   
  133. 133         UART4_RX_BUF[UART4_RX_CNT&0XFF]=Res;        //回傳的數據存入數組,0X3F限制為64個數值
  134. 134             UART4_RX_CNT++;
  135. 135         USART2_RX_STA=1;   
  136. 136     }
  137. 137     
  138. 138     if( USART_GetITStatus(UART4, USART_IT_TC) == SET )
  139. 139     {
  140. 140         USART_ClearFlag(UART4, USART_FLAG_TC);
  141. 141     }   
  142. 142     //溢出-如果發生溢出需要先讀SR,再讀DR寄存器則可清除不斷入中斷的問題
  143. 143     if(USART_GetFlagStatus(UART4,USART_FLAG_ORE) == SET)
  144. 144     {
  145. 145         USART_ReceiveData(UART4);
  146. 146         USART_ClearFlag(UART4,USART_FLAG_ORE);
  147. 147     }
  148. 148 //    USART_ITConfig(UART4, USART_IT_RXNE, DISABLE);//臨時關閉接收中斷
  149. 149     USART_ClearFlag(UART4,USART_IT_RXNE); //一定要清除接收中斷
  150. 150     
  151. 151 }
  152. 152
  153. 153 //初始化延遲函數
  154. 154 //SYSTICK的時鐘固定為HCLK時鐘的1/8
  155. 155 //SYSCLK:系統時鐘
  156. 156 void Systick_delay_init(u8 SYSCLK)
  157. 157 {
  158. 158     SysTick->CTRL&=0xfffffffb;//bit2清空,選擇外部時鐘  HCLK/8
  159. 159 //    SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);    //選擇外部時鐘  HCLK/8
  160. 160     fac_us=SYSCLK/8;            
  161. 161     fac_ms=(u16)fac_us*1000;
  162. 162 }
  163. 163 /*===============================================================================
  164. 164 Author:peter pan
  165. 165 Date:
  166. 166 Description: 查詢式分時或叫做輪詢式(近似延時)。本函數是用于執行高效率場合的查詢延時,但是一個for or while 循環中只能用一次。
  167. 167 revise Description:  
  168. 168 @ num :    //分時查詢的周期計數值   
  169. 169 @ unit :    //分時查詢的周期單位
  170. 170     @@ParaValue :
  171. 171         MS    //周期單位為MS毫秒級
  172. 172         US    //周期單位為US微秒級
  173. 173 @ virtual_delay_status :    //靜態變量
  174. 174     @@ParaValue :
  175. 175         SET    //SYSTICK正在占用中,請勿用
  176. 176         RESET  //SYSTICK空閑,可以使用
  177. 177 @ReValue :
  178. 178     with zero mean Time non-arrive ,one representative Time arrived ,you can do task;
  179. 179 ##example             if(virtual_delay(1000,MS)) LedFlash();    //1000ms LED閃爍一下
  180. 180 ===============================================================================*/
  181. 181 u8 virtual_delay(u32 num,u8 unit)
  182. 182 {
  183. 183     u32 temp;           
  184. 184     if(virtual_delay_status==RESET)    //  SYSTICK空閑,可以使用
  185. 185       {
  186. 186           if(unit==MS)
  187. 187           {
  188. 188                 SysTick->LOAD=(u32)num*Delay_SYSCLK*125;//時間加載(SysTick->LOAD為24bit)
  189. 189                 SysTick->VAL =0x00;           //清空計數器
  190. 190                 SysTick->CTRL=0x01 ;          //開始倒數  
  191. 191           }else if(unit==US)
  192. 192           {
  193. 193                 SysTick->LOAD=num*Delay_SYSCLK/8; //時間加載               
  194. 194                 SysTick->VAL=0x00;        //清空計數器
  195. 195                 SysTick->CTRL=0x01 ;      //開始倒數     
  196. 196           }
  197. 197           virtual_delay_status=SET;
  198. 198           return 0;
  199. 199         }
  200. 200     else
  201. 201         {        //virtual_delay_status==SET SYSTICK被占用
  202. 202         
  203. 203             temp=SysTick->CTRL;
  204. 204             if(!(temp&0x01&&!(temp&(1<<16))))//等待時間到達   
  205. 205             {
  206. 206                 SysTick->CTRL=0x00;       //關閉計數器
  207. 207                 SysTick->VAL =0X00;       //清空計數器   
  208. 208                 virtual_delay_status=RESET;   
  209. 209                 return 1;
  210. 210             }else return 0;
  211. 211         }
  212. 212 }
復制代碼





STM32串口通信配置.pdf

253.31 KB, 下載次數: 80, 下載積分: 黑幣 -5

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏5 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:142699 發表于 2019-11-4 19:42 | 只看該作者
樓主測試過程序么,串口三能發送不能接收數據
回復

使用道具 舉報

板凳
ID:795735 發表于 2020-7-2 15:20 | 只看該作者
串口4不行啊,RS485_TX_EN沒有定義
回復

使用道具 舉報

地板
ID:795735 發表于 2020-7-2 15:21 | 只看該作者
jianfeii 發表于 2019-11-4 19:42
樓主測試過程序么,串口三能發送不能接收數據

串口3我配置通了,
回復

使用道具 舉報

5#
ID:797825 發表于 2020-7-5 15:57 | 只看該作者
這個串口能否加MODUBUS協議
回復

使用道具 舉報

6#
ID:570410 發表于 2020-9-20 23:51 | 只看該作者

這幾個串口能否加MODUBUS協議,做主站或從站?
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 北条麻妃一区二区三区在线观看 | 99久久99| 日韩精品在线一区 | 日韩一级二级片 | 精品亚洲一区二区 | 免费视频一区二区 | 97精品超碰一区二区三区 | 日韩精品视频在线观看一区二区三区 | 国产精品a久久久久 | 欧美激情视频一区二区三区免费 | 久一精品 | 夜夜爽99久久国产综合精品女不卡 | 在线日韩不卡 | 日韩字幕| 久久久性色精品国产免费观看 | 中文字幕亚洲欧美日韩在线不卡 | 日日艹夜夜艹 | 国产精品久久久久久久久久久免费看 | 一级片av | 欧美精品网站 | 成年人黄色小视频 | 日韩欧美字幕 | 亚洲国产精品人人爽夜夜爽 | 91亚洲国产成人久久精品网站 | www.亚洲国产精品 | 色播久久久 | 亚洲激情网站 | 9191在线播放 | 爱爱视频网| 九九99久久 | 一区二区三区视频在线 | 日韩免费视频一区二区 | 亚洲毛片在线观看 | 精品欧美一区二区精品久久久 | 亚洲午夜精品久久久久久app | 欧美不卡在线 | 免费成人av | 久久精品免费 | 日韩中文字幕在线免费 | 国产精品高潮呻吟久久 | 日韩中文字幕在线 |