您好,欢迎来到小侦探旅游网。
搜索
您的当前位置:首页STM32串口通信配置(USART1+USART2+USART3+UART4)

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

来源:小侦探旅游网
STM32串⼝通信配置(USART1+USART2+USART3+UART4)

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

1 /*=============================================================================== 2 Copyright: 3 Version: 4 Author:

5 Date: 2017/11/3 6 Description:

7 配置独⽴看门狗初始化函数,在主函数中运⾏IWDG_ReloadCounter进⾏喂狗主函数必须在4s内进⾏⼀次喂狗不然系统会复位; 8 函数功能是将接收固定长度的字符串,并将接收后的字符串通过串⼝发送出去 9 revise Description:

10 ===============================================================================*/ 11 #include \"stm32f10x_usart.h\" 12 #include \"stm32f10x.h\"

13 #include \"stm32f10x_iwdg.h\" 14

15 u8 USART1_RX_BUF[21]; 16 u8 USART1_RX_CNT=0; 17

18 void IWDG_Configuration(void); 19

20 void Usart1_Init(u32 bound) 21 {

22 //GPIO端⼝设置

23 GPIO_InitTypeDef GPIO_InitStructure; 24 USART_InitTypeDef USART_InitStructure; 25 NVIC_InitTypeDef NVIC_InitStructure; 26

27 RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOC, ENABLE);//使能USART1,GPIOA,C时钟 28

29 //USART1_TX GPIOA.9

30 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9

31 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

32 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复⽤推挽输出 33 GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.9 34

35 //USART1_RX GPIOA.10初始化

36 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10

37 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输⼊ 38 GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10 39

40 //Usart1 NVIC 配置

41 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级 0-3; 42

43 NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;

44 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3 45 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //⼦优先级3

46 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能 47 NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器 48

49 //USART 初始化设置 50

51 USART_InitStructure.USART_BaudRate = bound;//串⼝波特率

52 USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式 53 USART_InitStructure.USART_StopBits = USART_StopBits_1;//⼀个停⽌位 54 USART_InitStructure.USART_Parity = USART_Parity_No;//⽆奇偶校验位

55 USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//⽆硬件数据流控制 56 USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式 57

58 USART_Init(USART1, &USART_InitStructure); //初始化串⼝1

59 USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启串⼝接受中断 60 USART_Cmd(USART1, ENABLE); //使能串⼝1 61 } 62 /**

63 * USART1发送len个字节. 64 * buf:发送区⾸地址

65 * len:发送的字节数(为了和本代码的接收匹配,这⾥建议不要超过64个字节) 66 **/

67 void USART1_Send_Data(u8 *buf,u16 len) 68 {

69 u16 t;

70 GPIO_SetBits(GPIOC,GPIO_Pin_9);

71 // RS485_TX_EN=1; //设置为发送模式 72 for(t=0;t74 while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET); //循环发送,直到发送完毕 75 USART_SendData(USART1,buf[t]);

76 }

77 while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET); 78 GPIO_ResetBits(GPIOC,GPIO_Pin_9);

79 // RS485_TX_EN=0; //设置为接收模式 80 }

81 void main(void) 82 {

83 Usart1_Init(9600);//串⼝1波特率设置为9600 84 IWDG_Configuration(); 85 while(1) 86 {

87 IWDG_ReloadCounter();//4s内必须喂狗不然复位 88 if(USART1_RX_CNT==21)//数据接收完成 89 {

90 USART1_RX_CNT=0;//指针复位 91 //将接收到的数据发送出去

92 USART1_Send_Data(USART1_RX_BUF,21);//通过串⼝1将接收到的固定长度字符发送出去 93 } 94 } 95 96 } 97 /**

98 * 接收指定长度的字符串

99 * ⽐如接收固定⼤⼩为21个字节的字符串100 **/

101 void USART1_IRQHandler(void) //串⼝1中断服务程序102 {

103 u8 Res;

104 if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) 105 {

106 Res =USART_ReceiveData(USART1); //读取接收到的数据 107 if(USART1_RX_CNT<21)//对于接收指定长度的字符串108 {

109 USART1_RX_BUF[USART1_RX_CNT]=Res; //记录接收到的值 110 USART1_RX_CNT++; //接收数据增加1 111 } 112 }

113 //溢出-如果发⽣溢出需要先读SR,再读DR寄存器则可清除不断⼊中断的问题114 if(USART_GetFlagStatus(USART1,USART_FLAG_ORE) == SET)115 {

116 USART_ReceiveData(USART1);

117 USART_ClearFlag(USART1,USART_FLAG_ORE);118 }

