[APM32E0] 【APM32E030R Micro-EVB开发板评测】+使用串口打印ADC采集的数据

[复制链接]
LiuDW091 发表于 2025-8-27 16:55 | 显示全部楼层 |阅读模式
本帖最后由 LiuDW091 于 2025-8-27 19:44 编辑

本次实验通过USART1串口打印ADC采集的数据(TMR1触发)。

串口USART1:RX----PA10、TX----PA9
ADC采集口:ADC_IN0------PA0
一、硬件原理图以及硬件连接
1780568aec208bb251.png
231868aec2308b470.png
6646768aec299495a7.png
273768aec31c27f7d.png
二、代码
USART串口函数:

void USART1_Init(void)
{
    USART_Config_T usartConfigStruct;
    GPIO_Config_T gpioConfig;
   
    // 使能USART1和GPIOB时钟
    RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_USART1);
//    RCM_EnableAHBPeriphReset(RCM_AHB_PERIPH_GPIOA);
          RCM_EnableAHBPeriphClock(RCM_AHB_PERIPH_GPIOA);
        
            // 配置引脚复用功能
    GPIO_ConfigPinAF(USART1_GPIO, GPIO_PIN_SOURCE_9, GPIO_AF_PIN1);  // TX
    GPIO_ConfigPinAF(USART1_GPIO, GPIO_PIN_SOURCE_10, GPIO_AF_PIN1); // RX
   
    // 配置USART1引脚
    gpioConfig.pin = USART1_TX_PIN;
    gpioConfig.mode = GPIO_MODE_AF;
    gpioConfig.speed = GPIO_SPEED_50MHz;
    gpioConfig.outtype = GPIO_OUT_TYPE_PP;
    gpioConfig.pupd = GPIO_PUPD_NO;
    GPIO_Config(USART1_GPIO, &gpioConfig);
   
    gpioConfig.pin = USART1_RX_PIN;
    GPIO_Config(USART1_GPIO, &gpioConfig);
   
    // 配置USART1参数
    usartConfigStruct.baudRate = 115200;
    usartConfigStruct.hardwareFlowCtrl = USART_FLOW_CTRL_NONE;
    usartConfigStruct.mode = USART_MODE_TX_RX;
    usartConfigStruct.parity = USART_PARITY_NONE;
    usartConfigStruct.stopBits = USART_STOP_BIT_1;
    usartConfigStruct.wordLength = USART_WORD_LEN_8B;
   
    USART_Config(USART1, &usartConfigStruct);
   
                 USART_EnableInterrupt(USART1, USART_INT_RXBNEIE);
    // 使能USART1
    USART_Enable(USART1);
}

2、ADC函数

void ADC_Init(void)
{
    GPIO_Config_T gpioConfig;   
          ADC_Config_T adcConfig;

   
    // 使能ADC和GPIOA时钟
    RCM_EnableAHBPeriphClock(RCM_AHB_PERIPH_GPIOA);
          RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_ADC1);
          RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_SYSCFG);
   
    // 配置ADC输入引脚
    gpioConfig.pin = ADC_PIN;
    gpioConfig.mode = GPIO_MODE_AN;
    gpioConfig.pupd = GPIO_PUPD_NO;
    GPIO_Config(ADC_GPIO_PORT, &gpioConfig);
   
    // 复位ADC
     ADC_Reset();
     ADC_ConfigStructInit(&adcConfig);
        
    // 配置ADC参数
    adcConfig.resolution = ADC_RESOLUTION_12B;      // 12位分辨率
    adcConfig.dataAlign = ADC_DATA_ALIGN_RIGHT;       // 数据右对齐
    adcConfig.scanDir = ADC_SCAN_DIR_UPWARD;              // 扫描方向向上
    adcConfig.convMode = ADC_CONVERSION_SINGLE;   // 单次转换模式
    adcConfig.extTrigConv = ADC_EXT_TRIG_CONV_TRG1;   //
    adcConfig.extTrigEdge = ADC_EXT_TRIG_EDGE_RISING;   // 无外部触发边沿
   
    ADC_Config(&adcConfig);
   
    // 配置ADC通道
    ADC_ConfigChannel(ADC_CHANNEL_0, ADC_SAMPLE_TIME_239_5);
    // ADC校准
    ADC_ReadCalibrationFactor();               
        // 使能ADC
    ADC_Enable();

}

3、TMR1

