之前觉得gpt4也不咋滴,实际上还是我的使用姿势的问题。
最近尝试用gpt4写mcu固件,感受很震撼~~
下面我给出2个例子。第一个例子是我自己都对at32的库不熟悉,
只是随便找了点at32的范例,主要是给chatgpt一些支离破碎的参考,然后提出我的要求。
因为gpt4对at32不熟,所以它写的代码带有强烈的stm32 hal库风格。
这个代码肯定是无法编译过的,但不重要。
这阶段重点是把代码堆完整,把整个架子搭好,不要求编译过。
因为gpt4生成的代码还有很多细节错误。
后面第二个例子,这时我开始尝试编译代码,不断修复里面的错误。
小的错误,比如gpt4记忆偏差导致的小错误,诸如OD_READONLY它写成了OD_RO这种我就自己修了。(chatgpt也能自动修,但这种错误我直接改了更快)
然后另一种就是逻辑上没啥问题,但gpt4按照stm32的风格生成了。
这种我把at32的具体的官方示范一贴,要求他修复就行。
第二个例子中,虽然第一次它没理解对我的意思,但我明确指出要它干嘛之后它一下子就搞好了。
所以,我现在基本上就是chatgpt的搬运工了...
总体感觉:
1. 现在的gpt4已经非常可用了,完全可以当一个小弟帮你干活。
2. gpt4的记忆力还是有点弱,当然实际上openai内部版本记忆力更强,现在开放使用的版本其实也是阉割版。这一点不用怀疑。
3. 如果gpt4具有更大的上下文能力,后面可以把整个sdk和代码都丢给他,要求他一步到位全部改好。根本就不需要这么把代码片段搬运来搬运去,后面人连搬运工的价值都失去了...
4. 之前我认为gpt4缺乏更专业更小众领域的知识,做不好对应的事情。是我草率了。事实上我还让他移植了canopennode实现到了at32上...2-3天就搞定了...
5. 以前大家会觉得sdk很重要,模块化很重要,代码复用很重要...以后就不再是这样了。其实根本就不需要sdk,reference manual一丢,让ai直接在寄存器层面搞定就行了。如果读不懂让它给你解释下就行...下一个项目我会尝试这么搞下试试看...
==================
## You
这是一段初始化定时器的example:
tmr_input_default_para_init(&tmr_ic_init_structure);
tmr_ic_init_structure.input_filter_value = 0;
tmr_ic_init_structure.input_channel_select = TMR_SELECT_CHANNEL_2;
tmr_ic_init_structure.input_mapped_select = TMR_CC_CHANNEL_MAPPED_DIRECT;
tmr_ic_init_structure.input_polarity_select = TMR_INPUT_RISING_EDGE;
tmr_pwm_input_config(TMR3, &tmr_ic_init_structure, TMR_CHANNEL_INPUT_DIV_1);
/* select the tmr3 input trigger: C2IF2 */
tmr_trigger_input_select(TMR3, TMR_SUB_INPUT_SEL_C2DF2);
/* select the sub mode: reset mode */
tmr_sub_mode_select(TMR3, TMR_SUB_RESET_MODE);
/* enable the sub sync mode */
tmr_sub_sync_mode_set(TMR3, TRUE);
/* tmr enable counter */
tmr_counter_enable(TMR3, TRUE);
/* enable the c2 interrupt request */
tmr_interrupt_enable(TMR3, TMR_C2_INT, TRUE);
while(1)
{
printf("Frequency = %dHZ,Dutycycle = %d%%\r\n", frequency, duty_cycle);
}
参考这段代码,写下初始化motor定时器的设计,以下是motor和gpio的端口分配:
* PA9 -> PWMA TMR1_CH2
* PB0 -> PWMB TMR1_CH2N/TMR3_CH3/TMR8_CH2N
* PB1 -> DIR
## ChatGPT
首先,你需要明确哪个通道是用于PWM信号,哪个通道是用于DIR信号。假设PA9和PB0是PWM信号,PB1是DIR信号。根据你的需求,可能需要对三个通道进行单独的设置。但是在这里,我将为你提供一个PWM的基本设置,你可以根据实际的需求进行修改。
以下是代码实现:
```c
void init_motor_timer_pwm() {
tmr_base_init_type tmr_base_init_structure;
tmr_oc_init_type tmr_oc_init_structure;
crm_periph_clock_enable(CRM_TMR1_PERIPH_CLOCK, TRUE);
crm_periph_clock_enable(CRM_TMR3_PERIPH_CLOCK, TRUE);
/* Timer base configuration for TMR1 */
tmr_base_default_para_init(&tmr_base_init_structure);
tmr_base_init_structure.period = 0xFFFF; // Depending on your PWM frequency
tmr_base_init_structure.prescaler = 0;
tmr_base_init_structure.clock_division = TMR_CLK_DIV1;
tmr_base_init_structure.counter_mode = TMR_COUNTER_MODE_UP;
tmr_base_init(TMR1, &tmr_base_init_structure);
/* Timer base configuration for TMR3 */
tmr_base_default_para_init(&tmr_base_init_structure);
tmr_base_init_structure.period = 0xFFFF; // Depending on your PWM frequency
tmr_base_init_structure.prescaler = 0;
tmr_base_init_structure.clock_division = TMR_CLK_DIV1;
tmr_base_init_structure.counter_mode = TMR_COUNTER_MODE_UP;
tmr_base_init(TMR3, &tmr_base_init_structure);
/* PWM configuration for TMR1 channel 2 */
tmr_oc_default_para_init(&tmr_oc_init_structure);
tmr_oc_init_structure.output_state = TMR_OUTPUT_STATE_ENABLE;
tmr_oc_init_structure.output_n_state = TMR_OUTPUTN_STATE_DISABLE;
tmr_oc_init_structure.pulse = 0; // The pulse should be set according to the duty cycle
tmr_oc_init_structure.oc_polarity = TMR_OC_POLARITY_HIGH;
tmr_oc_init_structure.ocn_polarity = TMR_OCN_POLARITY_HIGH;
tmr_oc_init_structure.oc_mode = TMR_OC_MODE_PWM1;
tmr_oc_init_structure.oc_idle_state = TMR_OC_IDLE_STATE_RESET;
tmr_oc_init_structure.ocn_idle_state = TMR_OCN_IDLE_STATE_RESET;
tmr_oc_init(TMR1, &tmr_oc_init_structure, TMR_CHANNEL_2);
/* PWM configuration for TMR3 channel 3 */
tmr_oc_default_para_init(&tmr_oc_init_structure);
tmr_oc_init_structure.output_state = TMR_OUTPUT_STATE_ENABLE;
tmr_oc_init_structure.output_n_state = TMR_OUTPUTN_STATE_DISABLE;
tmr_oc_init_structure.pulse = 0; // The pulse should be set according to the duty cycle
tmr_oc_init_structure.oc_polarity = TMR_OC_POLARITY_HIGH;
tmr_oc_init_structure.ocn_polarity = TMR_OCN_POLARITY_HIGH;
tmr_oc_init_structure.oc_mode = TMR_OC_MODE_PWM1;
tmr_oc_init_structure.oc_idle_state = TMR_OC_IDLE_STATE_RESET;
tmr_oc_init_structure.ocn_idle_state = TMR_OCN_IDLE_STATE_RESET;
tmr_oc_init(TMR3, &tmr_oc
```
## You
不用这么多,只需要初始化tmr1即可,不用管dir,那个只是一个gpio
## ChatGPT
了解了。这是一个更简化的版本,只初始化了TMR1:
```c
void init_motor_timer_pwm() {
tmr_base_init_type tmr_base_init_structure;
tmr_oc_init_type tmr_oc_init_structure;
crm_periph_clock_enable(CRM_TMR1_PERIPH_CLOCK, TRUE);
/* Timer base configuration for TMR1 */
tmr_base_default_para_init(&tmr_base_init_structure);
tmr_base_init_structure.period = 0xFFFF; // Depending on your PWM frequency
tmr_base_init_structure.prescaler = 0;
tmr_base_init_structure.clock_division = TMR_CLK_DIV1;
tmr_base_init_structure.counter_mode = TMR_COUNTER_MODE_UP;
tmr_base_init(TMR1, &tmr_base_init_structure);
/* PWM configuration for TMR1 channel 2 */
tmr_oc_default_para_init(&tmr_oc_init_structure);
tmr_oc_init_structure.output_state = TMR_OUTPUT_STATE_ENABLE;
tmr_oc_init_structure.output_n_state = TMR_OUTPUTN_STATE_DISABLE;
tmr_oc_init_structure.pulse = 0; // The pulse should be set according to the duty cycle
tmr_oc_init_structure.oc_polarity = TMR_OC_POLARITY_HIGH;
tmr_oc_init_structure.ocn_polarity = TMR_OCN_POLARITY_HIGH;
tmr_oc_init_structure.oc_mode = TMR_OC_MODE_PWM1;
tmr_oc_init_structure.oc_idle_state = TMR_OC_IDLE_STATE_RESET;
tmr_oc_init_structure.ocn_idle_state = TMR_OCN_IDLE_STATE_RESET;
tmr_oc_init(TMR1, &tmr_oc_init_structure, TMR_CHANNEL_2);
/* Enable TMR1 counter */
tmr_counter_enable(TMR1, TRUE);
}
```
这个函数会将TMR1的channel 2配置为PWM模式,并启用计数器。PWMA将输出在PA9,对应TMR1的channel 2。实际的PWM频率和占空比可以通过修改结构体`tmr_base_init_structure`和`tmr_oc_init_structure`中的参数来设定。
## You
还需要打开TMR1_CH2N,也即反相输出
## ChatGPT
了解了。要打开反相输出 (N-Channel),我们需要在函数中启用 `output_n_state` 并指定 `ocn_polarity`。以下是修改后的代码:
```c
void init_motor_timer_pwm() {
tmr_base_init_type tmr_base_init_structure;
tmr_oc_init_type tmr_oc_init_structure;
crm_periph_clock_enable(CRM_TMR1_PERIPH_CLOCK, TRUE);
/* Timer base configuration for TMR1 */
tmr_base_default_para_init(&tmr_base_init_structure);
tmr_base_init_structure.period = 0xFFFF; // Depending on your PWM frequency
tmr_base_init_structure.prescaler = 0;
tmr_base_init_structure.clock_division = TMR_CLK_DIV1;
tmr_base_init_structure.counter_mode = TMR_COUNTER_MODE_UP;
tmr_base_init(TMR1, &tmr_base_init_structure);
/* PWM configuration for TMR1 channel 2 */
tmr_oc_default_para_init(&tmr_oc_init_structure);
tmr_oc_init_structure.output_state = TMR_OUTPUT_STATE_ENABLE;
tmr_oc_init_structure.output_n_state = TMR_OUTPUTN_STATE_ENABLE; // Enable N-Channel
tmr_oc_init_structure.pulse = 0; // The pulse should be set according to the duty cycle
tmr_oc_init_structure.oc_polarity = TMR_OC_POLARITY_HIGH;
tmr_oc_init_structure.ocn_polarity = TMR_OCN_POLARITY_HIGH; // Set N-Channel polarity
tmr_oc_init_structure.oc_mode = TMR_OC_MODE_PWM1;
tmr_oc_init_structure.oc_idle_state = TMR_OC_IDLE_STATE_RESET;
tmr_oc_init_structure.ocn_idle_state = TMR_OCN_IDLE_STATE_RESET; // Set N-Channel idle state
tmr_oc_init(TMR1, &tmr_oc_init_structure, TMR_CHANNEL_2);
/* Enable TMR1 counter */
tmr_counter_enable(TMR1, TRUE);
}
```
这个函数现在将TMR1的channel 2和channel 2N(反相)配置为PWM模式,并启用计数器。PWMA将在PA9(对应TMR1的channel 2)上输出,PWMB将在PB0(对应TMR1的channel 2N)上输出。实际的PWM频率和占空比可以通过修改结构体`tmr_base_init_structure`和`tmr_oc_init_structure`中的参数来设定。
## You
没有ocn_polarity这些东西哦,这是这个结构体的定义:
typedef struct
{
tmr_output_control_mode_type oc_mode; /*!< output channel mode */
confirm_state oc_idle_state; /*!< output channel idle state */
confirm_state occ_idle_state; /*!< output channel complementary idle state */
tmr_output_polarity_type oc_polarity; /*!< output channel polarity */
tmr_output_polarity_type occ_polarity; /*!< output channel complementary polarity */
confirm_state oc_output_state; /*!< output channel enable */
confirm_state occ_output_state; /*!< output channel complementary enable */
} tmr_output_config_type;
## ChatGPT
了解了,我看到这个库的naming convention和我之前见过的STM32库略有不同。我之前误解了这个库的naming convention。我们将"ocn"改为"occ"应该就可以了。以下是修改后的代码:
```c
void init_motor_timer_pwm() {
tmr_base_init_type tmr_base_init_structure;
tmr_oc_init_type tmr_oc_init_structure;
crm_periph_clock_enable(CRM_TMR1_PERIPH_CLOCK, TRUE);
/* Timer base configuration for TMR1 */
tmr_base_default_para_init(&tmr_base_init_structure);
tmr_base_init_structure.period = 0xFFFF; // Depending on your PWM frequency
tmr_base_init_structure.prescaler = 0;
tmr_base_init_structure.clock_division = TMR_CLK_DIV1;
tmr_base_init_structure.counter_mode = TMR_COUNTER_MODE_UP;
tmr_base_init(TMR1, &tmr_base_init_structure);
/* PWM configuration for TMR1 channel 2 */
tmr_oc_default_para_init(&tmr_oc_init_structure);
tmr_oc_init_structure.oc_output_state = TMR_OUTPUT_STATE_ENABLE;
tmr_oc_init_structure.occ_output_state = TMR_OUTPUT_STATE_ENABLE; // Enable complementary output
tmr_oc_init_structure.pulse = 0; // The pulse should be set according to the duty cycle
tmr_oc_init_structure.oc_polarity = TMR_OC_POLARITY_HIGH;
tmr_oc_init_structure.occ_polarity = TMR_OC_POLARITY_HIGH; // Set complementary output polarity
tmr_oc_init_structure.oc_mode = TMR_OC_MODE_PWM1;
tmr_oc_init_structure.oc_idle_state = TMR_OC_IDLE_STATE_RESET;
tmr_oc_init_structure.occ_idle_state = TMR_OC_IDLE_STATE_RESET; // Set complementary output idle state
tmr_oc_init(TMR1, &tmr_oc_init_structure, TMR_CHANNEL_2);
/* Enable TMR1 counter */
tmr_counter_enable(TMR1, TRUE);
}
```
在这个函数中,TMR1的channel 2和channel 2N(反相)被配置为PWM模式,启用计数器。PWMA将在PA9(对应TMR1的channel 2)上输出,而PWMB将在PB0(对应TMR1的channel 2N)上输出。实际的PWM频率和占空比可以通过修改`tmr_base_init_structure`和`tmr_oc_init_structure`中的参数来设定。
## You
很好,下面再写一段初始化timer的函数。TIM3_CH3用于产生pwm,TMR_CH2用于测量占空比。如果不知道怎么测量占空比可以告诉我,我找个例子给你看看。
## ChatGPT
我可以为你提供一个大概的模板,但是我需要了解一下你的具体需求。你需要在PB0(TIM3_CH3)上产生PWM信号,而在哪个引脚上测量占空比?因为你提到的TMR_CH2没有给出具体的引脚分配,如果这个信号在不同的引脚上,可能需要配置另一个定时器的输入捕获。这就需要更多的定时器初始化代码。
不过,我可以提供一个简化版的示例,该示例将测量同一定时器产生的PWM信号的占空比。也就是说,我们假设PWM信号也在PB0(TIM3_CH3)上。
以下是生成PWM并在同一定时器的同一通道上设置输入捕获的代码:
```c
<<这里生成过这种我已经看到错误了,被我主动打断>>
```
## You
PA9, TMR1_CH2上测量占空比
## ChatGPT
在你的应用中,TMR1_CH2(PA9)将被用于测量PWM占空比,而TMR3_CH3(PB0)则将被用于产生PWM信号。因此,我们需要初始化两个定时器:TMR1和TMR3。
首先,我们来初始化TMR3以产生PWM信号。因为你没有指定PWM的频率和占空比,我将假设一个频率为20kHz,占空比为50%的情况。你可以根据你的实际需要进行调整。
```c
void init_pwm_output(void)
{
// Init structure for PWM output
tmr_output_default_para_init(&tmr_oc_init_structure);
tmr_oc_init_structure.oc_mode = TMR_OC_MODE_PWM_1;
tmr_oc_init_structure.oc_polarity = TMR_OUTPUT_ACTIVE_HIGH;
tmr_oc_init_structure.oc_output_state = ENABLE;
tmr_time_base_structure.period = 1000; // Frequency = 20kHz
tmr_time_base_structure.prescaler = (SystemCoreClock / 20000000) - 1; // To have a 1us resolution
tmr_time_base_structure.repetition_counter = 0;
tmr_time_base_init(TMR3, &tmr_time_base_structure);
tmr_oc_init_structure.pulse = 500; // Duty cycle = 50%
tmr_oc_config(TMR3, TMR_CHANNEL_3, &tmr_oc_init_structure);
// Enable timer counter
tmr_counter_enable(TMR3, TRUE);
}
```
接下来,我们来初始化TMR1以测量PWM占空比。由于你的PWM信号和测量的信号在不同的定时器和通道上,我们需要使用输入捕获功能。首先我们将初始化TMR1的输入捕获:
```c
void init_pwm_input(void)
{
// Init structure for PWM input
tmr_input_default_para_init(&tmr_ic_init_structure);
tmr_ic_init_structure.input_filter_value = 0;
tmr_ic_init_structure.input_channel_select = TMR_SELECT_CHANNEL_2;
tmr_ic_init_structure.input_mapped_select = TMR_CC_CHANNEL_MAPPED_DIRECT;
tmr_ic_init_structure.input_polarity_select = TMR_INPUT_RISING_EDGE;
tmr_time_base_structure.period = 0xFFFF; // As big as possible
tmr_time_base_structure.prescaler = (SystemCoreClock / 20000000) - 1; // To have a 1us resolution
tmr_time_base_structure.repetition_counter = 0;
tmr_time_base_init(TMR1, &tmr_time_base_structure);
tmr_input_config(TMR1, &tmr_ic_init_structure, TMR_CHANNEL_INPUT_DIV_1);
// Enable timer counter
tmr_counter_enable(TMR1, TRUE);
}
```
你可以使用`tmr_input_capture_get()`函数获取输入捕获的值,从而计算PWM的占空比。
## You
请生成完整的代码,比如这个代码里没有声明tmr_base_init_structure, tmr_oc_init_structure,没有crm_periph_clock_enable来使能对应的时钟等等。
## ChatGPT
对不起,我确实忽略了一些初始化步骤。以下是包含所有必要步骤的完整代码。
```c
#include "at32f403a_407.h"
void init_pwm_output(void)
{
// Declare structures
tmr_baseinit_type tmr_base_init_structure;
tmr_ocinit_type tmr_oc_init_structure;
// Enable clocks for TMR3 and GPIOB
crm_periph_clock_enable(CRM_GPIOB_PERIPH_CLOCK, TRUE);
crm_periph_clock_enable(CRM_TMR3_PERIPH_CLOCK, TRUE);
// Init structure for PWM output
tmr_output_default_para_init(&tmr_oc_init_structure);
tmr_oc_init_structure.oc_mode = TMR_OC_MODE_PWM_1;
tmr_oc_init_structure.oc_polarity = TMR_OUTPUT_ACTIVE_HIGH;
tmr_oc_init_structure.oc_output_state = ENABLE;
tmr_base_init_structure.period = 1000; // Frequency = 20kHz
tmr_base_init_structure.prescaler = (SystemCoreClock / 20000000) - 1; // To have a 1us resolution
tmr_base_init_structure.repetition_counter = 0;
tmr_base_init(TMR3, &tmr_base_init_structure);
tmr_oc_init_structure.pulse = 500; // Duty cycle = 50%
tmr_oc_config(TMR3, TMR_CHANNEL_3, &tmr_oc_init_structure);
// Enable timer counter
tmr_counter_enable(TMR3, TRUE);
}
void init_pwm_input(void)
{
// Declare structures
tmr_baseinit_type tmr_base_init_structure;
tmr_icinit_type tmr_ic_init_structure;
// Enable clocks for TMR1 and GPIOA
crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE);
crm_periph_clock_enable(CRM_TMR1_PERIPH_CLOCK, TRUE);
// Init structure for PWM input
tmr_input_default_para_init(&tmr_ic_init_structure);
tmr_ic_init_structure.input_filter_value = 0;
tmr_ic_init_structure.input_channel_select = TMR_SELECT_CHANNEL_2;
tmr_ic_init_structure.input_mapped_select = TMR_CC_CHANNEL_MAPPED_DIRECT;
tmr_ic_init_structure.input_polarity_select = TMR_INPUT_RISING_EDGE;
tmr_base_init_structure.period = 0xFFFF; // As big as possible
tmr_base_init_structure.prescaler = (SystemCoreClock / 20000000) - 1; // To have a 1us resolution
tmr_base_init_structure.repetition_counter = 0;
tmr_base_init(TMR1, &tmr_base_init_structure);
tmr_input_config(TMR1, &tmr_ic_init_structure, TMR_CHANNEL_INPUT_DIV_1);
// Enable timer counter
tmr_counter_enable(TMR1, TRUE);
}
```
这段代码中,我们首先为TMR3和TMR1分别启用了时钟,并对相关GPIO进行了配置。之后,我们对TMR3进行了配置以产生PWM信号,并对TMR1进行了配置以测量PWM占空比。
## You
很好,下面把这两个初始化函数放在一个函数里就行了
## ChatGPT
好的,这是把两个函数合并在一起的代码:
```c
#include "at32f403a_407.h"
void init_pwm(void)
{
// Declare structures
tmr_baseinit_type tmr_base_init_structure;
tmr_ocinit_type tmr_oc_init_structure;
tmr_icinit_type tmr_ic_init_structure;
// Enable clocks for TMR3, TMR1 and GPIOB, GPIOA
crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE);
crm_periph_clock_enable(CRM_GPIOB_PERIPH_CLOCK, TRUE);
crm_periph_clock_enable(CRM_TMR1_PERIPH_CLOCK, TRUE);
crm_periph_clock_enable(CRM_TMR3_PERIPH_CLOCK, TRUE);
// Init structure for PWM output
tmr_output_default_para_init(&tmr_oc_init_structure);
tmr_oc_init_structure.oc_mode = TMR_OC_MODE_PWM_1;
tmr_oc_init_structure.oc_polarity = TMR_OUTPUT_ACTIVE_HIGH;
tmr_oc_init_structure.oc_output_state = ENABLE;
tmr_base_init_structure.period = 1000; // Frequency = 20kHz
tmr_base_init_structure.prescaler = (SystemCoreClock / 20000000) - 1; // To have a 1us resolution
tmr_base_init_structure.repetition_counter = 0;
tmr_base_init(TMR3, &tmr_base_init_structure);
tmr_oc_init_structure.pulse = 500; // Duty cycle = 50%
tmr_oc_config(TMR3, TMR_CHANNEL_3, &tmr_oc_init_structure);
// Enable timer counter for TMR3
tmr_counter_enable(TMR3, TRUE);
// Init structure for PWM input
tmr_input_default_para_init(&tmr_ic_init_structure);
tmr_ic_init_structure.input_filter_value = 0;
tmr_ic_init_structure.input_channel_select = TMR_SELECT_CHANNEL_2;
tmr_ic_init_structure.input_mapped_select = TMR_CC_CHANNEL_MAPPED_DIRECT;
tmr_ic_init_structure.input_polarity_select = TMR_INPUT_RISING_EDGE;
tmr_base_init_structure.period = 0xFFFF; // As big as possible
tmr_base_init_structure.prescaler = (SystemCoreClock / 20000000) - 1; // To have a 1us resolution
tmr_base_init_structure.repetition_counter = 0;
tmr_base_init(TMR1, &tmr_base_init_structure);
tmr_input_config(TMR1, &tmr_ic_init_structure, TMR_CHANNEL_INPUT_DIV_1);
// Enable timer counter for TMR1
tmr_counter_enable(TMR1, TRUE);
}
```
这段代码初始化PWM输入和输出。TMR3用于生成PWM信号,TMR1用于测量PWM占空比。
==================
## You
这是一段at32的官方初始化串口的代码范例:
/* enable the usart2 and gpio clock */
crm_periph_clock_enable(CRM_USART2_PERIPH_CLOCK, TRUE);
crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE);
/* enable the usart3 and gpio clock */
crm_periph_clock_enable(CRM_USART3_PERIPH_CLOCK, TRUE);
crm_periph_clock_enable(CRM_GPIOB_PERIPH_CLOCK, TRUE);
gpio_default_para_init(&gpio_init_struct);
/* configure the usart2 tx pin */
gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
gpio_init_struct.gpio_out_type = GPIO_OUTPUT_OPEN_DRAIN;
gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
gpio_init_struct.gpio_pins = GPIO_PINS_2;
gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
gpio_init(GPIOA, &gpio_init_struct);
/* configure the usart3 tx pin */
gpio_init_struct.gpio_pins = GPIO_PINS_10;
gpio_init(GPIOB, &gpio_init_struct);
/* configure usart2 param */
usart_init(USART2, 115200, USART_DATA_8BITS, USART_STOP_1_BIT);
usart_transmitter_enable(USART2, TRUE);
usart_receiver_enable(USART2, TRUE);
usart_single_line_halfduplex_select(USART2, TRUE);
usart_enable(USART2, TRUE);
/* configure usart3 param */
usart_init(USART3, 115200, USART_DATA_8BITS, USART_STOP_1_BIT);
usart_transmitter_enable(USART3, TRUE);
usart_receiver_enable(USART3, TRUE);
usart_single_line_halfduplex_select(USART3, TRUE);
usart_enable(USART3, TRUE);
下面是你写的代码,gpio已经在另一个地方初始化了。你再仔细检查下串口初始化部分的问题,把它修复
usart_init_type USART_InitStructure;
/* Enable USART2 clock */
crm_periph_clock_enable(CRM_USART2_PERIPH_CLOCK, TRUE);
/* Configure USART2 parameters */
USART_InitStructure.baud_rate = 9600;
USART_InitStructure.data_length = USART_DATA_8BITS;
USART_InitStructure.stop_bits = USART_STOP_1_BIT;
USART_InitStructure.parity = USART_PARITY_NONE;
USART_InitStructure.mode = USART_MODE_TX_RX;
USART_InitStructure.flow_control = USART_FLOW_CONTROL_NONE;
usart_init(USART2, &USART_InitStructure);
/* Enable USART2 */
usart_enable(USART2, TRUE);
## ChatGPT
你的反馈很有用,我了解到你的GPIO已经在其他地方初始化了,那么我们需要重点关注USART的初始化。我注意到你的代码中,USART的模式是`USART_MODE_TX_RX`,但在官方示例中,模式被设置为`usart_single_line_halfduplex_select()`,这是半双工模式。因此,我们需要将你的代码中的模式更改为半双工模式。这是修改后的代码:
```c
usart_init_type USART_InitStructure;
/* Enable USART2 clock */
crm_periph_clock_enable(CRM_USART2_PERIPH_CLOCK, TRUE);
/* Configure USART2 parameters */
USART_InitStructure.baud_rate = 9600;
USART_InitStructure.data_length = USART_DATA_8BITS;
USART_InitStructure.stop_bits = USART_STOP_1_BIT;
USART_InitStructure.parity = USART_PARITY_NONE;
USART_InitStructure.flow_control = USART_FLOW_CONTROL_NONE;
usart_init(USART2, &USART_InitStructure);
/* Set USART2 to Half Duplex mode */
usart_single_line_halfduplex_select(USART2, TRUE);
/* Enable USART2 */
usart_enable(USART2, TRUE);
```
在上述代码中,我添加了`usart_single_line_halfduplex_select(USART2, TRUE);`以将USART2设置为半双工模式。注意,这是根据官方示例中的设置来调整的,你应该根据你的实际硬件和应用需求来选择正确的模式。
此外,这个代码假设你使用的是USART2,如果你实际使用的是其他USART,请根据实际情况进行更改。
如果还有其他错误,请提供更多的信息,这样我可以更准确地提供帮助。
## You
不是的,并不是半双工的问题。是根本就没有usart_init_type USART_InitStructure;这个东西。你需要仔细对照官方范例修改
## ChatGPT
感谢你的耐心和反馈。现在我了解到了你的问题,你需要按照AT32官方的示例进行USART初始化,而不是使用STM32的`usart_init_type`。这是修改后的代码:
```c
/* Enable USART2 clock */
crm_periph_clock_enable(CRM_USART2_PERIPH_CLOCK, TRUE);
/* Configure USART2 parameters */
usart_init(USART2, 9600, USART_DATA_8BITS, USART_STOP_1_BIT);
usart_transmitter_enable(USART2, TRUE);
usart_receiver_enable(USART2, TRUE);
/* Enable USART2 */
usart_enable(USART2, TRUE);
```
在上述代码中,我按照AT32的示例初始化了USART2,注意我没有使用`usart_init_type`结构体,而是直接将参数传递给`usart_init()`函数。这是因为AT32的USART初始化和STM32的不同,前者没有使用结构体来保存参数。请根据你的硬件和需求来修改这段代码。
--
修改:lvsoft FROM 180.111.27.*
FROM 180.111.27.*