最近在做一个项目,用到的主控芯片是沁恒微的WCH32v003,其中一个功能是多通道采集ADC+DMA运输,在编写代码的时候想找官方的库函数文件,但是找了很久都没有找到,官网只有一个数据手册和应用手册,而应用手册一般是分为库函数应用手册和寄存器应用手册,但是官网上的应用手册是只有寄存器的,而官方的库又用了大量的封装,所以看起来特别的痛苦,于是我结合网上的资料和自己的理解,总结处理一个关于ADC采集的库函数介绍,希望可以帮助到大家。
1.1、void ADC_DeInit(ADC_TypeDef* ADCx)
功 能:将ADCx外围寄存器初始化为其默认重置值。
输 入:ADCx:其中x可以是1以选择ADC外围设备。
1.2、void ADC_Init(ADC_TypeDef* ADCx, ADC_InitTypeDef* ADC_InitStruct)
功 能:根据ADC_InitStruct中指定的参数初始化ADCx外围设备。
输 入:ADCx:其中x可以是1以选择ADC外围设备;ADC_InitStruct:指向包含指定ADC外围设备的配置信息的ADC_InitTypeDef结构的指针。
1.3、void ADC_StructInit(ADC_InitTypeDef* ADC_InitStruct)
功 能:用默认值填充每个ADC_InitStruct成员。
输 入:ADC_InitStruct:指向包含指定ADC外围设备的配置信息的ADC_InitTypeDef结构的指针。
1.4、void ADC_Cmd(ADC_TypeDef* ADCx, FunctionalState NewState)
功 能:启用或禁用指定的ADC外围设备。
输 入:ADCx:其中x可以是1以选择ADC外围设备;NewState:启用或禁用。
1.5、void ADC_DMACmd(ADC_TypeDef* ADCx, FunctionalState NewState)
功 能:启用或禁用指定的ADC DMA请求。
输 入:ADCx:其中x可以是1以选择ADC外围设备;NewState:启用或禁用。
1.6、void ADC_ITConfig(ADC_TypeDef* ADCx, uint16_t ADC_IT, FunctionalState NewState)
功 能:启用或禁用指定的ADC中断。
输 入:ADCx:其中x可以是1以选择ADC外围设备;ADC_IT:指定要启用或禁用的ADC中断源。NewState:启用或禁用。
1.7、void ADC_ResetCalibration(ADC_TypeDef* ADCx)
功 能:重置所选ADC校准寄存器。
输 入:ADCx:其中x可以是1以选择ADC外围设备。
1.8、FlagStatus ADC_GetResetCalibrationStatus(ADC_TypeDef* ADCx)
功 能:获取所选ADC重置校准寄存器状态。
输 入:ADCx:其中x可以是1以选择ADC外围设备。
1.9、void ADC_StartCalibration(ADC_TypeDef* ADCx)
功 能:启动所选ADC校准过程。
输 入:ADCx:其中x可以是1以选择ADC外围设备。
1.10、FlagStatus ADC_GetCalibrationStatus(ADC_TypeDef* ADCx)
功 能:获取所选ADC校准状态。
输 入:ADCx:其中x可以是1以选择ADC外围设备。
1.11、void ADC_SoftwareStartConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState)
功 能:启用或禁用所选ADC软件启动转换。
输 入:ADCx:其中x可以是1以选择ADC外围设备;NewState:启用或禁用。
1.12、FlagStatus ADC_GetSoftwareStartConvStatus(ADC_TypeDef* ADCx)
功 能:获取所选ADC软件开始转换状态。
输 入:ADCx:其中x可以是1以选择ADC外围设备。
1.13、void ADC_DiscModeChannelCountConfig(ADC_TypeDef* ADCx, uint8_t Number)
功 能:为所选ADC常规组通道配置不连续模式。
输 入:ADCx:其中x可以是1以选择ADC外围设备;Number:指定不连续模式常规通道计数值。
1.14、void ADC_DiscModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState)
功 能:为指定的ADC启用或禁用常规组通道上的不连续模式。
输 入:ADCx:其中x可以是1以选择ADC外围设备;NewState:启用或禁用。
1.15、void ADC_RegularChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime)
功 能:为所选ADC常规通道配置其在序列器中的相应列组及其采样时间。
输 入:ADCx:其中x可以是1以选择ADC外围设备;ADC_Channel:要配置的ADC信道;Rank:常规组序列器中的等级;ADC_SampleTime:要为所选通道设置的采样时间值。
1.16、void ADC_ExternalTrigConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState)
功 能:通过外部触发器启用或禁用ADCx转换。
输 入:ADCx:其中x可以是1以选择ADC外围设备;NewState:启用或禁用。
1.17、uint16_t ADC_GetConversionValue(ADC_TypeDef* ADCx)
功 能:返回常规通道的最后一个ADCx转换结果数据。
输 入:ADCx:其中x可以是1以选择ADC外围设备。
1.18、uint32_t ADC_GetDualModeConversionValue(void)
功 能:以双模式返回最后一个ADC1和ADC2转换结果数据。
输 入:无。
1.19、void ADC_AutoInjectedConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState)
功 能:启用或禁用所选ADC在常规转换后自动注入组转换。
输 入:ADCx:其中x可以是1以选择ADC外围设备;NewState:启用或禁用。
1.20、void ADC_InjectedDiscModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState)
功 能:为指定的ADC启用或禁用注入组通道的不连续模式。
输 入:ADCx:其中x可以是1以选择ADC外围设备;NewState:启用或禁用。
1.21、void ADC_ExternalTrigInjectedConvConfig(ADC_TypeDef* ADCx, uint32_t ADC_ExternalTrigInjecConv)
功 能:为注入通道转换配置ADCx外部触发器。
输 入:ADCx:其中x可以是1以选择ADC外围设备;ADC_ExternalTrigInjecConv:指定开始注入转换的ADC触发器。
1.22、void ADC_ExternalTrigInjectedConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState)
功 能:通过外部触发器启用或禁用ADCx注入通道转换。
输 入:ADCx:其中x可以是1以选择ADC外围设备;NewState:启用或禁用。
1.23、void ADC_SoftwareStartInjectedConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState)
功 能:启用或禁用注入通道转换的所选ADC启动。
输 入:ADCx:其中x可以是1以选择ADC外围设备;NewState:启用或禁用。
1.24、FlagStatus ADC_GetSoftwareStartInjectedConvCmdStatus(ADC_TypeDef* ADCx)
功 能:获取所选ADC软件开始注入转换状态。
输 入:ADCx:其中x可以是1以选择ADC外围设备。
1.25、void ADC_InjectedChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime)
功 能:为所选ADC注入通道配置其在序列器中的相应秩及其采样时间。
输 入:ADCx:其中x可以是1以选择ADC外围设备;ADC_Channel:要配置的ADC信道;Rank:注入组序列器中的秩;ADC_SampleTime:要为所选通道设置的采样时间值。
1.26、void ADC_InjectedSequencerLengthConfig(ADC_TypeDef* ADCx, uint8_t Length)
功 能:配置注入通道的序列器长度。
输 入:ADCx:其中x可以是1以选择ADC外围设备;Length:序列器的长度。
1.27、void ADC_SetInjectedOffset(ADC_TypeDef* ADCx, uint8_t ADC_InjectedChannel, uint16_t Offset)
功 能:设置注入通道转换值偏移。
输 入:ADCx:其中x可以是1以选择ADC外围设备;Offset:所选ADC注入通道的偏移值。
1.28、uint16_t ADC_GetInjectedConversionValue(ADC_TypeDef* ADCx, uint8_t ADC_InjectedChannel)
功 能:ADC返回注入通道的结果。
输 入:ADCx:其中x可以是1以选择ADC外围设备;ADC_InjectedChannel:转换后的ADC注入通道。
1.29、void ADC_AnalogWatchdogCmd(ADC_TypeDef* ADCx, uint32_t ADC_AnalogWatchdog)
功 能:启用或禁用单个/所有常规或注入通道上的模拟看门狗。
输 入:ADCx:其中x可以是1以选择ADC外围设备;ADC_AnalogWatchdog:ADC模拟看门狗配置。
1.30、void ADC_AnalogWatchdogThresholdsConfig(ADC_TypeDef* ADCx, uint16_t HighThreshold,uint16_t LowThreshold)
功 能:配置模拟看门狗的高阈值和低阈值。
输 入:ADCx:其中x可以是1以选择ADC外围设备;HighThreshold:ADC模拟看门狗高阈值;LowThreshold:ADC模拟看门狗低阈值。
1.31、void ADC_AnalogWatchdogSingleChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel)
功 能:配置模拟看门狗保护的单通道。
输 入:ADCx:其中x可以是1以选择ADC外围设备;ADC_Channel:为模拟看门狗配置的ADC信道。
1.32、void ADC_TempSensorVrefintCmd(FunctionalState NewState)
功 能:启用或禁用温度传感器和Vrefint通道。
输 入:NewState:启用或禁用。
1.33、FlagStatus ADC_GetFlagStatus(ADC_TypeDef* ADCx, uint8_t ADC_FLAG)
功 能:检查是否设置了指定的ADC标志。
输 入:ADCx:其中x可以是1以选择ADC外围设备;ADC_FLAG:指定要检查的标志。
1.34、void ADC_ClearFlag(ADC_TypeDef* ADCx, uint8_t ADC_FLAG)
功 能:清除ADCx的挂起标志。
输 入:ADCx:其中x可以是1以选择ADC外围设备;ADC_FLAG:指定要清除的标志。
1.35、ITStatus ADC_GetITStatus(ADC_TypeDef* ADCx, uint16_t ADC_IT)
功 能:检查指定的ADC中断是否已发生。
输 入:ADCx:其中x可以是1以选择ADC外围设备;ADC_IT:指定要检查的ADC中断源。
1.36、void ADC_ClearITPendingBit(ADC_TypeDef* ADCx, uint16_t ADC_IT)
功 能:清除ADCx的中断挂起位。
输 入:ADCx:其中x可以是1以选择ADC外围设备;ADC_IT:指定要清除的ADC中断挂起位。
1.37、s32 TempSensor_Volt_To_Temper(s32 Value)
功 能:内部温度传感器电压与温度之间的关系。
输 入:Value:电压值。
这里是参考wch32v103的,基本上都是一样的,原文地址:十、CH32V103应用教程——ADC - RISC-V技术及应用论坛,开源指令集架构(ISA)论坛 - 21ic电子技术开发论坛
下面的代码部分,是可以直接使用的,具体就不做过多介绍了,对照这上面的库函数介绍都很容易理解。我的代码是3通道采集,大家可以根据自己的实际需求更改。下面是不同封装的引脚定义。
main.c
#include "debug.h" /* Global Variable */ u16 TxBuf[10]; /********************************************************************* * @fn ADC_Function_Init * * @brief Initializes ADC collection. * * @return none */ void ADC_Function_Init(void) { ADC_InitTypeDef ADC_InitStructure = {0}; GPIO_InitTypeDef GPIO_InitStructure = {0}; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); RCC_ADCCLKConfig(RCC_PCLK2_Div8); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; GPIO_Init(GPIOC, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; GPIO_Init(GPIOD, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; GPIO_Init(GPIOD, &GPIO_InitStructure); ADC_DeInit(ADC1); ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; ADC_InitStructure.ADC_ScanConvMode = ENABLE; ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_NbrOfChannel = 3; ADC_Init(ADC1, &ADC_InitStructure); ADC_Calibration_Vol(ADC1, ADC_CALVOL_50PERCENT); ADC_DMACmd(ADC1, ENABLE); ADC_Cmd(ADC1, ENABLE); ADC_ResetCalibration(ADC1); while(ADC_GetResetCalibrationStatus(ADC1)); ADC_StartCalibration(ADC1); while(ADC_GetCalibrationStatus(ADC1)); } /********************************************************************* * @fn Get_ADC_Val * * @brief Returns ADCx conversion result data. * * @param ch - ADC channel. * ADC_Channel_0 - ADC Channel0 selected. * ADC_Channel_1 - ADC Channel1 selected. * ADC_Channel_2 - ADC Channel2 selected. * ADC_Channel_3 - ADC Channel3 selected. * ADC_Channel_4 - ADC Channel4 selected. * ADC_Channel_5 - ADC Channel5 selected. * ADC_Channel_6 - ADC Channel6 selected. * ADC_Channel_7 - ADC Channel7 selected. * ADC_Channel_8 - ADC Channel8 selected. * ADC_Channel_9 - ADC Channel9 selected. * * @return none */ u16 Get_ADC_Val(u8 ch) { u16 val; ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_241Cycles); ADC_SoftwareStartConvCmd(ADC1, ENABLE); while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC)); val = ADC_GetConversionValue(ADC1); return val; } /********************************************************************* * @fn DMA_Tx_Init * * @brief Initializes the DMAy Channelx configuration. * * @param DMA_CHx - x can be 1 to 7. * ppadr - Peripheral base address. * memadr - Memory base address. * bufsize - DMA channel buffer size. * * @return none */ void DMA_Tx_Init(DMA_Channel_TypeDef *DMA_CHx, u32 ppadr, u32 memadr, u16 bufsize) { DMA_InitTypeDef DMA_InitStructure = {0}; RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); DMA_DeInit(DMA_CHx); DMA_InitStructure.DMA_PeripheralBaseAddr = ppadr; DMA_InitStructure.DMA_MemoryBaseAddr = memadr; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; DMA_InitStructure.DMA_BufferSize = bufsize; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_Init(DMA_CHx, &DMA_InitStructure); } /********************************************************************* * @fn main * * @brief Main program. * * @return none */ int main(void) { u16 i; SystemCoreClockUpdate(); Delay_Init(); #if (SDI_PRINT == SDI_PR_OPEN) SDI_Printf_Enable(); #else USART_Printf_Init(115200); #endif printf("SystemClk:%d\r\n", SystemCoreClock); printf( "ChipID:%08x\r\n", DBGMCU_GetCHIPID() ); ADC_Function_Init(); DMA_Tx_Init(DMA1_Channel1, (u32)&ADC1->RDATAR, (u32)TxBuf,3); while(1) { ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 1, ADC_SampleTime_241Cycles); ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 2, ADC_SampleTime_241Cycles); ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 3, ADC_SampleTime_241Cycles); DMA_Cmd(DMA1_Channel1, ENABLE); ADC_SoftwareStartConvCmd(ADC1, ENABLE); Delay_Ms(5); ADC_SoftwareStartConvCmd(ADC1, DISABLE); DMA_Cmd(DMA1_Channel1, DISABLE); for(i = 0; i < 3; i++) { printf("%04d\r\n", TxBuf[i]); Delay_Ms(10); } Delay_Ms(50); } }
我最近建了一个嵌入式的QQ交流群,感兴趣的可以进群了解一下,我会在群里分享一些常用的代码封装,以及一些项目的源码。QQ群讨论也是完全开放,只要不打广告大家可以就嵌入式尽情的沟通和交流,大家对文章中的内容有疑问也可以在群中提出,有空会尽我所能给大家一些帮助。QQ群号:643408467
文章浏览阅读2w次,点赞7次,收藏51次。四个步骤1.创建C++ Win32项目动态库dll 2.在Win32项目动态库中添加 外部依赖项 lib头文件和lib库3.导出C接口4.c#调用c++动态库开始你的表演...①创建一个空白的解决方案,在解决方案中添加 Visual C++ , Win32 项目空白解决方案的创建:添加Visual C++ , Win32 项目这......_c#调用lib
文章浏览阅读4.6k次。苹方字体是苹果系统上的黑体,挺好看的。注重颜值的网站都会使用,例如知乎:font-family: -apple-system, BlinkMacSystemFont, Helvetica Neue, PingFang SC, Microsoft YaHei, Source Han Sans SC, Noto Sans CJK SC, W..._ubuntu pingfang
文章浏览阅读159次。表单表单概述表单标签表单域按钮控件demo表单标签表单标签基本语法结构<form action="处理数据程序的url地址“ method=”get|post“ name="表单名称”></form><!--action,当提交表单时,向何处发送表单中的数据,地址可以是相对地址也可以是绝对地址--><!--method将表单中的数据传送给服务器处理,get方式直接显示在url地址中,数据可以被缓存,且长度有限制;而post方式数据隐藏传输,_html表单的处理程序有那些
文章浏览阅读1.2k次。使用说明:开启Google的登陆二步验证(即Google Authenticator服务)后用户登陆时需要输入额外由手机客户端生成的一次性密码。实现Google Authenticator功能需要服务器端和客户端的支持。服务器端负责密钥的生成、验证一次性密码是否正确。客户端记录密钥后生成一次性密码。下载谷歌验证类库文件放到项目合适位置(我这边放在项目Vender下面)https://github.com/PHPGangsta/GoogleAuthenticatorPHP代码示例://引入谷_php otp 验证器
文章浏览阅读4.3k次,点赞5次,收藏11次。matplotlib.plot画图横坐标混乱及间隔处理_matplotlib更改横轴间距
文章浏览阅读2.2k次。①Storage driver 处理各镜像层及容器层的处理细节,实现了多层数据的堆叠,为用户 提供了多层数据合并后的统一视图②所有 Storage driver 都使用可堆叠图像层和写时复制(CoW)策略③docker info 命令可查看当系统上的 storage driver主要用于测试目的,不建议用于生成环境。_docker 保存容器
文章浏览阅读834次,点赞27次,收藏13次。网络拓扑结构是指计算机网络中各组件(如计算机、服务器、打印机、路由器、交换机等设备)及其连接线路在物理布局或逻辑构型上的排列形式。这种布局不仅描述了设备间的实际物理连接方式,也决定了数据在网络中流动的路径和方式。不同的网络拓扑结构影响着网络的性能、可靠性、可扩展性及管理维护的难易程度。_网络拓扑csdn
文章浏览阅读1.8k次,点赞5次,收藏8次。IOS系统Date的坑要创建一个指定时间的new Date对象时,通常的做法是:new Date("2020-09-21 11:11:00")这行代码在 PC 端和安卓端都是正常的,而在 iOS 端则会提示 Invalid Date 无效日期。在IOS年月日中间的横岗许换成斜杠,也就是new Date("2020/09/21 11:11:00")通常为了兼容IOS的这个坑,需要做一些额外的特殊处理,笔者在开发的时候经常会忘了兼容IOS系统。所以就想试着重写Date函数,一劳永逸,避免每次ne_date.prototype 将所有 ios
文章浏览阅读5.3k次。方法一:用PLSQL Developer工具。 1 在PLSQL Developer的sql window里输入select * from test for update; 2 按F8执行 3 打开锁, 再按一下加号. 鼠标点到第一列的列头,使全列成选中状态,然后粘贴,最后commit提交即可。(前提..._excel导入pl/sql
文章浏览阅读83次。Git常用命令速查手册1、初始化仓库git init2、将文件添加到仓库git add 文件名 # 将工作区的某个文件添加到暂存区 git add -u # 添加所有被tracked文件中被修改或删除的文件信息到暂存区,不处理untracked的文件git add -A # 添加所有被tracked文件中被修改或删除的文件信息到暂存区,包括untracked的文件...
文章浏览阅读202次。分享119个ASP.NET源码总有一个是你想要的_千博二手车源码v2023 build 1120
文章浏览阅读1.8k次。版权声明:转载请注明出处 http://blog.csdn.net/irean_lau。目录(?)[+]1、缺省构造函数。2、缺省拷贝构造函数。3、 缺省析构函数。4、缺省赋值运算符。5、缺省取址运算符。6、 缺省取址运算符 const。[cpp] view plain copy_空类默认产生哪些类成员函数