用户工具

站点工具


icore3l_arm_10

差别

这里会显示出您选择的修订版和当前版本之间的差别。

到此差别页面的链接

两侧同时换到之前的修订记录 前一修订版
后一修订版
前一修订版
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.烧写程序进行验证
icore3l_arm_10.1606274635.txt.gz · 最后更改: 2020/11/25 11:23 由 zgf