打印
[应用相关]

关于STM32中多串口工作的问题

[复制链接]
615|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
逢dududu必shu|  楼主 | 2021-8-5 21:51 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
USART_SendDataUSART_SendData各位大虾:
      本人刚接触STM32,菜鸟一个。 我最近遇到一个关于STM32中5个串口同时工作的问题,自己忙了一个多月,也查了不少资料,但问题依旧没有解决,所以当自己努力后还没解决问题就要向吧里的各位兄弟姐妹求教了,废话不多说,直奔主题

    任务要求是,4路串口分别接收各路数据,然后由一个串口发给上位机;每路数据一共5个字节    {FF 81 数据位 数据位 校验和  }  前两个是帧头和状态位,当中是两个数据位 ,最后是校验和

    我的设计思路是: 让串口2~5这四个串口分时接收数据,然后通过串口1发送给电脑; 即先让串口2工作,把串口3、4、5关掉,只有当串口2收到中断里面的正确的状态位并通过串口1发送出去之后关掉串口2,然后使能串口3,当串口3工作完后关掉串口3,如此以往

在中断里面所做的工作就是判断帧头、状态位、校验和正确则置标志位,总的来讲程序设计思路简单;

使用特权

评论回复
沙发
逢dududu必shu|  楼主 | 2021-8-5 21:54 | 只看该作者
我所碰到的问题:只让串口2和3接收,串口1发出,即在代码中注释掉串口4和5工作的部分,工作非常正常,一点问题也没有;
                                但是当加入串口4让串口2、3、4同时工作,偶尔这3个串口能正确收几次程序就死掉,运气不好的时候,刚轮到串口4工作就死掉了,但是我把其它串口工作部分注释掉只让串口4收串口1发又是正常的,我现在很纠结,不知道问题出在哪?也不知道该怎么解决?自己调了一个多月,没什么进展,前来向各位兄弟姐妹求教,望指点一二,谢谢!(我用的是战舰板调的,有没有战舰板上短路帽插错导致这种现象的可能?)

使用特权

评论回复
板凳
逢dududu必shu|  楼主 | 2021-8-5 21:59 | 只看该作者
本帖最后由 逢dududu必shu 于 2021-8-5 22:01 编辑

附上源码

这是USART.C
001#include "sys.h"

002#include "usart.h"   

003

004u8 USART2_RX_BUF[USART_REC_LEN];     //接收缓冲,最大USART_REC_LEN个字节.

005u8 USART3_RX_BUF[USART_REC_LEN];

006u8 UART4_RX_BUF[USART_REC_LEN];

007u8 UART5_RX_BUF[USART_REC_LEN];

008

009

010u8 m=0;

011u8 n=0;

012u8 p=0;

013u8 q=0;

014

015

016u8 i=0;

017

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

019u16 USART3_RX_STA=0;

020u16 UART4_RX_STA=0;       //接收状态标记   

021u16 UART5_RX_STA=0;

022

023//初始化串口1`5

024//bound:波特率

025void uart_init(u32 bound){

026    //GPIO端口设置

027    GPIO_InitTypeDef GPIO_InitStructure;

028    USART_InitTypeDef USART_InitStructure;

029    NVIC_InitTypeDef NVIC_InitStructure;

030      

031    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB, ENABLE);    //使能USART1,GPIOA时钟

032    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOD, ENABLE);  

033  

034  

035  

036  

037  

038    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2|RCC_APB1Periph_USART3, ENABLE);

039    RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART4|RCC_APB1Periph_UART5, ENABLE);

040

041

042

043    USART_DeInit(USART1);  //复位串口1`5

044    USART_DeInit(USART2);

045    USART_DeInit(USART3);

046    USART_DeInit(UART4);

047    USART_DeInit(UART5);        

048      

049      

050      

051      

052      

053      

054      

055     //USART1_TX  USART2_TX  PA.9 PA.2

056    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_9; //PA.9与PA.2

057    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

058    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出

059    GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化PA9

060   

061    //USART1_RX USART2_RX  PA.10  PA.3

062    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3|GPIO_Pin_10;

063    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入

064    GPIO_Init(GPIOA, &GPIO_InitStructure);  //初始化PA10

065

066

067

068     //USART3_TX   PB.10

069    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //PB.10

070    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

071    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出

072    GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化PA9

