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

  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

  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

  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

  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

  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

  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

  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 }

  最后还是给搞一些串口方面的资料便于学习参考

(stm32串口应用)
http://www.makeru.com.cn/live/1392_1164.html?s=45051

基于STM32讲解串口操作
http://www.makeru.com.cn/live/1758_490.html?s=45051
通过Z-stack协议栈实现串口透传
http://www.makeru.com.cn/live/1758_330.html?s=45051

stm32之SPI通信
http://www.makeru.com.cn/live/3523_1795.html?s=45051

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. C# 加载Word的3种方法

    本次经验内容分享通过C#程序来加载Word文档的3种不同方法.分别是: 1. 加载本地Word文档 2. 以只读模式加载Word文档 3. 从流加载Word [程序环境] Windows 10 Vis ...

  2. JNDI注入基础

    JNDI注入基础 一.简介 JNDI(The Java Naming and Directory Interface,Java命名和目录接口)是一组在Java应用中访问命名和目录服务的API,命名服务 ...

  3. SpringBoot自定义初始化Bean+HashMap优化策略模式实践

    策略模式:定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户. 传统的策略模式一般是创建公共接口.定义公共方法-->然后创建实体类实现公共接口.根据各自的 ...

  4. linux命令(用户)

    一.常用命令 1.1 ls ls 命令是 linux 下最常用的命令,ls 命令就是 list 的缩写. ls 用来打印出当前目录的清单.如果 ls 指定其他目录,那么就会显示指定目录里的文件及文件夹 ...

  5. 使用 VSCode 开发调试 STM32 单片机尝试

    使用 VSCode 开发调试 STM32 单片机尝试 本文记录基于 Windows + DAP-Link 开发 STM32F103C8T6 的实践过程,其他操作系统或芯片应该也只是大同小异的问题. 注 ...

  6. js 签字插件

    1.jq-signature  http://bencentra.github.io/jq-signature/    支持的jquery版本低 2.HTML5 canvas   http://www ...

  7. webpack 安装与卸载

    全局安装(不推荐): npm install webpack webpack-cli -g 安装好后打印版本: webpack -v webpack-cli -v 卸载全局 npm uninstall ...

  8. Jmeter系列(1) - 踩坑之代理服务器录制失败

    前景 Jmeter代理服务器报错信息如下.Jmeter录制不成功 解决方案 需了解 代理服务器启动后会在/bin目录生成ApacheJMeterTemporaryRootCA.crt和ApacheJM ...

  9. spring入门3-jdbcTemplate简单使用和声明式事务

    1.JdbcTemplate简单使用 1.1.引入相关依赖包 <dependency> <groupId>mysql</groupId> <artifactI ...

  10. python3.7+flask+alipay 支付宝付款功能

    文档参考github:https://github.com/fzlee/alipay/blob/master/docs/init.md 沙箱环境配置:https://opendocs.alipay.c ...