119 USART_ClearFlag(UART1,USART_IT_RXNE); //⼀定要清除接收中断120 }

121 /*===============================================================================122 Copyright:123 Version:124 Author:

125 Date: 2017/11/3

126 Description:配置独⽴看门狗初始化函数,在主函数中运⾏IWDG_ReloadCounter进⾏喂狗127 主函数必须在4s内进⾏⼀次喂狗不然系统会复位128 revise Description:

129 ===============================================================================*/130 void IWDG_Configuration(void) 131 {

132 /* 写⼊0x5555,⽤于允许狗狗寄存器写⼊功能 */

133 IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable); 134 /* 狗狗时钟分频,40K/256=156HZ(6.4ms)*/

135 IWDG_SetPrescaler(IWDG_Prescaler_256); /* 喂狗时间 5s/6.4MS=781 .注意不能⼤于0xfff*/ 136 IWDG_SetReload(781);//781(5s时间)137 IWDG_SetReload(3125);//781(20s时间)138 IWDG_Enable();//启⽤定时器139 IWDG_ReloadCounter();140 }

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

1 /*=============================================================================== 2 Copyright: 3 Version: 4 Author:

5 Date: 2017/11/3 6 Description:

7 函数功能是将接收固定长度的字符串,并将接收后的字符串通过串⼝发送出去 8 revise Description:

9 ===============================================================================*/ 10 #include \"stm32f10x_usart.h\" 11 #include \"stm32f10x.h\"

12 #include \"stm32f10x_iwdg.h\" 13

14

15 u8 USART2_RX_BUF[250]; 16 u8 USART2_RX_CNT=0;

17 u16 USART2_RX_STA=0; //接收状态标记 18

19 void Usart2_Init(u32 bound) 20 {

21 GPIO_InitTypeDef GPIO_InitStructure; 22 USART_InitTypeDef USART_InitStructure; 23 NVIC_InitTypeDef NVIC_InitStructure; 24 //|RCC_APB2Periph_AFIO

25 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//使能GPIOA时钟 26 RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);//使能USART2时钟 27

28 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //PA2

29 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复⽤推挽 30 GPIO_Init(GPIOA, &GPIO_InitStructure); 31

32 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;//PA3

33 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输⼊ 34 GPIO_Init(GPIOA, &GPIO_InitStructure); 35

36 RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART2,ENABLE);//复位串⼝2 37 RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART2,DISABLE);//停⽌复位 38

39 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级 0-3; 40 NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn; //使能串⼝2中断

41 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3; //先占优先级2级 42 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //从优先级2级

43 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道

44 NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器 45

46 USART_InitStructure.USART_BaudRate = bound;//波特率设置

47 USART_InitStructure.USART_WordLength = USART_WordLength_8b;//8位数据长度 48 USART_InitStructure.USART_StopBits = USART_StopBits_1;//⼀个停⽌位 49 USART_InitStructure.USART_Parity = USART_Parity_No;///奇偶校验位

50 USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//⽆硬件数据流控制 51 USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;//收发模式 52

53 USART_Init(USART2, &USART_InitStructure); ; //初始化串⼝

54 USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);//开启中断 55 USART_Cmd(USART2, ENABLE); //使能串⼝ 56 57 } 58 /**

59 * USART2发送len个字节. 60 * buf:发送区⾸地址

61 * len:发送的字节数(为了和本代码的接收匹配,这⾥建议不要超过64个字节) 62 **/

63 void USART2_Send_Data(u8 *buf,u16 len) 64 {

65 u16 t;

66 for(t=0;t68 while(USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET); 69 USART_SendData(USART2,buf[t]); 70 }

71 while(USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET); 72 } 73 /**

74 * 这也是⼀个接收函数,可以⽤,也可以⽤下⾯main函数的⽅法调⽤ 75 * USART2查询接收到的数据 76 * buf:接收缓存⾸地址 77 * len:读到的数据长度 78 **/

