一、串口一的配置(初始化+中断配置+中断接收函数)

  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 }

本文地址:https://www.cnblogs.com/pertor/p/9488446.html

STM32串口通信配置(USART1+USART2+USART3+UART4)的更多相关文章

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

    一.串口一的配置(初始化+中断配置+中断接收函数) 1 /*====================================================================== ...

  2. Stm32串口通信(USART)

    Stm32串口通信(UART) 串口通信的分类 串口通信三种传递方式 串口通信的通信方式 串行通信的方式: 异步通信:它用一个起始位表示字符的开始,用停止位表示字符的结束.其每帧的格式如下: 在一帧格 ...

  3. STM32 串口通信使用奇偶校验

    STM32串口通信如果使用奇偶校验,需要设置数据位长度为9bit USART_InitStructure.USART_BaudRate = 9600; USART_InitStructure.USAR ...

  4. STM32串口通信UART使用

    STM32串口通信UART使用 uart使用的过程为: 1. 使能GPIO口和UART对应的总线时钟 2. 配置GPIO口的输出模式 3. 配置uart口相关的基本信息 4. 使能uart口的相关的中 ...

  5. STM32串口通信USART1转USART2问题解决

    使用的是STM32f103ZET6. 1.把文件main.c和usart.c中的所有usart1换成usart2 2.查看手册得知USART2的引脚是Tx->PA2,Rx->PA3,改变u ...

  6. stm32串口的配置方案

    最近老板要我去做控制方面的内容,所以买了一块正点原子的开发板,现在是研究了一下usart.c,函数的代码如下: void USART1_IRQHandler(void) { u8 Res; #ifde ...

  7. stm32串口通信实验,一点笔记

    第一次深入学习stm32,花了好长时间才看懂代码(主要是C语言学习不够深入),又花了段时间自己敲了一遍,然后比对教程,了解了利用中断来串口通信的设置方法. 板子是探索版f407,本实验工程把正点原子库 ...

  8. STM32 串口通信

    1. 中断说明 TXE(Tansmit Data Register empty interrupt) - 发送数据寄存器空,产生中断.当使能TXE后,只要Tx DR空了,就会产生中断.---写寄存器D ...

  9. STM32串口寄存器操作(转)

    源:STM32串口寄存器操作 //USART.C /************************************************************************** ...

随机推荐

  1. CodeForces - 557D Vitaly and Cycle(二分图)

    Vitaly and Cycle time limit per test 1 second memory limit per test 256 megabytes input standard inp ...

  2. Input 内提示填写内容

    输入框内提示默认内容,用户的点击后提示内容消失,如果填写内容为空,失去焦点后自动显示提示内容 <input type="text" value="搜索" ...

  3. Vue使用html2canvas将页面转化为图片

    需求是微信端将页面截屏之后保存到本地,使用了html2canvas插件 先引入插件 npm install --save html2canvas 之后在你所需要使用的页面引入 import html2 ...

  4. SpringBoot2.0整合SpringSecurity实现自定义表单登录

    我们知道企业级权限框架一般有Shiro,Shiro虽然强大,但是却不属于Spring成员之一,接下来我们说说SpringSecurity这款强大的安全框架.费话不多说,直接上干货. pom文件引入以下 ...

  5. vue打包问题:Tip: built files are meant to be served over an HTTP server.

    npm run build之后,出现提示:Tip: built files are meant to be served over an HTTP server. Opening index.html ...

  6. 不定长数组 Vector的 应用

    #include<cstdio> #include<vector> using namespace std; vector<int>a; int main() { ...

  7. Android Unable to add window -- token android.os.BinderProxy@3a067204 is not valid错误分析记录

    打开APP时,出现闪退的情况,查看android studio报错信息,主要为: Unable to add window -- token android.os.BinderProxy@3a0672 ...

  8. android学习之路资料集合

    版权声明:本文为 stormzhang 原创文章,可以随意转载,但必须在明确位置注明出处!!! 这篇博客背后的故事 一路走来很不容易,刚好知乎上被人邀请回答如何自学android编程, 就借这个机会在 ...

  9. JS高级——Object.prototype成员

    基本概念 成员 描述 Object.prototype.__proto__ 指向当对象被实例化的时候,用作原型的对象. Object.prototype.hasOwnProperty() 返回一个布尔 ...

  10. SQL基本操作——事务

    事务是并发和恢复控制的基本单元. 事务四个属性:原子性.一致性.隔离性.持久性. 原子性:一个事务是一个不可分割的单位,事务中包括的诸多操作要么成功要么都失败. 一致性:事务必须使数据库从一个一致性状 ...