C语言 STM32单片机与带有USART器件的SIM20模块之间的通信



我正试图使STM32f1微控制器与SIM20模块通信。我希望所有的硬件设置都做得很好。说到软件,我的C程序由以下几个部分组成:

  1. 碾压混凝土配置
  2. GPIO配置
  3. USART配置
  4. 发送字符串"AT+SRDFIRM"
  5. 将接收到的缓冲区存储在文件"test.txt"中
  6. 打开LED3

但是没有从SIM20接收到任何消息。文件中没有存储任何内容,LED3没有打开。

我的C代码如下:

/* Includes ------------------------------------------------------------------*/
#include "stm32f10x.h"
#include "stm32_eval.h"
#include <stdio.h>
#include <stdlib.h>
/* Private typedef -----------------------------------------------------------*/
typedef enum { FAILED = 0, PASSED = !FAILED} TestStatus;
/* Private define ------------------------------------------------------------*/
#define USARTy                   USART1
#define USARTy_GPIO              GPIOA /* PORT name*/
#define USARTy_CLK               RCC_APB2Periph_USART1
#define USARTy_GPIO_CLK          RCC_APB2Periph_GPIOA
#define USARTy_RxPin             GPIO_Pin_10/* pin Rx name*/ 
#define USARTy_TxPin             GPIO_Pin_9 /* pin Tx name*/
#define USARTz                   USART2
#define USARTz_GPIO              GPIOA/* PORT name*/
#define USARTz_CLK               RCC_APB1Periph_USART2
#define USARTz_GPIO_CLK          RCC_APB2Periph_GPIOA
#define USARTz_RxPin             GPIO_Pin_3/* pin Rx name*/
#define USARTz_TxPin             GPIO_Pin_2/* pin Tx name*/
#define TxBufferSize   (countof(TxBuffer))
/* Private macro -------------------------------------------------------------*/
#define countof(a)   (sizeof(a) / sizeof(*(a)))
/* Private variables ---------------------------------------------------------*/
USART_InitTypeDef USART_InitStructure;
uint8_t TxBuffer[] = "AT+SRDFIRM";
uint8_t RxBuffer[TxBufferSize];
__IO uint8_t TxConteur = 0, RxConteur = 0;
uint8_t Bin[16];
/* Private function prototypes -----------------------------------------------*/
void RCC_Configuration(void);
void GPIO_Configuration(void);
void Delay(__IO uint32_t);
TestStatus Buffercmp(uint8_t* pBuffer1, uint8_t* pBuffer2, uint16_t BufferLength);
__IO uint8_t index = 0;
volatile TestStatus TransferStatus = FAILED;  
GPIO_InitTypeDef GPIO_InitStructure;
int main(void)
{
  STM_EVAL_LEDInit(LED1);
  STM_EVAL_LEDInit(LED2);
  STM_EVAL_LEDInit(LED3);
  STM_EVAL_LEDInit(LED4);
    int i;
  /*TxBuffer[0] = 'B';
  RxBuffer[0] ='';*/
/* System Clocks Configuration */
 RCC_Configuration();
/* Configure the GPIO ports */
GPIO_Configuration();
USART_InitStructure.USART_BaudRate = 115200;      // configuration vitesse
USART_InitStructure.USART_WordLength = USART_WordLength_8b; // configuration longueur mot
USART_InitStructure.USART_StopBits = USART_StopBits_1;  // bit de stop
USART_InitStructure.USART_Parity = USART_Parity_No; // bit de parite
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; // hardware control
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; // half duplex
  /* Configure USARTy */
  USART_Init(USART1,&USART_InitStructure);
  /* Enable the USARTy */
  USART_Cmd(USART1,ENABLE);
  uint16_t reciv;
    /*********************************************************/
        FILE* fichier = NULL; 
         fichier = fopen("test.txt", "w");
    while(TxConteur < TxBufferSize)
  {  
    /* Send one byte from USARTy to USARTz */
      USART_SendData(USARTy, TxBuffer[TxConteur++]);
  } 
    /* Loop until USARTy DR register is empty */ 
    while(USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET);
      while(TxConteur < TxBufferSize)
  { 
    RxBuffer[RxConteur] = USART_ReceiveData(USARTy) & 0xFF;
    RxConteur++;
  }
   fprintf(fichier,"%s","RxBuffer");  
  fclose(fichier); // On ferme le fichier qui a été ouvert
   TransferStatus = Buffercmp(TxBuffer, RxBuffer, TxBufferSize);
 STM_EVAL_LEDOn(LED3);
  while (1)
  {
  }
}
void RCC_Configuration(void)
{    
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 , ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC , ENABLE);
}
void GPIO_Configuration(void)
{
  GPIO_InitTypeDef GPIO_InitStructure1,GPIO_InitStructure2;
  /* Configure USARTy Rx as input floating */
  GPIO_InitStructure1.GPIO_Pin =GPIO_Pin_10;
  GPIO_InitStructure1.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure1.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_Init(GPIOA, &GPIO_InitStructure1);
  /* Configure USARTy Tx as alternate function push-pull */
  GPIO_InitStructure2.GPIO_Pin =GPIO_Pin_9;
  GPIO_InitStructure2.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure2.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_Init(GPIOA, &GPIO_InitStructure2); 
}