073   

074    //USART3_RX   PB.11

075    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;

076    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入

077    GPIO_Init(GPIOB, &GPIO_InitStructure);  //初始化PA10

078

079    //UART4_TX   UART5_TX   PC10 PC12

080    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10|GPIO_Pin_12; //PC10 PC12

081    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

082    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出

083    GPIO_Init(GPIOC, &GPIO_InitStructure); //初始化PC10 PC12

084

085

086    //UART4_RX     PC11

087    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;

088    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入

089    GPIO_Init(GPIOC, &GPIO_InitStructure);  //初始化PC11

090

091    //UART5_RX     PD2

092    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;

093    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入

094    GPIO_Init(GPIOD, &GPIO_InitStructure);  //初始化 PD2

095

096

097

098

099

100   //USART1 初始化设置

101

102    USART_InitStructure.USART_BaudRate = bound;//一般设置为9600;

103    USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式

104    USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位

105    USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位

106    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制

107    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式

108

109    USART_Init(USART1, &USART_InitStructure); //初始化串口

110

111  //USART2 初始化设置

112

113    USART_InitStructure.USART_BaudRate = bound;//一般设置为9600;

114    USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式

115    USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位

116    USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位

117    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制

118    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式

119

120    USART_Init(USART2, &USART_InitStructure); //初始化串口

121

122

123

124      //USART3 初始化设置

125

126    USART_InitStructure.USART_BaudRate = bound;//一般设置为9600;

127    USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式

128    USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位

129    USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位

130    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制

131    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式

132

133    USART_Init(USART3, &USART_InitStructure); //初始化串口

134

135

136

137        //UART4 初始化设置

138

139    USART_InitStructure.USART_BaudRate = bound;//一般设置为9600;

140    USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式

141    USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位

142    USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位

143    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制

144    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式

145

146    USART_Init(UART4, &USART_InitStructure); //初始化串口

147

148

149

150           //UART5 初始化设置

151

152    USART_InitStructure.USART_BaudRate = bound;//一般设置为9600;

153    USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式

154    USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位

155    USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位

156    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制

157    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式

158

159    USART_Init(UART5, &USART_InitStructure); //初始化串口

160

161

162

163

164

165

166

167

168

169

170

171   //Usart1 NVIC 配置

172    NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;

173    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3;//抢占优先级3

174    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;      //子优先级3

175    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;         //IRQ通道使能

176    NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器

177   

178    USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);//开启中断

179

180

181   NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;

182    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3

183    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;      //子优先级3

184    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;         //IRQ通道使能

185    NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器

186   

187    USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);//开启中断

188

189

190

191    NVIC_InitStructure.NVIC_IRQChannel = UART4_IRQn;

192    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3

193    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;      //子优先级3

194    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;         //IRQ通道使能

195    NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器

196   

197    USART_ITConfig(UART4, USART_IT_RXNE, ENABLE);//开启中断

198

199

200    NVIC_InitStructure.NVIC_IRQChannel = UART5_IRQn;

201    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3

202    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;      //子优先级3

203    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;         //IRQ通道使能

204    NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器

205   

206    USART_ITConfig(UART5, USART_IT_RXNE, ENABLE);//开启中断

207

208

209

210

211

212

213    USART_Cmd(USART1, ENABLE);                    //使能串口

214 /*   USART_Cmd(USART2, ENABLE);

215    USART_Cmd(USART3, ENABLE);

216    USART_Cmd(UART4, ENABLE);

217    USART_Cmd(UART5, ENABLE);     */

218

219}

220

221

222

223void USART2_IRQHandler(void)                    //串口2中断服务程序

224    {

225    u8 Res2;

226

227

228    if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)  //

229        {

230        Res2=USART_ReceiveData(USART2);//(USART2->DR);   //读取接收到的数据

231         

232            USART2_RX_BUF[USART2_RX_STA]=Res2;  

233             USART2_RX_STA++;

234

235                if(USART2_RX_STA==5)

236

237             {

238               USART2_RX_STA=0;

239                 

240              i=USART2_RX_BUF[0]+USART2_RX_BUF[1]+USART2_RX_BUF[2]+USART2_RX_BUF[3];

241         

242             if(USART2_RX_BUF[0]==0XFF&&USART2_RX_BUF[1]==0X81&&i==USART2_RX_BUF[4])

243

244               {

245            

246                m=0x01;

247                 

248                  }

249                              

250              else {m=0;}

251         

252               }

253

254            }            