79 void USART2_Receive_Data(u8 *buf) 80 {

81 u8 rxlen=USART2_RX_CNT; 82 u8 i=0;

83 delay_ms(10); //等待10ms,连续超过10ms没有接收到⼀个数据,则认为接收结束 84 while(rxlen!=USART2_RX_CNT) 85 {

86 rxlen=USART2_RX_CNT; 87 delay_ms(10); 88 }

89 for(i=0;i<(USART2_RX_CNT);i++) 90 {

91 buf[i] = USART2_RX_BUF[i]; 92 USART2_RX_BUF[i] = 0; 93 }

94 USART2_RX_CNT=0; //清零 95 96 } 97

98 void main(void) 99 {

100 Usart2_Init(9600);//串⼝1波特率设置为9600101 while(1)102 {

103 if(USART2_RX_STA)//数据接收完成104 {

105 USART2_RX_STA=0; 106 //将接收到的数据发送出去

107 USART2_Send_Data(USART2_RX_BUF,USART2_RX_CNT);//通过串⼝1将接收到的固定长度字符发送出去 108 USART2_RX_CNT=0;//指针复位109 }110 } 111 }112 113

114 void USART2_IRQHandler(void)115 {

116 u8 res;

117 if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) //接收到数据118 {

119 res =USART_ReceiveData(USART2); //读取接收到的数据 120 if(USART2_RX_STA==0)121 {

122 USART2_RX_BUF[USART2_RX_CNT] = res; //记录接收到的值 123 //当数据结尾收到0xA0和0xA1代表数据接收完成,是⼀串完整的数据

124 if(USART2_RX_BUF[USART2_RX_CNT-1]==0xA0&&USART2_RX_BUF[USART2_RX_CNT]==0xA1)125 USART2_RX_STA=1;//表⽰接收数据结束

126 USART2_RX_CNT++; //接收数据增加1 127 }128 } 129 }

130 //溢出-如果发⽣溢出需要先读SR,再读DR寄存器则可清除不断⼊中断的问题131 if(USART_GetFlagStatus(USART2,USART_FLAG_ORE) == SET)132 {

133 USART_ReceiveData(USART2);

134 USART_ClearFlag(USART2,USART_FLAG_ORE);135 }

136 USART_ClearFlag(UART2,USART_IT_RXNE); //⼀定要清除接收中断 137 }

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

1 /*=============================================================================== 2 Copyright: 3 Version: 4 Author:

5 Date: 2017/11/3 6 Description:

7 函数功能是将接收固定长度的字符串,并将接收后的字符串通过串⼝发送出去 8 通过滴答定时器⽅式获取数据 9 revise Description:

10 ===============================================================================*/ 11 #include \"stm32f10x_usart.h\" 12 #include \"stm32f10x.h\" 13

14 #define USART3_TIMEOUT_Setting 800 //(ms) 15

16 u8 USART3_RX_BUF[250]; 17 u16 USART3_RX_CNT=0;

18 u16 USART3_RX_TIMEOUT=0; //接收状态标记 19

20 void Timer1CountInitial(void); 21

22 void USART3_Init(u32 baud) 23 {

24 USART_InitTypeDef USART_InitStructure; 25 NVIC_InitTypeDef NVIC_InitStructure;

26 GPIO_InitTypeDef GPIO_InitStructure; //声明⼀个结构体变量,⽤来初始化GPIO 27 //使能串⼝的RCC时钟

28 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB , ENABLE); //使能UART3所在GPIOB的时钟 29 RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE); 30

31 //串⼝使⽤的GPIO⼝配置

32 // Configure USART3 Rx (PB.11) as input floating 33 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;

34 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; 35 GPIO_Init(GPIOB, &GPIO_InitStructure); 36

37 // Configure USART3 Tx (PB.10) as alternate function push-pull 38 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;

39 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 40 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; 41 GPIO_Init(GPIOB, &GPIO_InitStructure); 42

43 //配置串⼝

44 USART_InitStructure.USART_BaudRate = baud;

