girlexplorer 发表于 2025-1-29 17:53:45

再用专业编程AI编了一个单片机程序,各位看看多少分

本帖最后由 girlexplorer 于 2025-1-29 17:55 编辑

这个也是国产AI,一个很有名的大公司制作的AI。

各位看看这个AI自动编出的程序能得多少分:

再和另一款AI编出的程序对比一下:
http://www.crystalradio.cn/forum.php?mod=redirect&goto=findpost&ptid=2176970&pid=26621482&fromuid=4258



您:(提出需求)

使用标准库,启用STM32的定时器一,输出PWM,系统时钟72MHz。热敏电阻采集温度,以采集的温度为参考,以PWM方式驱动直流电机调速,制作温控风扇。40°C时启动风扇,占空比30%,50°C时占空比100%。


gpt4all:(AI的全部回答如下)

要实现一个温控风扇,使用STM32的定时器一输出PWM信号,并根据热敏电阻采集到的温度来控制电机的速度,可以按照以下步骤进行:

1. 初始化硬件:
   - 初始化GPIO用于连接热敏电阻和直流电机。
   - 配置定时器一为PWM模式。

2. 读取热敏电阻值:
   - 使用ADC(模拟数字转换)模块读取热敏电阻的电压或温度值。

3. 计算占空比:
   - 根据采集到的温度,计算相应的占空比。例如,40°C时占空比为30%,50°C时占空比为100%。

4. 设置PWM输出:
   - 使用定时器一的PWM功能来控制电机的速度。

以下是一个示例代码:

c
#include "stm32f1xx_hal.h"

// 定义GPIO和ADC引脚
#define TEMP_SENSOR_PIN GPIO_Pin_8 // 热敏电阻连接到PA8
#define MOTOR_PWM_PIN GPIO_Pin_9// PWM输出连接到PB9

// ADC配置结构体
static ADC_HandleTypeDef hadc;

// 初始化函数
void SystemClock_Config(void);
void MX_GPIO_Init(void);
void MX_ADC1_Init(void);

int main(void)
{
    HAL_Init();
    SystemClock_Config();
    MX_GPIO_Init();
    MX_ADC1_Init();

    // 配置定时器一为PWM模式
    TIM_HandleTypeDef htim1;
    htim1.Instance = TIM1;
    htim1.Init.Prescaler = 72 - 1; // 假设系统时钟是72MHz,预分频器设置为63(最大值)
    htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
    htim1.Init.Period = 999;       // PWM周期
    if (HAL_TIM_PWM_Init(&htim1) != HAL_OK)
    {
      Error_Handler();
    }

    // 配置PWM通道
    TIM_OC_InitTypeDef sConfigOC;
    sConfigOC.OCMode = TIM_OCMODE_PWM1;
    sConfigOC.Pulse = 0;            // 初始占空比为0%
    sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
    if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
    {
      Error_Handler();
    }

    while (1)
    {
      // 读取热敏电阻值
      uint32_t adc_value = ADC_GetValue(&hadc);

      // 计算占空比(假设温度与ADC值成线性关系)
      float temperature = adc_value * 40.0 / 65535; // 假设最大电压是65535
      uint16_t duty_cycle = (uint16_t)(temperature * 99); // 范围从0到99

      // 设置PWM占空比
      TIM_SetCompare1(&htim1, duty_cycle);

      // 等待一段时间(例如,每秒读取一次)
      HAL_Delay(1000);
    }
}

// 初始化系统时钟
void SystemClock_Config(void)
{
    RCC_OscInitTypeDef RCC_OscInitStruct = {0};
    RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

    // 配置内部振荡器(HSI)为8MHz
    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
    RCC_OscInitStruct.HSIState = RCC_HSI_ON;
    RCC_OscInitStruct.HSICalibrationValue = 16;
    if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
    {
      Error_Handler();
    }

    // 配置系统时钟为HSI
    RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
    RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
    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_0) != HAL_OK)
    {
      Error_Handler();
    }
}

