这里会显示出您选择的修订版和当前版本之间的差别。
两侧同时换到之前的修订记录 前一修订版 后一修订版 | 前一修订版 | ||
icore3l_arm_10 [2020/11/25 11:23] zgf |
icore3l_arm_10 [2022/03/19 11:00] sean |
||
---|---|---|---|
行 2: | 行 2: | ||
|技术支持电话|**0379-69926675-801**||| | |技术支持电话|**0379-69926675-801**||| | ||
|技术支持邮件|Gingko@vip.163.com||| | |技术支持邮件|Gingko@vip.163.com||| | ||
- | |技术论坛|http://www.eeschool.org||| | ||
^ 版本 ^ 日期 ^ 作者 ^ 修改内容 ^ | ^ 版本 ^ 日期 ^ 作者 ^ 修改内容 ^ | ||
| V1.0 | 2020-11-25 | gingko | 初次建立 | | | V1.0 | 2020-11-25 | gingko | 初次建立 | | ||
行 85: | 行 84: | ||
* 满刻度误差:满度输出时对应的输入信号与理想输入信号值之差。 | * 满刻度误差:满度输出时对应的输入信号与理想输入信号值之差。 | ||
* 线性度:实际转换器的转移函数与理想直线的最大偏移。 | * 线性度:实际转换器的转移函数与理想直线的最大偏移。 | ||
+ | === 3.STM32F429 ADC介绍 === | ||
+ | * STM32F429内置有 3 个 12 位模数转换器 (ADC),每个 ADC 可共享多达 16 个外部通道,在单发或扫描模式下执行转换。在扫描模式下,将对一组选定的模拟输入执行自动转换 | ||
+ | ADC 接口内置的其它逻辑功能允许: | ||
+ | * **同步采样和保持** | ||
+ | * **交叉采样和保持** | ||
+ | * ADC 可以使用 DMA 控制器。利用模拟看门狗功能,可以非常精确地监视一路、多路或所有选定通道的转换电压。当转换电压超出编程的阈值时,将产生中断。 | ||
+ | * 为同步 A/D 转换和定时器,可由 TIM1、TIM2、TIM3、TIM4、TIM5、TIM8 定时器的任何一个触发 ADC。 | ||
+ | === 4.实验原理 === | ||
+ | STM32内部集成三个12位ADC,iCore3L的所有电源经过电阻分压或者直接接入STM32的ADC的输出通道内,输入电流经过高端电流检测芯片TP1001S3输入到ADC的输入通道内,从而实现电源监控功能。电压监控硬件连接示意图如下图所示: | ||
+ | {{ :icore3l:icore3l_arm_hal_10_1.png?direct |}} | ||
+ | 由上图可知: | ||
+ | * VCC=(1+R1/R2)*ADC_IN; | ||
+ | 故知: | ||
+ | * VCC=(1+49.9K/10K)*ADC_IN=6*ADC_IN; | ||
+ | 其它电源监控同理可得: | ||
+ | * D1V2=ADC_IN; | ||
+ | * D1V8=2*ADC_IN; | ||
+ | * D3V3=2*ADC_IN; | ||
+ | 电流监控硬件连接示意图如下图所示: | ||
+ | {{ :icore3l:icore3l_arm_hal_10_2.png?direct |}} | ||
+ | 由上图可知: | ||
+ | * ADC_IN=0.01*(VCC-LOAD)*R2; | ||
+ | 通过R1的电流: | ||
+ | * 100*ADC_IN/R2/R1; | ||
+ | 带入R2=10K,R1=0.02K: | ||
+ | * I=ADC_IN/2; | ||
+ | ==== 四、实验程序 ==== | ||
+ | 1.主函数 | ||
+ | <code c> | ||
+ | int main(void) | ||
+ | { | ||
+ | int i; | ||
+ | HAL_Init(); | ||
+ | SystemClock_Config(); | ||
+ | MX_GPIO_Init(); | ||
+ | MX_USART2_UART_Init(); | ||
+ | MX_ADC1_Init(); | ||
+ | MX_ADC3_Init(); | ||
+ | /* USER CODE BEGIN 2 */ | ||
+ | while (1) | ||
+ | { | ||
+ | if(systick._500ms_flag == 1) | ||
+ | { | ||
+ | LED_RED_ON; | ||
+ | systick._500ms_flag = 0; | ||
+ | for(i=0;i<5;i++) | ||
+ | { | ||
+ | my_adc.read(i); | ||
+ | } | ||
+ | usart1.initialize(115200); | ||
+ | usart1.printf("\x0c"); | ||
+ | usart1.printf("\033[1;32;40m"); | ||
+ | usart1.printf("Hello,I am iCore3L!\r\n\r\n"); | ||
+ | usart1.printf("[1.2V] %4.2fV,",my_adc.value[0]); //打印输入电源电压 | ||
+ | usart1.printf("[1.8V] %4.2fV,",my_adc.value[1]); | ||
+ | usart1.printf("[3.3V] %4.2fV,",my_adc.value[2]*2); | ||
+ | usart1.printf("[V] %4.2fV,",my_adc.value[3] * 6); | ||
+ | usart1.printf("[I] %3.0fmA\r\n",my_adc.value[4]/2*1000.); | ||
+ | LED_RED_OFF; | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | </code> | ||
+ | 2.ADC初始化函数 | ||
+ | <code c> | ||
+ | void MX_ADC1_Init(void) | ||
+ | { | ||
+ | ADC_ChannelConfTypeDef sConfig = {0}; | ||
+ | hadc1.Instance = ADC1; | ||
+ | hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV8; | ||
+ | hadc1.Init.Resolution = ADC_RESOLUTION_12B; //ADC转换分辨率12位 | ||
+ | hadc1.Init.ScanConvMode = DISABLE; //非扫描模式 | ||
+ | hadc1.Init.ContinuousConvMode = DISABLE; //关闭连续转换 | ||
+ | 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 = 1; | ||
+ | hadc1.Init.DMAContinuousRequests = DISABLE; | ||
+ | hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV; //关闭EOC中断 | ||
+ | if (HAL_ADC_Init(&hadc1) != HAL_OK) | ||
+ | { | ||
+ | Error_Handler(); | ||
+ | } | ||
+ | sConfig.Channel = ADC_CHANNEL_15; //通道15 | ||
+ | sConfig.Rank = 1; | ||
+ | sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES; //采样时间 | ||
+ | if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) | ||
+ | { | ||
+ | Error_Handler(); | ||
+ | } | ||
+ | } | ||
+ | void MX_ADC3_Init(void) | ||
+ | { | ||
+ | ADC_ChannelConfTypeDef sConfig = {0}; | ||
+ | hadc3.Instance = ADC3; | ||
+ | hadc3.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV8; | ||
+ | hadc3.Init.Resolution = ADC_RESOLUTION_12B; //ADC转换分辨率12位 | ||
+ | hadc3.Init.ScanConvMode = DISABLE; //非扫描模式 | ||
+ | hadc3.Init.ContinuousConvMode = DISABLE; //关闭连续转换 | ||
+ | hadc3.Init.DiscontinuousConvMode = DISABLE; //禁止不连续采样模式 | ||
+ | hadc3.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; //禁止触发检测 | ||
+ | hadc3.Init.ExternalTrigConv = ADC_SOFTWARE_START; //软件触发 | ||
+ | hadc3.Init.DataAlign = ADC_DATAALIGN_RIGHT; | ||
+ | hadc3.Init.NbrOfConversion = 1; | ||
+ | hadc3.Init.DMAContinuousRequests = DISABLE; | ||
+ | hadc3.Init.EOCSelection = ADC_EOC_SINGLE_CONV; //关闭EOC中断 | ||
+ | if(HAL_ADC_Init(&hadc3) != HAL_OK) | ||
+ | { | ||
+ | Error_Handler(); | ||
+ | } | ||
+ | sConfig.Channel = ADC_CHANNEL_6; //通道6 | ||
+ | sConfig.Rank = 1; | ||
+ | sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES; //采样时间 | ||
+ | if (HAL_ADC_ConfigChannel(&hadc3, &sConfig) != HAL_OK) | ||
+ | { | ||
+ | Error_Handler(); | ||
+ | } | ||
+ | } | ||
+ | </code> | ||
+ | 3.ADC读取函数 | ||
+ | <code c> | ||
+ | int read(int channel) | ||
+ | { | ||
+ | int i,k; | ||
+ | unsigned long int temp[20] = {0}; | ||
+ | unsigned short int data[100]; | ||
+ | ADC_ChannelConfTypeDef channel_config; | ||
+ | int channel_remap[5] = {ADC_CHANNEL_13,ADC_CHANNEL_6,ADC_CHANNEL_12,ADC_CHANNEL_7,ADC_CHANNEL_6}; | ||
+ | channel_config.Channel = channel_remap[channel]; | ||
+ | channel_config.Rank = 1; | ||
+ | channel_config.SamplingTime = ADC_SAMPLETIME_3CYCLES; | ||
+ | if(channel == 1 || channel == 3) | ||
+ | { | ||
+ | HAL_ADC_ConfigChannel(&hadc3,&channel_config); | ||
+ | } | ||
+ | else | ||
+ | { | ||
+ | HAL_ADC_ConfigChannel(&hadc1,&channel_config); | ||
+ | } | ||
+ | for(k = 0;k < 20;k ++) | ||
+ | { | ||
+ | for(i = 0;i < 100;i ++) | ||
+ | { | ||
+ | if(channel == 1 || channel == 3) | ||
+ | { | ||
+ | HAL_ADC_Start(&hadc3); | ||
+ | while(!__HAL_ADC_GET_FLAG(&hadc3,ADC_FLAG_EOC));//等待转换结束 | ||
+ | data[i] = HAL_ADC_GetValue(&hadc3); //将结果保存 | ||
+ | } | ||
+ | else | ||
+ | { | ||
+ | HAL_ADC_Start(&hadc1); | ||
+ | while(!__HAL_ADC_GET_FLAG(&hadc1,ADC_FLAG_EOC));//等待转换结束 | ||
+ | data[i] = HAL_ADC_GetValue(&hadc1); //将结果保存 | ||
+ | } | ||
+ | } | ||
+ | sort(data,100); | ||
+ | for(i = 40;i < 60;i++) | ||
+ | { | ||
+ | temp[k] += data[i]; | ||
+ | } | ||
+ | } | ||
+ | temp[k] = temp[k] / 20; | ||
+ | value = 0; | ||
+ | for(k = 0;k < 20;k ++) | ||
+ | { | ||
+ | value += temp[k]; | ||
+ | } | ||
+ | value /= 20; | ||
+ | my_adc.value[channel] = value * ADC_REF / 4096; | ||
+ | return value; | ||
+ | } | ||
+ | </code> | ||
+ | ==== 五、实验步骤 ==== | ||
+ | - 把仿真器与iCore3L的SWD调试口相连(直接相连或者通过转接器相连); | ||
+ | - 把iCore3L通过Micro USB线与计算机相连,为iCore3L供电; | ||
+ | - 打开Keil MDK 开发环境,并打开本实验工程; | ||
+ | - 烧写程序到iCore3L上; | ||
+ | - 也可以进入Debug 模式,单步运行或设置断点验证程序逻辑。 | ||
+ | ==== 六、实验现象 ==== | ||
+ | 串口一直向终端输出输入电源的数据。(关于PuTTY软件的使用,详情请看附录) | ||
+ | {{ :icore3l:icore3l_arm_hal_10_3.png?direct |}} | ||
+ | ===== 附录 ===== | ||
+ | 1.安装CH340驱动(双击安装,如果已安装忽略此步) | ||
+ | 2.iCore3L供电后,打开计算机——属性——设备管理器——端口 | ||
+ | {{ :icore3l:icore3l_arm_hal_10_4.png?direct |}} | ||
+ | 3.打开puTTY | ||
+ | {{ :icore3l:icore3l_arm_hal_10_5.png?direct |}} | ||
+ | 4.烧写程序进行验证 |