45 USART_InitStructure.USART_WordLength = USART_WordLength_8b; 46 USART_InitStructure.USART_StopBits = USART_StopBits_1; 47 USART_InitStructure.USART_Parity = USART_Parity_No;

48 USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; 49 USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; 50 51

52 // Configure USART3

53 USART_Init(USART3, &USART_InitStructure);//配置串⼝3 54 // Enable USART3 Receive interrupts 使能串⼝接收中断 55 USART_ITConfig(USART3, USART_IT_RXNE, ENABLE); 56 // Enable the USART3

57 USART_Cmd(USART3, ENABLE);//使能串⼝3 58

59 //串⼝中断配置

60 //Configure the NVIC Preemption Priority Bits 61 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); 62

63 // Enable the USART3 Interrupt

64 NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;

65 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3 66 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; //⼦优先级3 67 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 68 NVIC_Init(&NVIC_InitStructure); 69 70 } 71

72 void USART3_Sned_Char(u8 temp) 73 {

74 USART_SendData(USART3,(u8)temp);

75 while(USART_GetFlagStatus(USART3,USART_FLAG_TXE)==RESET); 76 77 } 78

79 void USART3_Sned_Char_Buff(u8 buf[],u32 len) 80 {

81 u32 i;

82 for(i=0;i83 USART3_Sned_Char(buf[i]); 84 85 } 86

87 void main(void) 88 {

89 Timer1CountInitial();

90 Usart3_Init(9600);//串⼝1波特率设置为9600 91 while(1) 92 {

93 if(USART3_RX_TIMEOUT==USART3_TIMEOUT_Setting) 94 {

95 USART3_RX_TIMEOUT=0;

96 USART3_Sned_Char_Buff(USART3_RX_BUF,USART3_RX_CNT);//将接收到的数据发送出去 97 USART3_RX_CNT=0; 98 } 99 100 } 101 }

102 void USART3_IRQHandler(void) //串⼝3中断服务程序103 {

104 u8 Res;

105 if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET) 106 {

107 USART3_RX_TIMEOUT=0;

108 USART3_RX_BUF[USART3_RX_CNT++] = USART_ReceiveData(USART3); //读取接收到的数据 109 }

110 //溢出-如果发⽣溢出需要先读SR,再读DR寄存器则可清除不断⼊中断的问题111 if(USART_GetFlagStatus(USART3,USART_FLAG_ORE) == SET)112 {

113 USART_ReceiveData(USART3);

114 USART_ClearFlag(USART3,USART_FLAG_ORE);115 }

116 USART_ClearITPendingBit(USART3, USART_IT_RXNE);117 118 }119

120 //放到主函数的初始化中初始化

121 void Timer1CountInitial(void)122 {

123 //定时=36000/72000x2=0.001s=1ms;

124 TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;125 ///////////////////////////////////////////////////////////////

126 RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);127

128 TIM_TimeBaseStructure.TIM_Period = 100-1;//⾃动重装值(此时改为10ms)129 TIM_TimeBaseStructure.TIM_Prescaler = 7200-1;//时钟预分频

130 TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//向上计数131 TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //时钟分频1132 TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; 133 TIM_TimeBaseInit(TIM1,&TIM_TimeBaseStructure);134

135 TIM_ClearFlag(TIM1,TIM_FLAG_Update);

136 TIM_ITConfig(TIM1,TIM_IT_Update,ENABLE); 137 TIM_Cmd(TIM1, ENABLE);138 }