TestStatus Buffercmp(uint8_t* pBuffer1, uint8_t* pBuffer2, uint16_t BufferLength)
{
  while(BufferLength--)
  {
    if(*pBuffer1 != *pBuffer2)
    {
      return FAILED;
    }
    pBuffer1++;
    pBuffer2++;
  }
  return PASSED;  
}

@H2CO3:这是程序中包含问题的部分:

 while(TxConteur < TxBufferSize-1)
  {  
    /* Send one byte from USARTy to USARTz */
      USART_SendData(USARTy, TxBuffer[TxConteur++]);
    while(USART_GetFlagStatus(USART1, USART_FLAG_IDLE) == RESET);
  } 
RxConteur=0;
    /* Store the received byte in RxBuffer */
      while(RxConteur < TxBufferSize-1)
  { 
    RxBuffer[RxConteur] = USART_ReceiveData(USARTy) & 0xFF;
    RxConteur++;
  }

一些值得关注的东西:

  • UART是否复位?

如果STM32在默认情况下使UARTs处于重置状态,我不记得了。您启用了时钟,但没有显式地将其从重置中取出。如果它仍然处于重置状态,那么当您旋转等待RXNE标志设置时,它可能总是读取为重置。这将停止执行,您将无法达到LED启用。

  • USART_SendDataUSART_ReceiveData是否检查数据寄存器的状态?

如果这些函数不检查数据寄存器的状态,那么您的传输可能无法正常输出。在115200传输一个字符需要80微秒。对DR的第一次写入将被快速加载到移位寄存器中,而对DR的第二次写入将被保持,但除非在USART_SendData中检查DR状态,否则进一步尝试发送将会踩踏先前加载的字节。传输的最终结果可能在串行线上显示为AM

同样,USART_ReceiveData可能会用相同字节的重复来填充接收缓冲区,直到下一个字节进入(尽管STM32可能在读取值后清除DR)。

  • 文件。你使用什么编译器和运行时?

由于这是您的main()函数,我们可以看到启动时初始化的内容。我没有看到任何文件系统的初始化。它可能发生在main之前,取决于运行时。您使用什么工具来构建它,它是否支持文件访问?我知道IAR的运行时支持标准的文件调用,但默认情况下它们将返回失败,除非您实现低级函数。您没有检查文件是否成功打开,并且使用fprintf的写入可能会崩溃。

确保你的运行时支持文件访问,并对调用做一些有意义的事情,并为你的文件调用添加错误检查。

最新更新