M69002400 2024-07-19 10:46 采纳率: 0%
浏览 18
已结题

任务是接收数据并把数据写入DAC7311,这些代码能实现此功能吗


#include "main.h"
#include "tim.h"
#include "usart.h"
#include "gpio.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "dac711.h"
#include "myusart.h"
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
extern   uint8_t USART1_NewData;
 extern   uint8_t My_RXData;

/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USART1_UART_Init();
  MX_USART2_UART_Init();
  MX_USART3_UART_Init();
  MX_TIM2_Init();
  /* USER CODE BEGIN 2 */
  DAC7311_Init();
    HAL_UART_Receive_IT(&huart1,(uint8_t *)&USART1_NewData,1);
 

     /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  
  while (1)
  {
    /* USER CODE END WHILE */
    
        AO1_Write(My_RXData);
        USART1_NewData = 0;
        /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    Error_Handler();
  }
}
```c

#include "string.h"
#include "stdio.h"
uint16_t cnum;
void delay(uint8_t us)
{
    for(; us !=0; us--);
}

void DAC7311_Init(void)
{
    AO1_SYNC_H();
    AO1_SCLK_L();
}

void AO1_Write(uint16_t Data)
{
    uint8_t temp;
    uint8_t    ui;
    
    temp=Data << 2;//7311ÐèÒªÒÆÁ½Î»
    temp &= 0x3FFF;//Ñ¡ÔñģʽΪNormal
    AO1_SYNC_H();
    AO1_SCLK_H();
    delay(10);
    AO1_SYNC_L();//ʹÄÜÊäÈëÒÆÎ»¼Ä´æÆ÷
    delay(10);
    
    for(ui=0; ui<16; ui++)
    {
        
        AO1_SCLK_H();
        
        if(0x8000 == (temp & 0x8000))
        {
            AO1_DIN_H();
        }
        else
        {
            AO1_DIN_L();
        }
        delay(10);
        AO1_SCLK_L();
        delay(10);
        temp <<=1;
    }
    
    AO1_SYNC_H();

}
```c

#include "myusart.h"
#include "string.h"
#include "stdio.h"

uint8_t USART1_RX_BUF[USART1_REC_LEN];//½ÓÊÕ»º³å,×î´óUSART_REC_LEN¸ö×Ö½Ú.
uint16_t USART1_RX_STA=0;//½ÓÊÕ״̬±ê¼Ç//bit15£º½ÓÊÕÍê³É±êÖ¾£¬bit14£º½ÓÊÕµ½0x0d£¬bit13~0£º½ÓÊÕµ½µÄÓÐЧ×Ö½ÚÊýÄ¿
uint8_t USART1_NewData;//µ±Ç°´®¿ÚÖжϽÓÊÕµÄ1¸ö×Ö½ÚÊý¾ÝµÄ»º´æ
uint32_t hex_to_decimal(uint8_t *hex_array, uint16_t length);
char receivedHex[3] = {0}; // ´æ´¢½ÓÊÕµ½µÄÁ½¸ö16½øÖÆ×Ö·ûºÍÒ»¸ö½áÊø·û

uint8_t USART2_RX_BUF[USART2_REC_LEN];//½ÓÊÕ»º³å,×î´óUSART_REC_LEN¸ö×Ö½Ú.
uint16_t USART2_RX_STA=0;//½ÓÊÕ״̬±ê¼Ç//bit15£º½ÓÊÕÍê³É±êÖ¾£¬bit14£º½ÓÊÕµ½0x0d£¬bit13~0£º½ÓÊÕµ½µÄÓÐЧ×Ö½ÚÊýÄ¿
uint8_t USART2_NewData;//µ±Ç°´®¿ÚÖжϽÓÊÕµÄ1¸ö×Ö½ÚÊý¾ÝµÄ»º´æ
uint8_t RS485orBT;//µ±RS485orBT±ê־λΪ1ʱÊÇRS485ģʽ£¬Îª0ʱÊÇÀ¶ÑÀģʽ