139 void TIM1_UP_IRQHandler(void)140 {

141 //TIM_TimeBaseStructure.TIM_Period = 100-1;//⾃动重装值(此时改为10ms)142 if (TIM_GetITStatus(TIM1, TIM_IT_Update) != RESET)143 {

144 if(USART3_RX_TIMEOUT147 TIM_ClearITPendingBit(TIM1,TIM_IT_Update);148 }

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

注意串⼝四的中断优先级没有贴出来,和前⾯的三个⼀样的配置,为了不占⽤过多的篇幅就不贴中断优先级配置了

1 /*=============================================================================== 2 Copyright: 3 Version: 4 Author:

5 Date: 2017/11/3 6 Description:

7 函数功能是将接收固定长度的字符串,并将接收后的字符串通过串⼝发送出去 8 通过滴答定时器⽅式获取数据 9 revise Description:

10 ===============================================================================*/ 11 #include \"stm32f10x_usart.h\" 12 #include \"stm32f10x.h\" 13

14 #define USART4_TIMEOUT_Setting 800 //(ms) 15

16 u8 USART4_RX_BUF[250]; 17 u16 USART4_RX_CNT=0;

18 u16 USART2_RX_STA=0; //接收状态标记 19

20 void Systick_delay_init(u8 SYSCLK); 21 u8 virtual_delay(u32 num,u8 unit); 22

23 //通⽤异步收发器UART4 24 void UART4_Init(u32 bound) 25 {

26 USART_InitTypeDef USART_InitStructure; 27 GPIO_InitTypeDef GPIO_InitStructure; 28

29 //used for USART3 full remap

30 //GPIO_PinRemapConfig(GPIO_FullRemap_USART3, ENABLE);

31 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO, ENABLE); 32 RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART4, ENABLE);//for UART4 33

34 //Configure RS485_TX_EN PIN

35 GPIO_InitStructure.GPIO_Pin = RS485_TX_EN_PIN; //PC9端⼝配置 36 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出 37 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 38 GPIO_Init(RS485_TX_EN_PORT, &GPIO_InitStructure); 39

40 RS485_TX_EN=0; //设置485默认为接收模式 41

42 /* Configure USART Tx as alternate function push-pull */ 43 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;

44 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 45 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; 46 GPIO_Init(GPIOC, &GPIO_InitStructure); 47

48 /* Configure USART Rx as input floating */

49 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;

50 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; 51 GPIO_Init(GPIOC, &GPIO_InitStructure); 52 53

54 USART_InitStructure.USART_BaudRate = bound;

55 USART_InitStructure.USART_WordLength = USART_WordLength_8b; 56 USART_InitStructure.USART_StopBits = USART_StopBits_1; 57 USART_InitStructure.USART_Parity = USART_Parity_No ;

58 USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; 59 USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; 60

61 USART_Init(UART4, &USART_InitStructure); 62 //USART_Init(USART3, &USART_InitStructure); 63 /* Enable the USART */

64 USART_Cmd(UART4, ENABLE);

65 USART_ITConfig(UART4, USART_IT_RXNE, ENABLE);//开启串⼝接受中断 66 USART_ClearFlag(UART4,USART_FLAG_TC); 67 }

68 //USART1查询接收到的数据 69 //buf:接收缓存⾸地址 70 //len:读到的数据长度

71 void UART4_Receive_Data(u8 *buf) 72 {

73 u8 rxlen=21; 74 u8 i=0;

75 delay_ms(10); //等待10ms,连续超过10ms没有接收到⼀个数据,则认为接收结束 76

77 RS485_RX_FLAG = 0;

78 if((UART4_RX_BUF[0]==0x01)&&(UART4_RX_BUF[1]==0x03)) 79 {

80 for(i=0;i82 buf[i]=UART4_RX_BUF[i]; 83 UART4_RX_BUF[i] = 0; 84 }

85 RS485_RX_FLAG = 1; 86 }

87 UART4_RX_CNT=0; //清零 88 } 89 90

91 //USART1发送len个字节. 92 //buf:发送区⾸地址

93 //len:发送的字节数(为了和本代码的接收匹配,这⾥建议不要超过64个字节) 94 void UART4_Send_Data(u8 *buf,u16 len) 95 {

96 u16 t;

97 RS485_TX_EN=1; //设置为发送模式 98 for(t=0;t100 while(USART_GetFlagStatus(UART4,USART_FLAG_TC)==RESET); //循环发送,直到发送完毕 101 USART_SendData(UART4,buf[t]); 102 }

103 while(USART_GetFlagStatus(UART4, USART_FLAG_TC) == RESET); 104 RS485_TX_EN=0; //设置为接收模式 105 }106

107 void main(void)108 {

109 Systick_delay_init(72);

110 Usart4_Init(9600);//串⼝1波特率设置为9600111 while(1)112 {

113 if(USART2_RX_STA)114 {

115 if(virtual_delay(USART4_TIMEOUT_Setting,MS))//超过800ms空闲则可以读取数据116 {

117 UART4_Send_Data(UART4_RX_BUF,UART4_RX_CNT);118 USART2_RX_STA=0;

119 UART4_RX_CNT=0; 120 }121 122 }123 124 } 125 }

