完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
电子发烧友论坛|
STM32F103 DMA采集 8路AD,AD为温度检测,10K的热敏电阻,上拉1K至3.3V, 检测到电压时,转为电阻值,通过电阻值二分查找温度,大部分情况下都没有问题,10中有一次,会出现温度错位。即通道2显示的是通过0的温度,通道4显示的是通过2的温度?代码如下:
#include "stdint.h" #include "stm32f10X_gpio.h" #include "stm32f10x_dma.h" #include "stm32f10x_adc.h" #include "temperature.h" #include "queue.h" #include "gui.h" #include "pid.h" #define ADC_SAMPLE_NUM (10) #define ADC_BUF_SIZE (ADC_SAMPLE_NUM * TEMP_CHN_NUM) #define ADC1_DR_Address ((uint32_t)0x4001244C) typedef struct { GPIO_TypeDef* temp_port; uint16_t temp_pin; uint8_t ADC_Channel; temp_grp_t group; } temp_ctrl_t; //µ±Ç°Î¶ȵÄ״̬£¬¹Ø±Õ»ò´ò¿ª static volatile temp_state_t temp_sta; //µ±Ç°É趨µÄÄ¿±êÎÂ¶È static volatile uint8_t target_temp = 60; //µ±Ç°µÄ¼ÓÈÈ×飬LOWΪ0 2 4 6¼ÓÈÈͨµÀ£¬HIGHΪ1£¬ 3 5 7¼ÓÈÈͨµÀ static volatile temp_grp_t temp_grp; //ζÈÊä³öµÄpwm volatile static int16_t heat_h[TEMP_CHN_NUM]; volatile static uint16_t pwm[GROUP_LENGTH]; static temp_ctrl_t const temp_ctrl[TEMP_CHN_NUM] = { {GPIOA, GPIO_Pin_0, ADC_Channel_0, GROUP_LOW}, {GPIOA, GPIO_Pin_1, ADC_Channel_1, GROUP_HIGH}, {GPIOA, GPIO_Pin_2, ADC_Channel_2, GROUP_LOW}, {GPIOA, GPIO_Pin_3, ADC_Channel_3, GROUP_HIGH}, {GPIOA, GPIO_Pin_4, ADC_Channel_4, GROUP_LOW}, {GPIOA, GPIO_Pin_5, ADC_Channel_5, GROUP_HIGH}, {GPIOA, GPIO_Pin_6, ADC_Channel_6, GROUP_LOW}, {GPIOA, GPIO_Pin_7, ADC_Channel_7, GROUP_HIGH} }; static volatile uint16_t ADC1ConvertedValue[ADC_SAMPLE_NUM][TEMP_CHN_NUM]; static volatile uint8_t temp_show[TEMP_CHN_NUM]; //ÈÈÃôµç×èζȱ仯ʱµÄ×èÖµ0-100¶È const uint16_t temperature[150] = { 32485, 30870, 29346, 27934, 26580, 25298, 24086, 22938, 21851, 20822, 19847, 18923, 18047, 17216, 16428, 15680, 14971, 14297, 13658, 13050, 12473, 11924, 11402, 10906, 10434, 10000, 9558, 9152, 8764, 8396, 8044, 7709, 7390, 7086, 6796, 6519, 6255, 6003, 5762, 5533, 5314, 5104, 4904, 4713, 4530, 4355, 4187, 4027, 3874, 3728, 3588, 3454, 3326, 3203, 3086, 2973, 2865, 2762, 2662, 2567, 2476, 2389, 2305, 2224, 2147, 2072, 2001, 1933, 1867, 1803, 1743, 1684, 1628, 1574, 1522, 1470, 1424, 1378, 1333, 1290, 1249, 1209, 1171, 1134, 1099, 1064, 1031, 999, 968, 935, 907, 879, 854, 828, 804, 780, 757, 736, 714, 694, 674, 655, 636, 619, 601, 584, 568, 553, 538, 523, 509, 495, 482, 469, 457, 445, 433, 421, 410, 400, 390, 380, 370, 361, 352, 343, 335, 326, 318, 310, 303, 295, 291, 284, 277, 270, 264, 257, 251, 245, 239, 233, 228, 223, 217, 212, 208, 203, 198, 194 }; //ÉèÖôò¿ª»ò¹Ø±Õ¼ÓÈÈÄ£¿é void set_temp_state(volatile temp_state_t state) { temp_sta = state; } temp_state_t get_temp_state(void) { return temp_sta; } //ÉèÖüÓÈÈ×é void set_temp_group(temp_grp_t grp) { temp_grp = grp; } temp_grp_t get_temp_group(void) { return temp_grp; } /* ÃèÊö£º¸ù¾Ýµç×èÖµ£¬²éÕÒÏàÓ¦µÄζ res: Ϊµç×èÖµ rvl: ·µ»ØÏàÓ¦µÄÎÂ¶È */ static int search_temperature(uint16_t res) { uint8_t start = 0, end = 149; uint8_t tmp; if ((res > temperature[start]) || (res < temperature[end])) return -1; while ((start + 1) < end) { tmp = (end + start) / 2; if (temperature[tmp] == res) return tmp; if (temperature[tmp] > res) { start = tmp; } else { end = tmp; } } return start; } static void GPIO_Configuration(void) { GPIO_InitTypeDef GPIO_InitStructure; uint8_t i; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE); for (i = 0; i < TEMP_CHN_NUM; i++) { GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; GPIO_InitStructure.GPIO_Pin = temp_ctrl[i].temp_pin; GPIO_Init(temp_ctrl[i].temp_port, GPIO_InitStructure); } } static void dma_init() { /* DMA1 channel1 configuration ----------------------------------------------*/ DMA_InitTypeDef DMA_InitStructure; DMA_DeInit(DMA1_Channel1); RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address; DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)ADC1ConvertedValue; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; DMA_InitStructure.DMA_BufferSize = ADC_BUF_SIZE; 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_High; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_Init(DMA1_Channel1, DMA_InitStructure); //DMA_ITConfig(DMA1_Channel1, DMA_IT_TC, ENABLE); } static void adc_init() { uint8_t i; /* ADC1 configuration ------------------------------------------------------*/ ADC_InitTypeDef ADC_InitStructure; RCC_ADCCLKConfig(RCC_PCLK2_Div6); RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_ADC2, ENABLE); ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; if (1 == TEMP_CHN_NUM) ADC_InitStructure.ADC_ScanConvMode = DISABLE; else 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 = TEMP_CHN_NUM; ADC_Init(ADC1, ADC_InitStructure); /* ADC1 regular channels configuration */ for (i = 0; i < TEMP_CHN_NUM; i++) ADC_RegularChannelConfig(ADC1, temp_ctrl[i].ADC_Channel, i + 1, ADC_SampleTime_41Cycles5); ADC_DMACmd(ADC1, ENABLE); /* Enable ADC1 */ ADC_Cmd(ADC1, ENABLE); /* Enable ADC1 reset calibration register */ ADC_ResetCalibration(ADC1); /* Check the end of ADC1 reset calibration register */ while(ADC_GetResetCalibrationStatus(ADC1)); /* Start ADC1 calibration */ ADC_StartCalibration(ADC1); /* Check the end of ADC1 calibration */ while(ADC_GetCalibrationStatus(ADC1)); /* Enable DMA1 channel1 */ DMA_Cmd(DMA1_Channel1, ENABLE); ADC_SoftwareStartConvCmd(ADC1, ENABLE); } #define PTC //¿ªÆô»ò¹Ø±Õζȼì²â void calc_temp(void) { uint8_t i, j; uint16_t temp_sum[TEMP_CHN_NUM]; uint16_t v_avg, resistance; int8_t error; static int16_t sum_err = 0; //°ÑÇóÖµµÄÊý×é³õʼΪ0 for (i = 0; i < TEMP_CHN_NUM; i++) temp_sum[i] = 0; //Çó³ö10´ÎµçѹµÄºÍÖµ for (i = 0; i < ADC_SAMPLE_NUM; i++) { for (j = 0; j < TEMP_CHN_NUM; j++) { temp_sum[j] += ADC1ConvertedValue[i][j]; } } //ÓɵçѹµÄºÍÖµÇó³öζÈÖµ for (i = 0; i < TEMP_CHN_NUM; i++) { v_avg = temp_sum[i] * 330 / 4095; //ƽ¾ùÖµÀ©´ó1000±¶ resistance = (1000 * v_avg) / (3300 - v_avg); temp_show[i] = search_temperature(resistance); //ÓÉζÈÖµÇó³ö¶ÔÓ¦µÄPWMÖµ error = target_temp - temp_show[i]; if (error < 0 ) { heat_h[i] = 0; sum_err += error; } else if (error < 8){ #ifdef PTC heat_h[i] = error * 100; #else sum_err += error; sum_err *= 5; sum_err = sum_err > 999 ? 999 : sum_err; heat_h[i] = (error * 90);// + sum_err; heat_h[i] = heat_h[i] > 999 ? 999 : heat_h[i]; #endif } else { heat_h[i] = 999; } } if (GROUP_LOW == get_temp_group()) { pwm[0] = heat_h[0]; pwm[1] = heat_h[2]; pwm[2] = heat_h[4]; pwm[3] = heat_h[6]; } else { pwm[0] = heat_h[1]; pwm[1] = heat_h[3]; pwm[2] = heat_h[5]; pwm[3] = heat_h[7]; } } void set_temp(uint8_t temperature) { target_temp = temperature; } void temperature_init(void) { GPIO_Configuration(); dma_init(); adc_init(); set_temp_state(TEMP_CLOSE); set_temp_group(GROUP_LOW); } /* void DMA1_Channel1_IRQHandler(void) { uint8_t i, j; uint16_t temp_sum[TEMP_CHN_NUM]; uint16_t v_avg, resistance; int8_t error; if(DMA_GetITStatus(DMA1_IT_TC1) != RESET) { //°ÑÇóÖµµÄÊý×é³õʼΪ0 for (i = 0; i < TEMP_CHN_NUM; i++) temp_sum[i] = 0; //Çó³ö10´ÎµçѹµÄºÍÖµ for (i = 0; i < ADC_SAMPLE_NUM; i++) { for (j = 0; j < TEMP_CHN_NUM; j++) { temp_sum[j] += ADC1ConvertedValue[i][j]; } } //ÓɵçѹµÄºÍÖµÇó³öζÈÖµ for (i = 0; i < TEMP_CHN_NUM; i++) { v_avg = temp_sum[i] * 330 / 4095; //ƽ¾ùÖµÀ©´ó1000±¶ resistance = (1000 * v_avg) / (3300 - v_avg); temp_show[i] = search_temperature(resistance); //ÓÉζÈÖµÇó³ö¶ÔÓ¦µÄPWMÖµ error = target_temp - temperature[i]; if (error < 0 ) { heat_h[i] = 0; } else if (error < 8){ heat_h[i] = error * 88; } else { heat_h[i] = 999; } } DMA_ClearITPendingBit(DMA1_IT_GL1); } } */ #define TEMP_LOW 0X54 #define TEMP_HIGH 0X55 //ÏòÉÏλ»ú´«ËÍ£¬¼ì²âµ½µÄζÈÖµ£¬¹²ÓÐ4· void do_send_temp(void) { msg_t msg; msg.text[0] = START1; msg.text[1] = START2; if (GROUP_LOW == get_temp_group()) { msg.text[2] = TEMP_LOW; msg.text[3] = temp_show[0]; msg.text[4] = temp_show[2]; msg.text[5] = temp_show[4]; msg.text[6] = temp_show[6]; } else if (GROUP_HIGH == get_temp_group()){ msg.text[2] = TEMP_HIGH; msg.text[3] = temp_show[1]; msg.text[4] = temp_show[3]; msg.text[5] = temp_show[5]; msg.text[6] = temp_show[7]; } put_msg(msg); } void heat_output(volatile uint16_t cnt) { uint8_t i; if (TEMP_CLOSE == get_temp_state()) { heat_all_off(); return; } for (i = 0; i < GROUP_LENGTH; i++) { if (cnt < pwm[i]) { heat_on(get_temp_group(), i); } else { heat_off(get_temp_group(), i); } } } #include "stdint.h" #include "systick.h" #include "soft_timer.h" #include "queue.h" #include "temperature.h" #include "speaker.h" #include "gui.h" static volatile uint32_t time_delay; static volatile uint16_t sec; static volatile uint16_t time_int; void SysTick_Handler(void) { static uint16_t systick_cnt = 0; volatile sig_t sig; if (time_delay != 0x00) { time_delay--; } spk_beep(); if (999 == systick_cnt) { systick_cnt = 0; if (sec != 0x00) { sec--; } calc_temp(); do_send_temp(); if (SOFT_TIMER_RUN == get_softtimer_state()) { if (0 != get_softtimer_time()) { softtimer_process(); sig = SIG_TIME_SEC_INT; put_sig(sig); } else { softtimer_stop(); sig = SIG_TIME_END; put_sig(sig); } } } else { systick_cnt++; heat_output(systick_cnt); } } void set_sec(uint16_t s) { sec = s; } uint16_t get_sec(void) { return sec; } void delay_ms(uint16_t ms) { time_delay = ms; while (time_delay != 0); } |
|
相关推荐
1个回答
|
|
|
STM32 DMA采集数据出现乱码的原因可能有以下几点:
1. DMA配置错误:请确保DMA的配置正确,包括通道选择、源地址、目标地址、数据宽度、传输方向等。 2. ADC配置错误:请检查ADC的配置,包括时钟源、分辨率、采样时间、触发方式等。 3. 通道冲突:如果多个通道共享同一ADC,可能会出现通道冲突。请确保在采集过程中,没有其他通道同时进行采集。 4. 中断优先级设置不当:如果DMA和ADC共用中断,可能会导致优先级冲突。请检查中断优先级设置,确保DMA中断优先级高于ADC中断。 5. 软件问题:请检查代码中是否存在逻辑错误,例如数组越界、错误的数据类型转换等。 6. 硬件问题:请检查硬件连接是否正确,包括热敏电阻、上拉电阻、模拟输入引脚等。 7. 电磁干扰:电磁干扰可能导致ADC采集到错误的数据。请检查电路板的布线,尽量避免长距离走线和靠近高电流或高速信号的走线。 8. 电源稳定性:不稳定的电源可能会影响ADC的性能。请确保电源稳定,可以考虑使用线性稳压器或开关稳压器。 9. 温度变化过快:如果温度变化过快,可能导致ADC采集到不稳定的数据。请确保温度变化在一个合理的范围内。 10. 软件滤波:如果问题仍然存在,可以考虑在软件中实现滤波算法,例如平均滤波、中值滤波等,以提高数据的稳定性。 建议您根据以上可能的原因逐一排查,找到问题所在并进行修复。 |
|
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
4209 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
3263 浏览 1 评论
2796 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
2228 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
15172 浏览 2 评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
3169浏览 4评论
stm32f4下spi+dma读取数据不对是什么原因导致的?
1943浏览 3评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
2110浏览 3评论
2020浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
2218浏览 3评论
/9
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2025-12-14 19:02 , Processed in 0.454383 second(s), Total 41, Slave 34 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191

淘帖
1108