vasilapita

  • 2024-06-19
  • 发表了主题帖: stm32f103c8t6的USART3接收数据很慢,恳请各位大佬分析一下原因。

    课题要求无线通信将单片机B采集到的AD值传输到单片机A进行PID移相控制,但是接收端更新数据很慢,完全满足不了我的控制要求,我的PID调制频率为85KHz。以下是UASRT串口代码以及main函数代码。 USART: #include "stm32f10x.h"                  // Device header #include <stdio.h> #include <stdarg.h> uint8_t Serial_TxPacket[4]; uint8_t Serial_RxPacket[4]; uint8_t Serial_RxFlag; void Serial_Init(void) {     RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);          GPIO_InitTypeDef GPIO_InitStructure;     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;     GPIO_Init(GPIOB, &GPIO_InitStructure);          GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;     GPIO_Init(GPIOB, &GPIO_InitStructure);          USART_InitTypeDef USART_InitStructure;     USART_InitStructure.USART_BaudRate = 115200;     USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;     USART_InitStructure.USART_Mode = USART_Mode_Rx;     USART_InitStructure.USART_Parity = USART_Parity_No;     USART_InitStructure.USART_StopBits = USART_StopBits_1;     USART_InitStructure.USART_WordLength = USART_WordLength_8b;     USART_Init(USART3, &USART_InitStructure);          USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);          NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);          NVIC_InitTypeDef NVIC_InitStructure;     NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;     NVIC_Init(&NVIC_InitStructure);          USART_Cmd(USART3, ENABLE); } void Serial_SendByte(uint8_t Byte) //传送单一字节 {     USART_SendData(USART3, Byte);     while (USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET); } void Serial_SendArray(uint8_t *Array,uint16_t Length) //传送一组但需要标识长度单位 {     uint16_t i;     for(i=0;i<Length;i++)     {     Serial_SendByte(Array[i]);     } } void Serial_SendString(char *string) //char可替换为uint8_t String表示结束标志位 {     uint8_t i;     for(i=0;string[i] !=0;i++) //string=0时结束     {     Serial_SendByte(string[i]);     } } uint32_t Serial_Pow(uint32_t X, uint32_t Y) //返回值为x的y次方 {     uint32_t Result=1;     while (Y--) //循环y次     {     Result *= X; //result累乘y次x 即得x的y次方     }     return Result; } void Serial_SendNumber(uint32_t Number, uint8_t Length)  //采用拆分数字的方式发送 过程同array {     uint8_t i;     for(i=0;i<Length;i++)     {         Serial_SendByte(Number/Serial_Pow(10,Length-i-1) % 10 + '0');     } } int fputc(int ch, FILE *f) {     Serial_SendByte(ch);     return ch; } void Serial_Printf(char *format, ...) {     char String[100];     va_list arg;     va_start(arg, format);     vsprintf(String, format, arg);     va_end(arg);     Serial_SendString(String); } void Serial_SendPacket(void) {     Serial_SendByte(0xFF);     Serial_SendArray(Serial_TxPacket, 4);     Serial_SendByte(0xFE); } uint8_t Serial_GetRxFlag(void) {     if (Serial_RxFlag == 1)     {         Serial_RxFlag = 0;         return 1;     }     return 0; } void USART3_IRQHandler(void) {     static uint8_t RxState1 = 0;     static uint8_t pRxPacket1 = 0;     if (USART_GetITStatus(USART3, USART_IT_RXNE) == SET)     {         uint8_t RxData1 = USART_ReceiveData(USART3);                  if (RxState1 == 0)         {             if (RxData1 == 0xFF)             {                 RxState1 = 1;                 pRxPacket1 = 0;             }         }         else if (RxState1 == 1)         {             Serial_RxPacket[pRxPacket1] = RxData1;             pRxPacket1 ++;             if (pRxPacket1 >= 4)             {                 RxState1 = 2;             }         }         else if (RxState1 == 2)         {             if (RxData1 == 0xFE)             {                 RxState1 = 0;                 Serial_RxFlag = 1;             }         }         USART_ClearITPendingBit(USART3, USART_IT_RXNE);     } } main: #include "stm32f10x.h" //#include "Delay.h" #include "timer.h"                  // Device header #include "PWM.h" #include "ADC.h" #include "OLED.h" #include "Serial.h" uint16_t AD1; float Voltage1; float Voltage2; float Voltage3; float RL1; float I1; float U1; int Phase; //float Kp = 0.00003; //float Ki = 0.0000000001;   float Kp = 0.00003;   float Ki = 0.00000000001; float target = 10; float actual = 0; float error = 0; float err_last = 0; float integral = 0; float  out = 0; uint16_t received_ad_value1; uint16_t received_ad_value2;     extern uint16_t pwm_high_1,pwm_high_2; extern uint16_t pwm_low_1,pwm_low_2; extern uint8_t Serial_RxFlag; int main (void) {         TIM1_PWM_Init();          AD_Init();          Serial_Init();          OLED_Init();     Timer_Init();          while(1)     {     if (Serial_GetRxFlag() == 1)     {                      received_ad_value1 = Serial_RxPacket[0] << 8 | Serial_RxPacket[1]; //IADC         received_ad_value2 = Serial_RxPacket[2] << 8 | Serial_RxPacket[3]; //UADC         Voltage1 = (float)AD1*3.3/4095;         Voltage2 = (float)received_ad_value1*3.3/4095;         Voltage3 = (float)received_ad_value2*3.3/4095;         U1 = (Voltage3 * 11);         I1 = (Voltage2 - 1.65) / (0.132);         RL1 = (U1)/(I1);          }          AD1 = AD_Value[0];     OLED_ShowString(1,1,"error:00.00");     OLED_ShowString(2,1,"integral:00.00"); //    OLED_ShowString(3,1,"out:00.00");     OLED_ShowString(4,1,"Rx:");          OLED_ShowSignedNum(1,7,error,2);     OLED_ShowNum(1,10,(uint16_t)(error*100)%100,2);     OLED_ShowSignedNum(2,10,integral,2);     OLED_ShowNum(2,13,(uint16_t)(integral*100)%100,2); //    OLED_ShowNum(3,5,out,2); //    OLED_ShowNum(3,8,(uint16_t)(out*100)%100,2);     OLED_ShowHexNum(4, 4, Serial_RxPacket[0], 2);     OLED_ShowHexNum(4, 7, Serial_RxPacket[1], 2);     OLED_ShowHexNum(4, 10, Serial_RxPacket[2], 2);     OLED_ShowHexNum(4, 13, Serial_RxPacket[3], 2);      } } void TIM2_IRQHandler(void) {     if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET)     {         actual = U1;         error = target - actual;         integral = integral + error;         out = out + Kp*error + Ki*integral;         if(out < 0)             out = 0;         if(out > 90)             out = 90;         err_last = error;                  Phase = out * 7 / 18;         pwm_high_1 = 0;         pwm_low_1 = 0+70;         pwm_high_2 = Phase ;         pwm_low_2 = 0+70+Phase;                      TIM_ClearITPendingBit(TIM2, TIM_IT_Update);     } }                           

最近访客

现在还没有访客

< 1/0 >

统计信息

已有--人来访过

  • 芯积分:17
  • 好友:--
  • 主题:1
  • 回复:0

留言

你需要登录后才可以留言 登录 | 注册


现在还没有留言