void TMR1_Init(void)
{
    TMR_TimeBase_T timerConfig;
    TMR_OCConfig_T  occonfig;

    // 使能TMR1时钟
     RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_TMR1);
   
    // 配置TMR1 - 10Hz采样率
    timerConfig.clockDivision = TMR_CKD_DIV1;
    timerConfig.counterMode = TMR_COUNTER_MODE_UP;
    timerConfig.div = 7199;      // 72MHz/(7199+1)=10kHz
    timerConfig.period = 999;         // 10kHz/1000=10Hz
    timerConfig.repetitionCounter =  0;
    TMR_ConfigTimeBase(TMR1, &timerConfig);

        
    /* PWM1 mode */
    occonfig.OC_Mode =  TMR_OC_MODE_PWM1;
    /* Idle State is reset */
    occonfig.OC_Idlestate  = TMR_OCIDLESTATE_RESET;
    /* NIdle State is reset */
    occonfig.OC_NIdlestate = TMR_OCNIDLESTATE_RESET;
    /* Enable CH1N ouput */
    occonfig.OC_OutputNState =  TMR_OUTPUT_NSTATE_ENABLE;
    /* Enable CH1 ouput */
    occonfig.OC_OutputState  =  TMR_OUTPUT_STATE_ENABLE;
    /* CH1  polarity is high */
    occonfig.OC_Polarity  = TMR_OC_POLARITY_HIGH;
    /* CH1N polarity is high */
    occonfig.OC_NPolarity = TMR_OC_NPOLARITY_HIGH;
    /* Set compare value = 0x01 */
    occonfig.Pulse = 0x1;
    TMR_OC4Config(TMR1, &occonfig);
               
    /* Enable PWM output */
    TMR_EnablePWMOutputs(TMR1);
    /*  Enable TMR1  */
    TMR_Enable(TMR1);
}

4、 串口发送字符串

// 串口发送字符串
void USART_SendString(USART_T* usart, char* str)
{
    while (*str) {
        while (USART_ReadStatusFlag(usart, USART_FLAG_TXBE) == RESET);
        USART_TxData(usart, *str++);
    }
}

5、串口发送ADC值

// 串口发送ADC值
void Send_ADC_Value(uint16_t value)
{
    float voltage = (float)value * 3.30f / 4095.0f;  // 计算电压值  
    // 格式化输出
    sprintf(uartBuffer, "ADC Value: %4d, Voltage: %.3fV\r\n", value, voltage);
    USART_SendString(USART1, uartBuffer);
}

6、系统初始化

// 系统初始化
void System_Init(void)
{
    // 系统时钟配置
    SystemInit();
    // 初始化外设
    USART1_Init();
    ADC_Init();
    TMR1_Init();
}

7、主函数

int main(void)
{
    // 系统初始化
    System_Init();
    // 发送启动信息
    USART_SendString(USART1, "APM32E030 ADC to USART Demo\r\n");
    USART_SendString(USART1, "ADC Channel: PA0\r\n");
    USART_SendString(USART1, "Sampling Rate: 10Hz\r\n");
    USART_SendString(USART1, "-----------------------\r\n");
    while (!ADC_ReadStatusFlag(ADC_FLAG_ADRDY))
    ADC_StartConversion();
           for (;;)
          {
       while (ADC_ReadStatusFlag(ADC_FLAG_CC) == RESET) {
              adcValue = ADC_ReadConversionValue();
                          Send_ADC_Value(adcValue);
                        
               
    }
}

}

Keil还有一点需要注意,就是浮点数,需要勾选红框内容,不然不显示。
5909468aec54f48cfc.png

过程还是这么个过程,就像上回的一样,库函数明肯定有变化,需要自己更改。
可以参考例程来看函数名。例程都是没问题的。
三、实验效果
输出两个值,码值value以及电压值voltage
value:   720   1296   1924   2514    3100    3753
voltage:0.5V    1V     1.5V    2V       2.5V    3.0V
视频:
整体来讲性能还是杠杠的,跟以前的STM32差不多。
只是这块demo没有片内DAC。还想测测DAC输出的。




天鹅绒星星 发表于 2025-8-27 17:52 | 显示全部楼层
楼主为什么采样值是 3753,采样电压就是3.3v了啊
 楼主| LiuDW091 发表于 2025-8-27 19:44 | 显示全部楼层
天鹅绒星星 发表于 2025-8-27 17:52
楼主为什么采样值是 3753,采样电压就是3.3v了啊

写错了,是3v ,3.3是4095
 楼主| LiuDW091 发表于 2025-8-27 19:45 | 显示全部楼层
天鹅绒星星 发表于 2025-8-27 17:52
楼主为什么采样值是 3753,采样电压就是3.3v了啊

笔误,已修改
您需要登录后才可以回帖 登录 | 注册

本版积分规则

25

主题

182

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部