本文代码是看例程进行更改,但是例程代码本身都有错误,所以进行ADC基本操作实验讲解
注意!需要代码改串口为USART2,板子引脚改为USART2输出才能有现象!
注意!需要代码改串口为USART2,板子引脚改为USART2输出才能有现象!
注意!需要代码改串口为USART2,板子引脚改为USART2输出才能有现象!
注意!需要代码改串口为USART2,板子引脚改为USART2输出才能有现象!
注意!需要代码改串口为USART2,板子引脚改为USART2输出才能有现象!
注意!需要代码改串口为USART2,板子引脚改为USART2输出才能有现象!
注意!需要代码改串口为USART2,板子引脚改为USART2输出才能有现象!
注意!需要代码改串口为USART2,板子引脚改为USART2输出才能有现象!
错误ADC例程 https://verimake.com/d/153-ch32v307-adc
错误的地方:
1;ADC和GPIO的结构体定义错误
2:USART2引脚初始化未编程
3:传参 u8 错误
错误地方更正
最终执行更改例程后,XCOM出来的结果图如下:
未加ADC转换值的代码为
////////////////////////////////////////////////分隔符,以下为代码///////////////////////////////////////////
#include "debug.h"// 包含 CH32V307 的头文件,C 标准单元库和delay()函数
/* Global Variable /
s16 Calibrattion_Val = 0;//校准值
/*******************************************************************
函 数 名 : ADC1_Init
函数功能 : 初始化ADC
输 入 : 无
输 出 : 无
********************************************************************/
void ADC1_Init(void)
{
ADC_InitTypeDef ADC_InitStructure={0};
GPIO_InitTypeDef GPIO_InitStructure={0};
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE );
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE );
RCC_ADCCLKConfig(RCC_PCLK2_Div8); //初始化ADC时钟,设置时钟为PCLK2的8分频,最大时钟为14MHz
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOA, &GPIO_InitStructure); //配置PA1口为AD输入口
ADC_DeInit(ADC1);
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //设置AD模式为单独模式,只使用ADC1
ADC_InitStructure.ADC_ScanConvMode = DISABLE; //禁用多通道模式,启用单通道模式
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; //启动连续转换模式
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //不启用外部触发源,启动软件触发
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //数据右对齐
ADC_InitStructure.ADC_NbrOfChannel = 1; //要转换通道数量
ADC_Init(ADC1, &ADC_InitStructure);
ADC_Cmd(ADC1, ENABLE); //使能ADC
ADC_BufferCmd(ADC1, DISABLE); //disable buffer
//测量ADC校准数据,也可以不使用。
ADC_ResetCalibration(ADC1);
while(ADC_GetResetCalibrationStatus(ADC1));
ADC_StartCalibration(ADC1);
while(ADC_GetCalibrationStatus(ADC1));
Calibrattion_Val = Get_CalibrationValue(ADC1);
ADC_BufferCmd(ADC1, ENABLE); //enable buffer
}
/********************************************************************
函 数 名 : Get_ADC_Val()
函数功能 : 返回ADCx转换出的结果数据。
输 入 : 通道数
输 出 : ADCx转换出的结果数据
********************************************************************/
u16 Get_ADC_Val(u8 ch)
{
u16 val;
ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_239Cycles5 );
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));
val = ADC_GetConversionValue(ADC1);
return val;
}
void USART2_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
//开启时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
// USART2 TX-->PA2 RX-->PA3
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //RX,输入上拉
GPIO_Init(GPIOA, &GPIO_InitStructure);
USART_InitStructure.USART_BaudRate = 115200; // 波特率
USART_InitStructure.USART_WordLength = USART_WordLength_8b; // 数据位 8
USART_InitStructure.USART_StopBits = USART_StopBits_1; // 停止位 1
USART_InitStructure.USART_Parity = USART_Parity_No; // 无校验
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; // 无硬件流控
USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; //使能 RX 和 TX
USART_Init(USART2, &USART_InitStructure);
USART_Cmd(USART2, ENABLE); //开启UART
}
/********************************************************************
函 数 名 : main
函数功能 : 主函数
输 入 : 无
输 出 : 无
*********************************************************************/
int main(void)
{
u16 i;
s32 val_mv;
Delay_Init();
USART_Printf_Init(115200);
USART2_Init();
ADC1_Init();
printf("CalibrattionValue:%d\n", Calibrattion_Val); //串口打印出校准值
while(1)
{
i=Get_ADC_Val(ADC_Channel_1);
printf("%d\r\n", i); //返回ADC转换结果。
Delay_Ms(100);
}
}
////////////////////////////////////////////////分隔符///////////////////////////////////////////
其实就是加了个转换计算值而已
然后转换成例程得ADC数值结果图:
### 增加ADC转换数值的代码:
////////////////////////////////////////////////分隔符,以下为代码///////////////////////////////////////////
/**
- @file main.c
- @author xy,Benue
- @version V1.0
- @date 2022-1-19
- @brief 使用 ADC 外设产生随机值。
******************************************************************
- @attention
- VeriMake 用于CH32V307例程
******************************************************************
*/
#include "debug.h"// 包含 CH32V307 的头文件,C 标准单元库和delay()函数
/* Global Variable /
s16 Calibrattion_Val = 0;//校准值
/*******************************************************************
函 数 名 : ADC1_Init
函数功能 : 初始化ADC
输 入 : 无
输 出 : 无
********************************************************************/
void ADC1_Init(void)
{
ADC_InitTypeDef ADC_InitStructure={0};
GPIO_InitTypeDef GPIO_InitStructure={0};
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE );
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE );
RCC_ADCCLKConfig(RCC_PCLK2_Div8); //初始化ADC时钟,设置时钟为PCLK2的8分频,最大时钟为14MHz
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOA, &GPIO_InitStructure); //配置PA1口为AD输入口
ADC_DeInit(ADC1);
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //设置AD模式为单独模式,只使用ADC1
ADC_InitStructure.ADC_ScanConvMode = DISABLE; //禁用多通道模式,启用单通道模式
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; //启动连续转换模式
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //不启用外部触发源,启动软件触发
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //数据右对齐
ADC_InitStructure.ADC_NbrOfChannel = 1; //要转换通道数量
ADC_Init(ADC1, &ADC_InitStructure);
ADC_Cmd(ADC1, ENABLE); //使能ADC
ADC_BufferCmd(ADC1, DISABLE); //disable buffer
//测量ADC校准数据,也可以不使用。
ADC_ResetCalibration(ADC1);
while(ADC_GetResetCalibrationStatus(ADC1));
ADC_StartCalibration(ADC1);
while(ADC_GetCalibrationStatus(ADC1));
Calibrattion_Val = Get_CalibrationValue(ADC1);
ADC_BufferCmd(ADC1, ENABLE); //enable buffer
}
/********************************************************************
函 数 名 : Get_ADC_Val()
函数功能 : 返回ADCx转换出的结果数据。
输 入 : 通道数
输 出 : ADCx转换出的结果数据
********************************************************************/
u16 Get_ADC_Val(u8 ch)
{
u16 val;
ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_239Cycles5 );
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));
val = ADC_GetConversionValue(ADC1);
return val;
}
void USART2_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
//开启时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
/* USART2 TX-->PA2 RX-->PA3 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //RX,输入上拉
GPIO_Init(GPIOA, &GPIO_InitStructure);
USART_InitStructure.USART_BaudRate = 115200; // 波特率
USART_InitStructure.USART_WordLength = USART_WordLength_8b; // 数据位 8
USART_InitStructure.USART_StopBits = USART_StopBits_1; // 停止位 1
USART_InitStructure.USART_Parity = USART_Parity_No; // 无校验
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; // 无硬件流控
USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; //使能 RX 和 TX
USART_Init(USART2, &USART_InitStructure);
USART_Cmd(USART2, ENABLE); //开启UART
}
/********************************************************************
函 数 名 : main
函数功能 : 主函数
输 入 : 无
输 出 : 无
*********************************************************************/
int main(void)
{
u16 i;
s32 val_mv;
Delay_Init();
USART_Printf_Init(115200);
USART2_Init();
ADC1_Init();
printf("CalibrattionValue:%d\n", Calibrattion_Val); //串口打印出校准值
while(1)
{
i=Get_ADC_Val(ADC_Channel_1);
printf("%d\r\n", i); //返回ADC转换结果。
val_mv = (i*3300/4096);
printf("%d\r\n", val_mv);
Delay_Ms(100);
}
}
////////////////////////////////////////////////分隔符///////////////////////////////////////////
以上为错误的更正得出的结果:
对比官方给的例程
得出来得结果一样得
`