// 初始化GPIO
void MX_GPIO_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};

    __HAL_RCC_GPIOA_CLK_ENABLE();
    __HAL_RCC_GPIOB_CLK_ENABLE();

    // 配置热敏电阻引脚为输入模式
    GPIO_InitStruct.Pin = TEMP_SENSOR_PIN;
    GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    // 配置PWM输出引脚为推挽输出模式
    GPIO_InitStruct.Pin = MOTOR_PWM_PIN;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}

// 初始化ADC1
void MX_ADC1_Init(void)
{
    ADC_ChannelConfTypeDef sConfigChannel = {0};

    __HAL_RCC_ADC1_CLK_ENABLE();

    hadc.Instance = ADC1;
    hadc.Init.ScanConvMode = DISABLE;
    hadc.Init.ContinuousConvMode = ENABLE;
    hadc.Init.DiscontinuousConvMode = DISABLE;
    hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
    hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;
    hadc.Init.NbrOfConversion = 1;
    if (HAL_ADC_Init(&hadc) != HAL_OK)
    {
      Error_Handler();
    }

    sConfigChannel.Channel = TEMP_SENSOR_PIN;
    sConfigChannel.Rank = 1;
    sConfigChannel.SamplingTime = ADC_SAMPLETIME_3CYCLES;
    if (HAL_ADC_ConfigChannel(&hadc, &sConfigChannel) != HAL_OK)
    {
      Error_Handler();
    }
}

// 错误处理函数
void Error_Handler(void)
{
    while(1);
}


说明:
- 系统时钟:假设系统时钟是72MHz,预分频器设置为63(最大值),PWM周期设置为999。
- 热敏电阻读取:使用ADC模块读取热敏电阻的电压或温度值。这里假设温度与ADC值成线性关系,并根据这个关系计算占空比。
- PWM输出:使用定时器一的PWM功能来控制电机的速度。

请根据实际情况调整代码中的参数和逻辑,例如ADC采样时间、预分频器设置等。

平淡中的幸福 发表于 2025-1-29 18:21:54

需要确定硬件参数和接口号
没有微调 要么不能运行 要么报错

做框架还行

girlexplorer 发表于 2025-1-29 18:47:39

本帖最后由 girlexplorer 于 2025-1-29 18:48 编辑

谢各位提示。

换了一个老外的小聊天AI,(不是专业编程AI),AI居然采用了STM32F405,而没有采用老衲经常听说的STM32F103,比较特别。
这个小AI回答不知能得多少分?





您:(提出要求)

使用标准库,启用STM32的定时器一,输出PWM,系统时钟72MHz。热敏电阻采集温度,以采集的温度为参考,以PWM方式驱动直流电机调速,制作温控风扇。40°C时启动风扇,占空比30%,50°C时占空比100%。


gpt4all:(AI的自动回答全部如下:)

要实现一个使用STM32F4系列微控制器的温控风扇系统,你可以按照以下步骤进行:

步骤1:硬件准备
- 硬件:
- STM32F405RG 或其他适合你需求的STM32系列开发板。
- 定时器一(TIM1)
- 热敏电阻(NTC温度传感器,例如LM35或DS18B20等)。
- PWM输出引脚
- 直流电机驱动模块

步骤2:软件准备
- STM32CubeMX工具来配置硬件连接和初始化。
- 使用STM32CubeIDE进行编程。

硬件连接示例:
1. TIM1 配置:
   - 连接 TIM1 的 CH0 和 PWM 输出引脚,通过PWM模式工作。
   
2. 温度传感器:
   - 将 NTC 温度传感器的数据线与 STM32 的 AIO3 引腳连接。

硬件配置(使用STM32CubeMX):
- 在TIM1中选择 CH0 作为 PWM 输出,设置PWM频率和宽度。
- 连接AIO3引脚到温度传感器输入端口,确保其工作模式正确。

步骤3:软件实现
1. 初始化硬件

c
#include "main.h"
#include "stm32f4xx_hal.h"

// 定时器一配置
TIM_HandleTypeDef htim1;
// 温度传感器初始化(假设使用DS18B20)
Temperature_t ds18b20;

void SystemClock_Config(void);
void TIM_Init(void);
void PWM_Init(void);