255

256         }

257

258

259

260void USART3_IRQHandler(void)                    //串口3中断服务程序

261    {

262    u8 Res3;

263

264

265    if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET)  //

266        {

267        Res3=USART_ReceiveData(USART3);//(USART2->DR);   //读取接收到的数据

268         

269            USART3_RX_BUF[USART3_RX_STA]=Res3;  

270             USART3_RX_STA++;

271

272                if(USART3_RX_STA==5)

273

274             {

275               USART3_RX_STA=0;

276                 

277              i=USART3_RX_BUF[0]+USART3_RX_BUF[1]+USART3_RX_BUF[2]+USART3_RX_BUF[3];

278         

279             if(USART3_RX_BUF[0]==0XFF&&USART3_RX_BUF[1]==0X81&&i==USART3_RX_BUF[4])

280

281               {

282            

283                n=0x01;

284                 

285                  }

286                              

287              else {n=0;}

288         

289               }

290

291            }            

292

293         }

294

295

296

297

298void UART4_IRQHandler(void)                 //串口4中断服务程序

299    {

300    u8 Res4;

301

302

303    if(USART_GetITStatus(UART4, USART_IT_RXNE) != RESET)  //

304        {

305        Res4=USART_ReceiveData(UART4);//读取接收到的数据

306         

307            UART4_RX_BUF[UART4_RX_STA]=Res4;   

308             UART4_RX_STA++;

309

310                if(UART4_RX_STA==5)

311

312             {

313               UART4_RX_STA=0;

314                 

315              i=UART4_RX_BUF[0]+UART4_RX_BUF[1]+UART4_RX_BUF[2]+UART4_RX_BUF[3];

316         

317             if(UART4_RX_BUF[0]==0XFF&&UART4_RX_BUF[1]==0X81&&i==UART4_RX_BUF[4])

318

319               {

320            

321                p=0x01;

322                 

323                  }

324                              

325              else {p=0;}

326         

327               }

328

329            }            

330

331         }

332

333

334

335

336

337void UART5_IRQHandler(void)                 //串口5中断服务程序

338    {

339    u8 Res5;

340

341

342    if(USART_GetITStatus(UART5, USART_IT_RXNE) != RESET)

343        {

344        Res5=USART_ReceiveData(UART5);//读取接收到的数据

345         

346            UART5_RX_BUF[UART5_RX_STA]=Res5;   

347             UART5_RX_STA++;

348

349                if(UART5_RX_STA==5)

350

351             {

352               UART5_RX_STA=0;

353                 

354              i=UART5_RX_BUF[0]+UART5_RX_BUF[1]+UART5_RX_BUF[2]+UART5_RX_BUF[3];

355         

356             if(UART5_RX_BUF[0]==0XFF&&UART5_RX_BUF[1]==0X81&&i==UART5_RX_BUF[4])

357

358               {

359            

360                q=0x01;

361                 

362                  }

363                              

364              else {q=0;}

365         

366               }

367

368            }            

369

370         }

371

372

373USART.H部分的源码


使用特权

评论回复
地板
逢dududu必shu|  楼主 | 2021-8-5 22:02 | 只看该作者



01

#ifndef __USART_H





02

#define __USART_H





03

#include "stdio.h"  





04

#include "sys.h"





05







06







07







08







09

#define USART_REC_LEN           5   //定义最大接收字节数 200





10







11

         





12

