1、实验环境
rt-thread 4.03
stm32f407vet6
stm3f4库版本 0.2.2
在sdk资源管理器中可以查看版本信息如下图。(小编遇见过因版本不兼容出现的编译错误问题)
2、创建rt-thread项目
此时编译结果没有错误
打开cubemx软件(不使用cubemx setting)step1:配置时钟。step2、配置adc+dma。
根据自己板子晶振确定时钟
根据adc引脚配置
配置adc1通道
配置dma
adc参数设置
生成项目
在rtt中如图文件夹下新建源文件
从cubemx生成的工程中复制如下图函数到rtt文件中;具体代码有所修改,可参考代码部分
参考代码
#include stm32f4xx_hal.h
adc_handletypedef hadc1;
dma_handletypedef hdma_adc1;
static void mx_dma_init(void)
{
/* dma controller clock enable /
__hal_rcc_dma2_clk_enable();
/ dma interrupt init /
/ dma2_stream0_irqn interrupt configuration /
hal_nvic_setpriority(dma2_stream0_irqn, 0, 0);
hal_nvic_enableirq(dma2_stream0_irqn);
}
void hal_adc_mspinit(adc_handletypedef hadc)
{
gpio_inittypedef gpio_initstruct = {0};
mx_dma_init();
if(hadc->instance==adc1)
{
/* user code begin adc1_mspinit 0 /
/ user code end adc1_mspinit 0 /
/ peripheral clock enable /
__hal_rcc_adc1_clk_enable();
__hal_rcc_gpioc_clk_enable();
__hal_rcc_gpioa_clk_enable();
/adc1 gpio configuration
pc0 ------> adc1_in10
pc1 ------> adc1_in11
pc2 ------> adc1_in12
pc3 ------> adc1_in13
pa0-wkup ------> adc1_in0
pa1 ------> adc1_in1
/
gpio_initstruct.pin = gpio_pin_0|gpio_pin_1|gpio_pin_2|gpio_pin_3;
gpio_initstruct.mode = gpio_mode_analog;
gpio_initstruct.pull = gpio_nopull;
hal_gpio_init(gpioc, &gpio_initstruct);
gpio_initstruct.pin = gpio_pin_0|gpio_pin_1;
gpio_initstruct.mode = gpio_mode_analog;
gpio_initstruct.pull = gpio_nopull;
hal_gpio_init(gpioa, &gpio_initstruct);
/ adc1 dma init /
/ adc1 init /
hdma_adc1.instance = dma2_stream0;
hdma_adc1.init.channel = dma_channel_0;
hdma_adc1.init.direction = dma_periph_to_memory;
hdma_adc1.init.periphinc = dma_pinc_disable;
hdma_adc1.init.meminc = dma_minc_enable;
hdma_adc1.init.periphdataalignment = dma_pdataalign_halfword;
hdma_adc1.init.memdataalignment = dma_mdataalign_halfword;
hdma_adc1.init.mode = dma_circular;
hdma_adc1.init.priority = dma_priority_low;
hdma_adc1.init.fifomode = dma_fifomode_disable;
hal_dma_init(&hdma_adc1);
__hal_linkdma(hadc,dma_handle,hdma_adc1);
/ user code begin adc1_mspinit 1 /
/ user code end adc1_mspinit 1 /
}
}
void mx_adc1_init(void)
{
/ user code begin adc1_init 0 /
/ user code end adc1_init 0 /
adc_channelconftypedef sconfig = {0};
/ user code begin adc1_init 1 /
/ user code end adc1_init 1 /
/ configure the global features of the adc (clock, resolution, data alignment and number of conversion)
/
hadc1.instance = adc1;
hadc1.init.clockprescaler = adc_clock_sync_pclk_div8;
hadc1.init.resolution = adc_resolution_12b;
hadc1.init.scanconvmode = enable;
hadc1.init.continuousconvmode = enable;
hadc1.init.discontinuousconvmode = disable;
hadc1.init.externaltrigconvedge = adc_externaltrigconvedge_none;
hadc1.init.externaltrigconv = adc_software_start;
hadc1.init.dataalign = adc_dataalign_right;
hadc1.init.nbrofconversion = 6;
hadc1.init.dmacontinuousrequests = enable;
hadc1.init.eocselection = adc_eoc_single_conv;
hal_adc_init(&hadc1);
/ configure for the selected adc regular channel its corresponding rank in the sequencer and its sample time.
/
sconfig.channel = adc_channel_0;
sconfig.rank = 1;
sconfig.samplingtime = adc_sampletime_3cycles;
hal_adc_configchannel(&hadc1, &sconfig);
/ configure for the selected adc regular channel its corresponding rank in the sequencer and its sample time.
/
sconfig.channel = adc_channel_1;
sconfig.rank = 2;
hal_adc_configchannel(&hadc1, &sconfig);
/ * configure for the selected adc regular channel its corresponding rank in the sequencer and its sample time.
/
sconfig.channel = adc_channel_13;
sconfig.rank = 3;
hal_adc_configchannel(&hadc1, &sconfig);
/ * configure for the selected adc regular channel its corresponding rank in the sequencer and its sample time.
/
sconfig.channel = adc_channel_12;
sconfig.rank = 4;
hal_adc_configchannel(&hadc1, &sconfig);
/ * configure for the selected adc regular channel its corresponding rank in the sequencer and its sample time.
/
sconfig.channel = adc_channel_11;
sconfig.rank = 5;
hal_adc_configchannel(&hadc1, &sconfig);
/ * configure for the selected adc regular channel its corresponding rank in the sequencer and its sample time.
/
sconfig.channel = adc_channel_10;
sconfig.rank = 6;
hal_adc_configchannel(&hadc1, &sconfig);
/ user code begin adc1_init 2 /
/ user code end adc1_init 2 /
}
void dma2_stream0_irqhandler(void)
{
/ user code begin dma2_stream0_irqn 0 /
/ user code end dma2_stream0_irqn 0 /
hal_dma_irqhandler(&hdma_adc1);
// rt_kprintf(11111111 n);
/ user code begin dma2_stream0_irqn 1 /
/ user code end dma2_stream0_irqn 1 */
}
配置rt-thread setting
编译通过,结果如下图
修改drv_adc.c文件
编译通过,结果如下图
3、添加业务测试代码
新建user_adc.c源文件添加业务测试代码如下
#include
#include
#include
rt_thread_t adc_thread1= rt_null;
#define adc_max_sample 12
#define adc_max_chanle 6
extern adc_handletypedef hadc1;
extern rt_uint16_t value[adc_max_sample][adc_max_chanle];
rt_uint16_t adc_convertedvalue[adc_max_sample][adc_max_chanle];
rt_uint16_t adc_averagevalue[adc_max_chanle];
extern adc_handletypedef hadc1;
static void caladc_average(void)
{
unsigned short i, j;
unsigned short uintmax,uintmin,i_max,i_min;
unsigned int sum;
for(i=0;iadc_convertedvalue[j][i]){
uintmin=adc_convertedvalue[j][i];
i_min = j;
}
}
adc_convertedvalue[i_max][i]=0;
adc_convertedvalue[i_min][i]=0;
sum = 0;
for(j=0; j sum += adc_convertedvalue[j][i];
}
if(i_min==i_max){
adc_averagevalue[i] = sum/(adc_max_sample-1)/11.91;
}
else {
adc_averagevalue[i] = sum/(adc_max_sample-2)/11.91;
}
}
}
static void adc_entry(void *parameter)
{
hal_adc_start_dma(&hadc1, adc_convertedvalue, (uint32_t)(adc_max_sample * adc_max_chanle));
while (1)
{
caladc_average();
rt_kprintf(/************************/n);
rt_kprintf(avg0 is :%d n,adc_averagevalue[0]);
rt_kprintf(avg1 is :%d n,adc_averagevalue[1]);
rt_kprintf(avg2 is :%d n,adc_averagevalue[2]);
rt_kprintf(avg3 is :%d n,adc_averagevalue[3]);
rt_kprintf(avg4 is :%d n,adc_averagevalue[4]);
rt_kprintf(avg5 is :%d n,adc_averagevalue[5]);
rt_thread_mdelay(500);
}
}
static int adc_deal(void)
{
rt_err_t ret = rt_eok;
/*创建第一个线程,用于采集in8的值*/
adc_thread1 = rt_thread_create(adc1,
adc_entry,
(void*)0,
512,
16,
20);
if(adc_thread1 != rt_null)
rt_thread_startup(adc_thread1);
else
ret = rt_error;
return ret;
}
init_app_export(adc_deal);
测试结果
本测试板模拟量是采集4~20ma电流。使用信号发生器输出电流信号对各个通道测试正常。下图是对chanle_10通道采集数据(12ma电流显示118。其他通道接输入信号也可以正常采集,其他通道不超过40为干扰信号,不会计入有效采集)。
掌握一些关于晶体振荡器的知识
Microchip在中国推出PIC单片机系列技术培训研讨会
台积电官宣:核准不超过1亿美元额度认购Arm股票
直流电子负载在电子电器研发中的重要性
华为发布会下午2点30闪耀登场,华为MatePadPro13.2详细参数
RTT下ADC+DMA裸机程序移植成功经验分享
精密光纤激光打标机未来的研究重点是什么
5G网络切片什么鬼?怎么实现端到端网络切片?
诺基亚8什么时候上市?最新消息:“机皇”诺基亚8八月回归,这才是真正的旗舰!
5G中高频产业技术创新发展论坛在北京顺义成功召开
iPhone8确定搭载无线充电,有理有据iPhone8无线充电器曝光
电信运营商Sunrise宣布将于3月底在瑞士推出首个5G产品
华为自研HUAWElxMotion车身协同控制系统介绍
三星显示器公司计划在牙山市A4工厂内新建一条OLED面板生产线
工地在线扬尘监测系统应该怎样选择
恩智浦半导体公司
区块链治理方案是什么样的
变压器组能不能同时运行?变压器温度该如何控制?
万用表,万用表是什么意思
Thunderbolt™ 2将如何实现4k视频分辨率