int main(void)
{
    HAL_Init();
    SystemClock_Config();

    TIM_Init();
    PWM_Init();

    while (1) {
      // 读取温度
      Temperature_read(&ds18b20);
      
      if(ds18b20.temperature > 40){
            HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_HIGH); // 启动风扇,占空比30%
      } else{
            HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_LOW); // 关闭风扇
      }
    }

    return 0;
}


2. 定时器一配置

c
void TIM_Init(void)
{
    htim1.Instance = TIM1;
    htim1.Init.Prescaler = 0;            // 保持频率为72MHz(没有分辨率调整)
    htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
    htim1.Init.Period = 65535;          // 设置计时器周期
    HAL_TIM_Init(&htim1);
}


3. PWM初始化

c
void PWM_Init(void)
{
    GPIO_InitTypeDef s_GPIOConfig;
   
    // 初始化GPIOA0为PWM输出
    s_GPIOConfig.Mode = GPIO_MODE_OUTPUT_PP;
    s_GPIOConfig.PullUpPushDown = GPIO_NOPULL;
    HAL_GPIO_Init(GPIOA, &s_GPIOConfig);
}


4. 温度传感器读取

假设使用DS18B20,需要引入相应的库并初始化:

c
#include "ds18b20.h"

void Temperature_read(Temperature_t *temperature)
{
    ds18x3x_Read(temperature);
}


5. 其他补充代码(具体依据传感器类型和实现细节而定)

注意事项:
1. 确保温度传感器的电源稳定,避免影响读取结果。
2. 在实际应用中可能需要考虑系统电压、过热保护等问题。
3. 代码中的部分库函数(如 `ds18x3x_Read`)需根据具体使用的温度传感器替换。

以上步骤为一个基本框架,具体实现细节和配置依赖于你所选择的STM32系列及特定硬件。

girlexplorer 发表于 2025-1-30 10:15:41

AI编程,作为学习还是很有用的。
试了一下:

您:(提出问题)
编写一个检测cpu是否支持AVX2指令的程序

gpt4all:(AI的回答)

编写一个检测CPU是否支持AVX2指令的程序可以使用C语言和标准库函数。以下是一个简单的示例,展示了如何在Windows上实现这一功能:

c
#include <stdio.h>
#include <intrin.h>

int main() {
    // 检查CPU是否支持AVX2指令
    if (Has_AVX2()) {
      printf("Your CPU supports AVX2 instructions.\n");
    } else {
      printf("Your CPU does not support AVX2 instructions.\n");
    }

    return 0;
}

// 函数用于检查CPU是否支持AVX2指令
int Has_AVX2() {
    // 使用内置的intrin.h函数来检测AVX2
    __cpuidex(&eax, &ebx, &ecx, 1);
    if ((ecx >> 5) & 0x1) { // 检查ECX位上的第6位(即AVX2标志)
      return 1;
    }
    return 0;
}


解释
- `__cpuidex`: 这是一个内置的C函数,用于获取CPUID指令的结果。它允许你查询特定的CPU特性。
- ECX寄存器: 在CPUID指令中,ECX寄存器在不同的EAX值下有不同的含义。对于AVX2检测,我们使用EAX=1和ECX=0来检查`ecx >> 5 & 0x1`是否为1。

编译
确保你的编译器支持C99标准,并且已经安装了Windows SDK。你可以使用以下命令进行编译:


cl /EHsc -o check_avx2.exe check_avx2.c


运行生成的可执行文件 `check_avx2.exe`,它将输出CPU是否支持AVX2指令的信息。

注意事项
- 这个程序仅适用于Windows平台。
- 确保你的系统已经安装了必要的开发工具和库。

t3486784401 发表于 2025-1-31 10:11:46

让用标准库SPL,怎么就直接上HAL了; 热敏电阻的程序,怎么就直接假定正比于电压了,还用了16bit的换算参数。

t3486784401 发表于 2025-1-31 10:51:12

girlexplorer 发表于 2025-1-29 18:47
谢各位提示。

换了一个老外的小聊天AI,(不是专业编程AI),AI居然采用了STM32F405,而没有采用老衲经 ...

这个程序更不靠谱,要求用热敏电阻,看到 18b20 这都啥

girlexplorer 发表于 2025-1-31 18:29:44

页: [1]
查看完整版本: 再用专业编程AI编了一个单片机程序,各位看看多少分