extern u8  USART2_RX_BUF[USART_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.末字节为换行符





13

extern u8  USART3_RX_BUF[USART_REC_LEN];





14

extern u8  UART4_RX_BUF[USART_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.末字节为换行符





15

extern u8  UART5_RX_BUF[USART_REC_LEN];





16







17

extern u8  m;





18

extern u8  n;





19

extern u8  p;





20

extern u8  q;





21







22







23







24







25







26

extern u16 USART2_RX_STA;               //接收状态标记   





27

extern u16 USART3_RX_STA;





28

extern u16 UART4_RX_STA;                //接收状态标记   





29

extern u16 UART5_RX_STA;





30







31







32







33

//如果想串口中断接收,请不要注释以下宏定义





34

void uart_init(u32 bound);





35

#endif

使用特权

评论回复
5
逢dududu必shu|  楼主 | 2021-8-5 22:03 | 只看该作者
main.c部分源码




001

#include "sys.h"





002

#include "usart.h"





003







004

int main(void)





005

{  





006

  





007

     





008

    u8 t=0;





009

    NVIC_Configuration();    //设置NVIC中断分组2:2位抢占优先级,2位响应优先级





010

    uart_init(9600);     //串口初始化为9600





011







012

    while(1)





013

    {





014

      





015

      //串口2





016







017







018

    USART_Cmd(USART2, ENABLE);                  //使能串口2





019

     while(m!=0X01);





020

        {                     





021

         





022

         USART_ITConfig(USART2, USART_IT_RXNE, DISABLE);//在此处要关闭中断





023

            m=0;   





024

            for(t=0;t<5;t++)





025

            {





026

                USART_SendData(USART1, USART2_RX_BUF[t]);//向串口1发送数据





027

                while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待发送结束





028

            }     





029







030

           USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);  //开启串口中断





031







032

        }





033

     





034







035

    USART_Cmd(USART2, DISABLE);                       //失能串口2





036







037







038

    //串口3





039







040







041

USART_Cmd(USART3, ENABLE);





042







043

while(n!=0X01);





044

        {                     





045

         





046

         USART_ITConfig(USART3, USART_IT_RXNE, DISABLE);//在此处要关闭中断





047

            n=0;   





048

            for(t=0;t<5;t++)





049

            {





050

                USART_SendData(USART1, USART3_RX_BUF[t]);//向串口1发送数据





051

                while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待发送结束





052

            }     





053







054

           USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);  //开启串口中断





055

     





056

     





057

         





058

        }





059







060







061

    USART_Cmd(USART3, DISABLE);            





062







063







064







065







066







067







068

//串口4





069







070

USART_Cmd(UART4, ENABLE);





071







072

while(p!=0X01);





073

        {                     





074

         





075

         USART_ITConfig(UART4, USART_IT_RXNE, DISABLE);//在此处要关闭中断





076

            p=0;   





077

            for(t=0;t<5;t++)





078

            {





079

                USART_SendData(USART1, UART4_RX_BUF[t]);//向串口1发送数据





080

                while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待发送结束





081

            }     





082







083

           USART_ITConfig(UART4, USART_IT_RXNE, ENABLE);  //开启串口中断





084

     





085

     





086

         





087

        }





088







089







090

    USART_Cmd(UART4, DISABLE);





091







092

   





093







094







095







096







097







098

//   串口5





099

   





100

USART_Cmd(UART5, ENABLE);





101







102

while(q!=0X01);





103

        {                     





104

         





105

         USART_ITConfig(UART5, USART_IT_RXNE, DISABLE);//在此处要关闭中断





106

            q=0;   





107

            for(t=0;t<5;t++)





108

            {





109

                USART_SendData(USART1, UART5_RX_BUF[t]);//向串口1发送数据





110

                while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待发送结束





111

            }     





112







113

           USART_ITConfig(UART5, USART_IT_RXNE, ENABLE);  //开启串口中断





114

     





115

     





116

         





117

        }





118







119







120

    USART_Cmd(UART5, DISABLE);        





121







122







123







124







125







126







127







128







129







130







131







132

    }   





133

}

使用特权

评论回复
6
呐咯密密| | 2021-8-6 10:04 | 只看该作者
有几点回复一下:
1.代码贴的简直不忍直视,一个屏幕两三行代码。太难受了。希望后面可以改善一下,或者我给你整理一下。
2.这里有个地方你没介绍,就是你的板子上的几个串口数据是怎么来的,是一起还是一个个来。
3.主函数的while(1)循环里面判断数据有没有接收到,不要用while()来等待,如果你的某个数据出错,会导致一直卡死在这里

使用特权

评论回复
7
diweo| | 2021-8-6 13:56 | 只看该作者
随便跑个RTOS,5个任务同时开,各跑各的,互不影响。当串口2,3,4,5收到数据时通知串口1发送即可。

使用特权

评论回复
8
asmine| | 2021-8-6 14:03 | 只看该作者
这代码,我选择了直接忽略。
但串口应该没问题,好好缕缕
我407所以的串口都用了,并且有232和485

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

61

主题

451

帖子

0

粉丝