126 void UART4_IRQHandler(void) //UART4 Receive Interrupt 127 {

128 u8 Res;129

130 if(USART_GetITStatus(UART4, USART_IT_RXNE) != RESET) //接收中断(接收到的数据必须是0x0d 0x0a结尾)131 {

132 Res =USART_ReceiveData(UART4);//(USART1->DR); //读取接收到的数据

133 UART4_RX_BUF[UART4_RX_CNT&0XFF]=Res; //回传的数据存⼊数组,0X3F限制为64个数值134 UART4_RX_CNT++;135 USART2_RX_STA=1; 136 }137

138 if( USART_GetITStatus(UART4, USART_IT_TC) == SET )139 {

140 USART_ClearFlag(UART4, USART_FLAG_TC);141 }

142 //溢出-如果发⽣溢出需要先读SR,再读DR寄存器则可清除不断⼊中断的问题143 if(USART_GetFlagStatus(UART4,USART_FLAG_ORE) == SET)144 {

145 USART_ReceiveData(UART4);

146 USART_ClearFlag(UART4,USART_FLAG_ORE);147 }

148 // USART_ITConfig(UART4, USART_IT_RXNE, DISABLE);//临时关闭接收中断149 USART_ClearFlag(UART4,USART_IT_RXNE); //⼀定要清除接收中断150 151 } 152

153 //初始化延迟函数

154 //SYSTICK的时钟固定为HCLK时钟的1/8155 //SYSCLK:系统时钟

156 void Systick_delay_init(u8 SYSCLK)157 {

158 SysTick->CTRL&=0xfffffffb;//bit2清空,选择外部时钟 HCLK/8

159 // SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); //选择外部时钟 HCLK/8160 fac_us=SYSCLK/8; 161 fac_ms=(u16)fac_us*1000;162 }

163 /*===============================================================================164 Author:peter pan165 Date:

166 Description: 查询式分时或叫做轮询式(近似延时)。本函数是⽤于执⾏⾼效率场合的查询延时,但是⼀个for or while 循环中只能⽤⼀次。167 revise Description:

168 @ num : //分时查询的周期计数值 169 @ unit : //分时查询的周期单位 170 @@ParaValue :

171 MS //周期单位为MS毫秒级172 US //周期单位为US微秒级173 @ virtual_delay_status : //静态变量174 @@ParaValue :

175 SET //SYSTICK正在占⽤中,请勿⽤176 RESET //SYSTICK空闲,可以使⽤177 @ReValue :

178 with zero mean Time non-arrive ,one representative Time arrived ,you can do task;179 ##example if(virtual_delay(1000,MS)) LedFlash(); //1000ms LED闪烁⼀下

180 ===============================================================================*/181 u8 virtual_delay(u32 num,u8 unit)182 {

183 u32 temp;

184 if(virtual_delay_status==RESET) // SYSTICK空闲,可以使⽤185 {

186 if(unit==MS)187 {

188 SysTick->LOAD=(u32)num*Delay_SYSCLK*125;//时间加载(SysTick->LOAD为24bit)189 SysTick->VAL =0x00; //清空计数器190 SysTick->CTRL=0x01 ; //开始倒数 191 }else if(unit==US) 192 {

193 SysTick->LOAD=num*Delay_SYSCLK/8; //时间加载 194 SysTick->VAL=0x00; //清空计数器195 SysTick->CTRL=0x01 ; //开始倒数 196 }

197 virtual_delay_status=SET;198 return 0;199 }200 else

201 { //virtual_delay_status==SET SYSTICK被占⽤202

203 temp=SysTick->CTRL;

204 if(!(temp&0x01&&!(temp&(1<<16))))//等待时间到达 205 {

206 SysTick->CTRL=0x00; //关闭计数器207 SysTick->VAL =0X00; //清空计数器 208 virtual_delay_status=RESET; 209 return 1;210 }else return 0;211 }212 }

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- xiaozhentang.com 版权所有

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务