这里会显示出您选择的修订版和当前版本之间的差别。
两侧同时换到之前的修订记录 前一修订版 后一修订版 | 前一修订版 | ||
icore4tx_56 [2020/07/29 17:09] fmj [三、实验原理] |
icore4tx_56 [2022/04/01 11:34] sean |
||
---|---|---|---|
行 2: | 行 2: | ||
|技术支持电话|**0379-69926675-801**||| | |技术支持电话|**0379-69926675-801**||| | ||
|技术支持邮件|Gingko@vip.163.com||| | |技术支持邮件|Gingko@vip.163.com||| | ||
- | |技术论坛|http://www.eeschool.org||| | ||
^ 版本 ^ 日期 ^ 作者 ^ 修改内容 ^ | ^ 版本 ^ 日期 ^ 作者 ^ 修改内容 ^ | ||
| V1.0 | 2020-07-29 | gingko | 初次建立 | | | V1.0 | 2020-07-29 | gingko | 初次建立 | | ||
行 306: | 行 305: | ||
{{ :icore4tx:icore4tx_arm_hal_56_32.png?direct&800 |}} | {{ :icore4tx:icore4tx_arm_hal_56_32.png?direct&800 |}} | ||
{{ :icore4tx:icore4tx_arm_hal_56_33.png?direct&800 |}} | {{ :icore4tx:icore4tx_arm_hal_56_33.png?direct&800 |}} | ||
- | ==== 实验程序 ==== | + | ==== 四、实验程序 ==== |
=== 1.主函数 === | === 1.主函数 === | ||
行 315: | 行 314: | ||
int i; | int i; | ||
unsigned short int temp[10] = {0}; | unsigned short int temp[10] = {0}; | ||
- | HAL_Init(); | + | HAL_Init(); |
- | SystemClock_Config(); | + | SystemClock_Config(); |
i2c.initialize(); | i2c.initialize(); | ||
axp152.initialize(); | axp152.initialize(); | ||
行 331: | 行 330: | ||
- | MX_GPIO_Init(); | + | MX_GPIO_Init(); |
- | MX_USART1_UART_Init(); | + | MX_USART1_UART_Init(); |
- | MX_ADC1_Init(); | + | MX_ADC1_Init(); |
- | MX_ADC3_Init(); | + | MX_ADC3_Init(); |
usart1.initialize(115200); | usart1.initialize(115200); | ||
行 522: | 行 521: | ||
</code> | </code> | ||
=== 3.74HC4051通道配置 === | === 3.74HC4051通道配置 === | ||
+ | <code c> | ||
+ | //定义74HC4051片选管脚 | ||
+ | #define SEL_A_ON HAL_GPIO_WritePin(GPIOI, SEL_A_Pin, GPIO_PIN_SET) | ||
+ | #define SEL_A_OFF HAL_GPIO_WritePin(GPIOI, SEL_A_Pin, GPIO_PIN_RESET) | ||
+ | #define SEL_B_ON HAL_GPIO_WritePin(GPIOI, SEL_B_Pin, GPIO_PIN_SET) | ||
+ | #define SEL_B_OFF HAL_GPIO_WritePin(GPIOI, SEL_B_Pin, GPIO_PIN_RESET) | ||
+ | |||
+ | #define SEL_C_ON HAL_GPIO_WritePin(GPIOI, SEL_C_Pin, GPIO_PIN_SET) | ||
+ | #define SEL_C_OFF HAL_GPIO_WritePin(GPIOI, SEL_C_Pin, GPIO_PIN_RESET) | ||
+ | //选择测量BK4时片选脚状态 | ||
+ | #define CHANNEL_0_ON SEL_C_OFF;\ | ||
+ | SEL_B_OFF;\ | ||
+ | SEL_A_OFF | ||
+ | //选择测量BK3时片选脚状态 | ||
+ | #define CHANNEL_1_ON SEL_C_OFF;\ | ||
+ | SEL_B_OFF;\ | ||
+ | SEL_A_ON | ||
+ | //选择测量BK5时片选脚状态 | ||
+ | #define CHANNEL_2_ON SEL_C_OFF;\ | ||
+ | SEL_B_ON;\ | ||
+ | SEL_A_OFF | ||
+ | //选择测量2.5V时片选脚状态 | ||
+ | #define CHANNEL_3_ON SEL_C_OFF;\ | ||
+ | SEL_B_ON;\ | ||
+ | SEL_A_ON | ||
+ | //选择测量输入电流时片选脚状态 | ||
+ | #define CHANNEL_4_ON SEL_C_ON;\ | ||
+ | SEL_B_OFF;\ | ||
+ | SEL_A_OFF | ||
+ | //选择测量1.2V时片选脚状态 | ||
+ | #define CHANNEL_5_ON SEL_C_ON;\ | ||
+ | SEL_B_OFF;\ | ||
+ | SEL_A_ON | ||
+ | //选择测量3.3V时片选脚状态 | ||
+ | #define CHANNEL_6_ON SEL_C_ON;\ | ||
+ | SEL_B_ON;\ | ||
+ | SEL_A_OFF | ||
+ | //选择测量BK7时片选脚状态 | ||
+ | #define CHANNEL_7_ON SEL_C_ON;\ | ||
+ | SEL_B_ON;\ | ||
+ | SEL_A_ON | ||
+ | |||
+ | |||
+ | </code> | ||
=== 4.ADC初始化函数 === | === 4.ADC初始化函数 === | ||
+ | <code c> | ||
+ | void MX_ADC1_Init(void) | ||
+ | { | ||
+ | ADC_MultiModeTypeDef multimode = {0}; | ||
+ | ADC_ChannelConfTypeDef sConfig = {0}; | ||
+ | hadc1.Instance = ADC1; | ||
+ | hadc1.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV16; //16分频 | ||
+ | hadc1.Init.Resolution = ADC_RESOLUTION_16B; //ADC转换分辨率16位 | ||
+ | hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE; //非扫描模式 | ||
+ | hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV; //关闭 EOC 中断 | ||
+ | hadc1.Init.LowPowerAutoWait = DISABLE; //自动低功耗关闭 | ||
+ | hadc1.Init.ContinuousConvMode = DISABLE; //关闭连续转换 | ||
+ | hadc1.Init.NbrOfConversion = 1; //1个转换在规则序列中 | ||
+ | hadc1.Init.DiscontinuousConvMode = DISABLE; //禁止不连续采样模式 | ||
+ | hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START; //软件触发 | ||
+ | hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; //禁止触发检测 | ||
+ | hadc1.Init.ConversionDataManagement = ADC_CONVERSIONDATA_DR; //存到DR寄存器 | ||
+ | hadc1.Init.Overrun = ADC_OVR_DATA_PRESERVED; //溢出保留上次转换数据 | ||
+ | hadc1.Init.LeftBitShift = ADC_LEFTBITSHIFT_NONE; //位数不左移 | ||
+ | hadc1.Init.OversamplingMode = DISABLE; //关闭过采样 | ||
+ | if (HAL_ADC_Init(&hadc1) != HAL_OK) | ||
+ | { | ||
+ | Error_Handler(); | ||
+ | } | ||
+ | multimode.Mode = ADC_MODE_INDEPENDENT; //独立模式 | ||
+ | if (HAL_ADCEx_MultiModeConfigChannel(&hadc1, &multimode) != HAL_OK) | ||
+ | { | ||
+ | Error_Handler(); | ||
+ | } | ||
+ | sConfig.Channel = ADC_CHANNEL_16; //通道16 | ||
+ | sConfig.Rank = ADC_REGULAR_RANK_1; //第 1 个序列 | ||
+ | sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5; //采样时间 | ||
+ | sConfig.SingleDiff = ADC_SINGLE_ENDED; //单端输入 | ||
+ | sConfig.OffsetNumber = ADC_OFFSET_NONE; //不选择偏移序号 | ||
+ | sConfig.Offset = 0; | ||
+ | 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_ASYNC_DIV16; | ||
+ | hadc3.Init.Resolution = ADC_RESOLUTION_16B; | ||
+ | hadc3.Init.ScanConvMode = ADC_SCAN_DISABLE; | ||
+ | hadc3.Init.EOCSelection = ADC_EOC_SINGLE_CONV; | ||
+ | hadc3.Init.LowPowerAutoWait = DISABLE; | ||
+ | hadc3.Init.ContinuousConvMode = DISABLE; | ||
+ | hadc3.Init.NbrOfConversion = 1; | ||
+ | hadc3.Init.DiscontinuousConvMode = DISABLE; | ||
+ | hadc3.Init.ExternalTrigConv = ADC_SOFTWARE_START; | ||
+ | hadc3.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; | ||
+ | hadc3.Init.ConversionDataManagement = ADC_CONVERSIONDATA_DR; | ||
+ | hadc3.Init.Overrun = ADC_OVR_DATA_PRESERVED; | ||
+ | hadc3.Init.LeftBitShift = ADC_LEFTBITSHIFT_NONE; | ||
+ | hadc3.Init.OversamplingMode = DISABLE; | ||
+ | if (HAL_ADC_Init(&hadc3) != HAL_OK) | ||
+ | { | ||
+ | Error_Handler(); | ||
+ | } | ||
+ | sConfig.Channel = ADC_CHANNEL_1; | ||
+ | sConfig.Rank = ADC_REGULAR_RANK_1; | ||
+ | sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5; | ||
+ | sConfig.SingleDiff = ADC_SINGLE_ENDED; | ||
+ | sConfig.OffsetNumber = ADC_OFFSET_NONE; | ||
+ | sConfig.Offset = 0; | ||
+ | if (HAL_ADC_ConfigChannel(&hadc3, &sConfig) != HAL_OK) | ||
+ | { | ||
+ | Error_Handler(); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | |||
+ | </code> | ||
=== 5.ADC读取函数 === | === 5.ADC读取函数 === | ||
+ | <code c> | ||
+ | void sort(unsigned short int a[], int n) | ||
+ | { | ||
+ | int i, j, t; | ||
+ | | ||
+ | //元素从小到大排列 | ||
+ | for (i = 0; i < n - 1; i++) { | ||
+ | for (j = 0; j < n - i - 1; j++) { | ||
+ | if (a[j] > a[j + 1]) { | ||
+ | t = a[j]; | ||
+ | a[j] = a[j + 1]; | ||
+ | a[j + 1] = t; | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | int read(int channel) | ||
+ | { | ||
+ | int i; | ||
+ | unsigned long int temp = 0; | ||
+ | unsigned short int data[50]; | ||
+ | ADC_ChannelConfTypeDef channel_config; | ||
+ | int channel_remap[2] = {ADC_CHANNEL_16,ADC_CHANNEL_1};//ADC1,16通道 | ||
+ | | ||
+ | channel_config.Channel = channel_remap[channel]; //通道选择 | ||
+ | channel_config.Offset = 0; //偏移量为0 | ||
+ | channel_config.Rank = ADC_REGULAR_RANK_1; //第一个序列 | ||
+ | channel_config.SamplingTime = ADC_SAMPLETIME_1CYCLE_5; //采样时间 | ||
+ | channel_config.SingleDiff = ADC_SINGLE_ENDED; //单端输入 | ||
+ | channel_config.OffsetNumber = ADC_OFFSET_NONE; //不选择偏移序号 | ||
+ | | ||
+ | for(i = 0;i < 50;i ++){ | ||
+ | if(channel == 0){ //如果通道为0,则使能ADC1 | ||
+ | HAL_ADC_ConfigChannel(&hadc1,&channel_config); | ||
+ | HAL_ADC_Start(&hadc1); | ||
+ | while(!__HAL_ADC_GET_FLAG(&hadc1,ADC_FLAG_EOC)); | ||
+ | data[i] = HAL_ADC_GetValue(&hadc1); | ||
+ | }else if(channel == 1){ //如果通道为1,则使能ADC3 | ||
+ | HAL_ADC_ConfigChannel(&hadc3,&channel_config); | ||
+ | HAL_ADC_Start(&hadc3); | ||
+ | while(!__HAL_ADC_GET_FLAG(&hadc3,ADC_FLAG_EOC)); | ||
+ | data[i] = HAL_ADC_GetValue(&hadc3); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | sort(data,50); | ||
+ | for(i = 20;i < 30;i++){ //取ADC排序后的中间10位数值 | ||
+ | temp += data[i]; | ||
+ | } | ||
+ | |||
+ | temp = temp / 10; //取ADC平均值 | ||
+ | if(channel == 0){ //读取ADC1的值 | ||
+ | my_adc.value[channel] = temp * ADC_REF / 65536; | ||
+ | } | ||
+ | | ||
+ | return temp; | ||
+ | } | ||
+ | |||
+ | static int read_mux(void) | ||
+ | { //打开通道并读取ADC的值 | ||
+ | CHANNEL_0_ON; | ||
+ | my_adc.value[1] = my_adc.read(1) * ADC_REF / 65536; | ||
+ | | ||
+ | CHANNEL_1_ON; | ||
+ | my_adc.value[2] = my_adc.read(1) * ADC_REF / 65536; | ||
+ | | ||
+ | CHANNEL_2_ON; | ||
+ | my_adc.value[3] = my_adc.read(1) * ADC_REF / 65536; | ||
+ | | ||
+ | CHANNEL_3_ON; | ||
+ | my_adc.value[4] = my_adc.read(1) * ADC_REF / 65536; | ||
+ | | ||
+ | CHANNEL_4_ON; | ||
+ | my_adc.value[5] = my_adc.read(1) * ADC_REF / 65536; | ||
+ | | ||
+ | CHANNEL_5_ON; | ||
+ | my_adc.value[6] = my_adc.read(1) * ADC_REF / 65536; | ||
+ | | ||
+ | CHANNEL_6_ON; | ||
+ | my_adc.value[7] = my_adc.read(1) * ADC_REF / 65536; | ||
+ | | ||
+ | CHANNEL_7_ON; | ||
+ | my_adc.value[8] = my_adc.read(1) * ADC_REF / 65536; | ||
+ | | ||
+ | return 0; | ||
+ | } | ||
+ | |||
+ | |||
+ | </code> | ||
行 542: | 行 749: | ||
==== 六.实验现象 ==== | ==== 六.实验现象 ==== | ||
* 通过Modbus Poll软件获得iCore4TX的电源电压和温度信息。 | * 通过Modbus Poll软件获得iCore4TX的电源电压和温度信息。 | ||
- | + | {{ :icore4tx:icore4tx_arm_hal_56_34.png?direct&10000 |}} | |
行 567: | 行 774: | ||
2、打开 Modbus Poll,点击 Connection connect,输入 SN.txt 中的序列号。 | 2、打开 Modbus Poll,点击 Connection connect,输入 SN.txt 中的序列号。 | ||
- | + | {{ :icore4tx:icore4tx_arm_hal_56_35.png?direct&800 |}} | |
3、按下图进行设置,点击 OK 即可。 | 3、按下图进行设置,点击 OK 即可。 | ||
- | + | {{ :icore4tx:icore4tx_arm_hal_56_36.png?direct&600 |}} | |