本帖最后由 LiuDW091 于 2025-8-27 19:44 编辑
本次实验通过USART1串口打印ADC采集的数据(TMR1触发)。
串口USART1:RX----PA10、TX----PA9
ADC采集口:ADC_IN0------PA0
一、硬件原理图以及硬件连接
二、代码
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还有一点需要注意,就是浮点数,需要勾选红框内容,不然不显示。
过程还是这么个过程,就像上回的一样,库函数明肯定有变化,需要自己更改。
可以参考例程来看函数名。例程都是没问题的。
三、实验效果
输出两个值,码值value以及电压值voltage
value: 720 1296 1924 2514 3100 3753
voltage:0.5V 1V 1.5V 2V 2.5V 3.0V
视频:
整体来讲性能还是杠杠的,跟以前的STM32差不多。
只是这块demo没有片内DAC。还想测测DAC输出的。
|