uint8_t USART3_RX_BUF[USART3_REC_LEN];//½ÓÊÕ»º³å,×î´óUSART_REC_LEN¸ö×Ö½Ú.
uint16_t USART3_RX_STA=0;//½ÓÊÕ״̬±ê¼Ç//bit15£º½ÓÊÕÍê³É±êÖ¾£¬bit14£º½ÓÊÕµ½0x0d£¬bit13~0£º½ÓÊÕµ½µÄÓÐЧ×Ö½ÚÊýÄ¿
uint8_t USART3_NewData;//µ±Ç°´®¿ÚÖжϽÓÊÕµÄ1¸ö×Ö½ÚÊý¾ÝµÄ»º´æ
int decimalNumber=0;
int i=0;
int fputc(int ch, FILE *f)
{
  HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xffff);
  return ch;
}

int fgetc(FILE *f)
{
  uint8_t ch = 0;
  HAL_UART_Receive(&huart1, &ch, 1, 0xffff);
  return ch;
}


uint8_t My_RXData;
void  HAL_UART_RxCpltCallback(UART_HandleTypeDef  *huart)//´®¿ÚÖжϻص÷º¯Êý
{
    if(huart ==&huart1)//ÅжÏÖжÏÀ´Ô´£¨´®¿Ú1£ºUSBת´®¿Ú£©
    {
       My_RXData = USART1_NewData;
       HAL_UART_Receive_IT(&huart1,(uint8_t *)&USART1_NewData,1); //ÔÙ¿ªÆô½ÓÊÕÖжÏ
    }

```

```任务是接收数据并把数据写入DAC7311,这些代码能实现此功能吗,while函数里的数据清除代码是否正确,在中断回调函数里是否还要添加代码

  • 写回答

14条回答 默认 最新

  • 专家-赤兔[在线] 全栈领域优质创作者 2024-07-19 10:46
    关注

    引自免费微信小程序:皆我百晓生

    从您提供的代码来看,您正在尝试使用STM32来接收数据并通过UART接口写入DAC7311转换器。针对您的任务需求,让我们逐点进行分析:

    首先,您已经在main函数中设置了UART的初始化,并在中断回调函数中接收数据。这是正确的做法。当接收到数据时,您将其存储在My_RXData变量中。然后,您使用AO1_Write()函数将数据写入DAC7311。这看起来是一个合适的逻辑。

    关于您在while循环中的代码:

    while (1)
    {
      /* USER CODE END WHILE */
      
      AO1_Write(My_RXData);
      USART1_NewData = 0; // 这个操作似乎是清除接收标志位。这种做法通常正确,除非在清除前要确保所有数据都已处理完毕。但在某些应用中,可能需要更复杂的逻辑来处理数据的接收和清除。具体取决于您的应用需求。如果您正在使用的HAL库是基于标志来识别中断,这个清除是必要的。如果在一个事务或处理循环的结束阶段已经处理过所有数据并重置标志,这样做是没问题的。
      /* USER CODE BEGIN 3 */
    }
    

    至于中断回调函数,目前看来代码似乎足够。但是要注意的是中断函数通常用于响应某些事件(如数据接收)。您已经在其中设置了标志位以标识新数据的接收,然后在主循环中使用该标志来进行后续处理(在这里是写入DAC)。这样做通常是合理的。不过要注意保持代码的逻辑性并确保不会在中断处理中执行过长导致潜在的时序问题或并发问题。如果您的中断服务程序(ISR)执行时间过长或涉及复杂的计算或操作,可能会影响系统的实时响应能力或其他中断的处理。确保ISR尽可能简洁和快速执行是关键。如果不需要在中断中进行其他操作(如处理多个接收缓冲区等),则不需要添加其他代码。否则,请根据您的实际需求添加适当的代码逻辑来处理多个事件或状态切换等。另外,对于数据同步和数据完整性保护等要求较高的场合,还需要进行更详细的考虑和处理措施,比如设置标志位并使用循环确认等方式来保证数据传输的正确性和完整性等。关于您的代码是否能够实现此功能的问题,基于您提供的代码片段来看,大体上看起来是可以实现接收数据并写入DAC的功能的。当然具体是否完全可行还需要测试代码在硬件上的实际表现情况,并进行必要的调试和优化以确保功能的正确性和稳定性。同时还需要注意处理好各种可能的异常情况和边界条件等问题以确保系统的健壮性和可靠性等。如果您对具体的实现细节或遇到的问题还有疑问或困惑的话,请提供更多的上下文信息或详细描述您的问题以便我能更好地帮助您解决问题。

    评论 编辑记录

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 7月19日
  • 创建了问题 7月19日