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;t<len;t++)        //循环发送数据

73     {          

74         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;t<len;t++)        //循环发送数据

67     {          

68         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波特率设置为9600

101     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;i<len;i++)  

83     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;        //时钟分频1

132         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_TIMEOUT<USART3_TIMEOUT_Setting)

145                 USART3_RX_TIMEOUT++;        

146     }

147     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;i<rxlen;i++)

81         {

82             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;t<len;t++)        //循环发送数据

99     {          

100         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波特率设置为9600

111     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/8

155 //SYSCLK:系统时钟

156 void Systick_delay_init(u8 SYSCLK)

157 {

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

159 //    SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);    //选择外部时钟  HCLK/8

160     fac_us=SYSCLK/8;            

161     fac_ms=(u16)fac_us*1000;

162 }

163 /*===============================================================================

164 Author:peter pan

165 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 }


相关文章
|
4月前
stm32f407探索者开发板(十七)——串口寄存器库函数配置方法
stm32f407探索者开发板(十七)——串口寄存器库函数配置方法
694 0
|
4月前
STM32CubeMX 串口收发一帧数据
STM32CubeMX 串口收发一帧数据
56 9
|
4月前
|
芯片
STM32CubeMX 串口数据收发
STM32CubeMX 串口数据收发
138 2
|
5月前
|
传感器
【经典案例】STM32F407使用HAL库配置I2C详解
STM32F407是一个强大的微控制器,广泛应用于嵌入式系统中。在许多应用中,我们需要使用I2C总线来与传感器、EEPROM、显示屏等外设进行通信。本文将详细介绍如何使用STM32 HAL库来配置和使用I2C接口。
674 2
|
5月前
|
开发者
【经典案例】使用HAL库配置STM32F407的SPI外设
在嵌入式系统开发中,STM32F407是一款广泛应用的微控制器,而SPI(Serial Peripheral Interface)是一种常用的通信接口。本文将详细介绍如何使用STM32的硬件抽象层(HAL)库配置STM32F407的SPI外设,并提供完整的代码示例。
553 1
|
4月前
|
监控
stm32f407探索者开发板(十八)——串口通信实验讲解(USART_RX_STA流程图详解)
stm32f407探索者开发板(十八)——串口通信实验讲解(USART_RX_STA流程图详解)
270 0
|
4月前
stm32f407探索者开发板(十六)——串行通信原理讲解-UART
stm32f407探索者开发板(十六)——串行通信原理讲解-UART
262 0
|
4月前
|
传感器 编解码 API
【STM32开发入门】温湿度监测系统实战:SPI LCD显示、HAL库应用、GPIO配置、UART中断接收、ADC采集与串口通信全解析
SPI(Serial Peripheral Interface)是一种同步串行通信接口,常用于微控制器与外围设备间的数据传输。SPI LCD是指使用SPI接口与微控制器通信的液晶显示屏。这类LCD通常具有较少的引脚(通常4个:MISO、MOSI、SCK和SS),因此在引脚资源有限的系统中非常有用。通过SPI协议,微控制器可以向LCD发送命令和数据,控制显示内容和模式。
156 0
|
4月前
|
数据安全/隐私保护
STM32F103C8T6实现简易密码锁(CubeMax配置)(一),Oled显示。
项目功能:实现设置密码,登陆密码,后期还可以通过E2PROM实现掉电不丢失数据。通过Oled的显示去判断我们是否设置或者登陆成功。