资深版主
- 积分
- 4306
- 金钱
- 4306
- 注册时间
- 2018-6-30
- 在线时间
- 808 小时
|
本帖最后由 1208 于 2019-12-10 19:58 编辑
本程序可以串口显示和屏幕显示四路
1.阿波罗F767:板子四路ADC+除法运算2.zip:用的是ADC1,输入通道是PA0,PA5,PA6,PA7
2.阿波罗F767:板子四路ADC+DMA.zip:用的是ADC1,输入通道是PA5,PA6,PA7,PC4
3.阿波罗F767:板子四路ADC1.zip:用的是ADC1,输入通道是PA0,PA5,PA6,PA7
1)dma.c
DMA传输采用的是从外设到内存,
内存:ADC_ConvertedValueRead
外设:ADC>DR寄存器
在HAL_ADC_Start_DMA(&ADC1_Handler,&ADC_ConvertedValue[0],4);有对应的ADC>DR寄存器
HAL_StatusTypeDef HAL_DMA_Start_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
DMA 数据流 x 外设地址寄存器 (DMA_SxPAR)
- extern uint32_t ADC_ConvertedValueRead[4];
- //DMA_HandleTypeDef UART1TxDMA_Handler; //DMA句柄
- DMA_HandleTypeDef ADC1TxDMA_Handler; //DMA句柄
- //DMAx的各通道配置
- //这里的传输形式是固定的,这点要根据不同的情况来修改
- //从存储器->外设模式/8位数据宽度/存储器增量模式
- //DMA_Streamx:DMA数据流,DMA1_Stream0~7/DMA2_Stream0~7
- //chx:DMA通道选择,@ref DMA_channel DMA_CHANNEL_0~DMA_CHANNEL_7
- void DMA_Config(void)
- {
- __HAL_RCC_DMA2_CLK_ENABLE();//DMA2时钟使能
-
- //Tx DMA配置
- ADC1TxDMA_Handler.Instance=DMA2_Stream0; //数据流选择
- ADC1TxDMA_Handler.Init.Channel=DMA_CHANNEL_0; //通道选择
- ADC1TxDMA_Handler.Init.Direction=DMA_PERIPH_TO_MEMORY; //外设到存储器
- ADC1TxDMA_Handler.Init.PeriphInc=DMA_PINC_DISABLE; //外设非增量模式
- ADC1TxDMA_Handler.Init.MemInc=DMA_MINC_ENABLE; //存储器增量模式
- ADC1TxDMA_Handler.Init.PeriphDataAlignment=DMA_PDATAALIGN_WORD; //外设数据长度:32位
- ADC1TxDMA_Handler.Init.MemDataAlignment=DMA_MDATAALIGN_WORD; //存储器数据长度:32位
- ADC1TxDMA_Handler.Init.Mode=DMA_CIRCULAR; //外设流控模式
- ADC1TxDMA_Handler.Init.Priority=DMA_PRIORITY_MEDIUM; //中等优先级
- ADC1TxDMA_Handler.Init.FIFOMode=DMA_FIFOMODE_DISABLE;
- ADC1TxDMA_Handler.Init.FIFOThreshold=DMA_FIFO_THRESHOLD_FULL;
- ADC1TxDMA_Handler.Init.MemBurst=DMA_MBURST_SINGLE; //存储器突发单次传输
- ADC1TxDMA_Handler.Init.PeriphBurst=DMA_PBURST_SINGLE; //外设突发单次传输
- ADC1TxDMA_Handler.XferCpltCallback = HAL_DMA_IRQHandler;
-
- HAL_DMA_DeInit(&ADC1TxDMA_Handler);
- HAL_DMA_Init(&ADC1TxDMA_Handler);
- HAL_ADC_Start_DMA(&ADC1_Handler,&ADC_ConvertedValueRead[0],4);
- __HAL_LINKDMA(&ADC1_Handler,DMA_Handle,ADC1TxDMA_Handler); //将ADC与DMA联系起来(发送DMA)
- HAL_NVIC_SetPriority(DMA2_Stream0_IRQn,0,0);
- HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn);
- // HAL_ADC_Stop_DMA(&ADC1_Handler); //传输完成以后关闭串口DMA
- }
- void DMA2_Stream0_IRQHandler(void)
- {
- HAL_DMA_IRQHandler(&ADC1TxDMA_Handler);
-
- }
复制代码
2)adc.c
STM32767在使用时一定要注意Cache的问题
- uint32_t ADC_ConvertedValueRead[4];
- uint32_t ADC_ConvertedValue[4];
- ADC_HandleTypeDef ADC1_Handler;//ADC句柄
- //DMA_HandleTypeDef ADC1TxDMA_Handler; //DMA句柄
- //ADC底层驱动,引脚配置,时钟使能
- //此函数会被HAL_ADC_Init()调用
- //hadc:ADC句柄
- //初始化ADC
- void MY_ADC_Init(void)
- {
- //ADC1引脚配置
- GPIO_InitTypeDef GPIO_Initure;
- ADC_ChannelConfTypeDef ADC1_ChanConf;
- __HAL_RCC_ADC1_CLK_ENABLE(); //使能ADC1时钟
- __HAL_RCC_GPIOA_CLK_ENABLE(); //开启GPIOA时钟
- __HAL_RCC_GPIOC_CLK_ENABLE(); //开启GPIOC时钟
-
- GPIO_Initure.Pin=GPIO_PIN_5|GPIO_PIN_7|GPIO_PIN_6; //PA5
- GPIO_Initure.Mode=GPIO_MODE_ANALOG; //模拟
- GPIO_Initure.Pull=GPIO_NOPULL; //不带上下拉
- HAL_GPIO_Init(GPIOA,&GPIO_Initure);
-
- GPIO_Initure.Pin=GPIO_PIN_4; //|GPIO_PIN_5;
- GPIO_Initure.Mode=GPIO_MODE_ANALOG; //模拟
- GPIO_Initure.Pull=GPIO_NOPULL; //不带上下拉
- HAL_GPIO_Init(GPIOC,&GPIO_Initure);
- //ADC1功能配置
- ADC1_Handler.Instance=ADC1;
- ADC1_Handler.Init.ClockPrescaler=ADC_CLOCK_SYNC_PCLK_DIV4; //4分频,ADCCLK=PCLK2/4=108/4=27MHZ
- ADC1_Handler.Init.Resolution=ADC_RESOLUTION_12B; //12位模式
- ADC1_Handler.Init.DataAlign=ADC_DATAALIGN_RIGHT; //右对齐
- ADC1_Handler.Init.ScanConvMode=ENABLE; //扫描模式
- ADC1_Handler.Init.EOCSelection=DISABLE; //关闭EOC中断
- ADC1_Handler.Init.ContinuousConvMode=ENABLE; //关闭连续转换
- ADC1_Handler.Init.NbrOfConversion=4; //4个转换在规则序列中 也就是只转换规则序列1
- ADC1_Handler.Init.DiscontinuousConvMode=DISABLE; //禁止不连续采样模式
- ADC1_Handler.Init.NbrOfDiscConversion=0; //不连续采样通道数为0
- ADC1_Handler.Init.ExternalTrigConv=ADC_SOFTWARE_START; //软件触发
- ADC1_Handler.Init.ExternalTrigConvEdge=ADC_EXTERNALTRIGCONVEDGE_NONE;//使用软件触发
- ADC1_Handler.Init.DMAContinuousRequests=ENABLE; //开启DMA请求
- ADC1_Handler.DMA_Handle=&ADC1TxDMA_Handler;
- HAL_ADC_Init(&ADC1_Handler);
- //采样通道、顺序配置
- ADC1_ChanConf.Channel=ADC_CHANNEL_7; //通道
- ADC1_ChanConf.Rank=1; //1个序列
- ADC1_ChanConf.SamplingTime=ADC_SAMPLETIME_480CYCLES; //采样时间
- ADC1_ChanConf.Offset=0;
- HAL_ADC_ConfigChannel(&ADC1_Handler,&ADC1_ChanConf); //通道配置
-
- ADC1_ChanConf.Channel=ADC_CHANNEL_14; //通道
- ADC1_ChanConf.Rank=2; //1个序列
- ADC1_ChanConf.SamplingTime=ADC_SAMPLETIME_480CYCLES; //采样时间
- ADC1_ChanConf.Offset=0;
- HAL_ADC_ConfigChannel(&ADC1_Handler,&ADC1_ChanConf); //通道配置
-
- ADC1_ChanConf.Channel=ADC_CHANNEL_6; //通道
- ADC1_ChanConf.Rank=3; //1个序列
- ADC1_ChanConf.SamplingTime=ADC_SAMPLETIME_480CYCLES; //采样时间
- ADC1_ChanConf.Offset=0;
- HAL_ADC_ConfigChannel(&ADC1_Handler,&ADC1_ChanConf); //通道配置
-
- ADC1_ChanConf.Channel=ADC_CHANNEL_5; //通道
- ADC1_ChanConf.Rank=4; //1个序列
- ADC1_ChanConf.SamplingTime=ADC_SAMPLETIME_480CYCLES; //采样时间
- ADC1_ChanConf.Offset=0;
- HAL_ADC_ConfigChannel(&ADC1_Handler,&ADC1_ChanConf); //通道配置
-
- }
- /** * 函数功能: ADC转换完成回调函数
- * 输入参数: hadc:ADC外设设备句柄
- * 返 回 值: 无 * 说 明: 读取ADC转化结果时,一定要关闭Cache,
- 否则数组中的数据为空,即关闭Cache后读取数据,读完在打开。
- 此函数在 void HAL_ADC_IRQHandler(ADC_HandleTypeDef* hadc) 中调用 */
- void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
- {
- uint32_t i;
- SCB_DisableDCache();
- for(i=0;i<4;i++)
- {
- ADC_ConvertedValue = ADC_ConvertedValueRead;
- }
- SCB_EnableDCache();
- }
复制代码
3)main.c
- #define N 4
- extern uint32_t ADC_ConvertedValue[4];
- extern u16 value[N];
- int main(void)
- {
- u16 adcx;
- float temp[6];
- int i,k,j;
- Cache_Enable(); //打开L1-Cache
- HAL_Init(); //初始化HAL库
- Stm32_Clock_Init(432,25,2,9); //设置时钟,216Mhz
- delay_init(216); //延时初始化
- uart_init(115200); //串口初始化
- LED_Init(); //初始化LED
- KEY_Init(); //初始化按键
- SDRAM_Init(); //初始化SDRAM
- LCD_Init(); //LCD初始化
- MY_ADC_Init(); //初始化ADC1通道5
- DMA_Config();
- //Time_Config();
- POINT_COLOR=RED;
- LCD_ShowString(30,50,200,16,16,"Apollo STM32F4/F7");
- LCD_ShowString(30,70,200,16,16,"ADC TEST");
- LCD_ShowString(30,90,200,16,16,"ATOM@ALIENTEK");
- LCD_ShowString(30,110,200,16,16,"2016/7/12");
- POINT_COLOR=BLUE;//设置字体为蓝色
- LCD_ShowString(30,130,200,16,16,"ADC1_PA7_VAL:");
- LCD_ShowString(30,150,200,16,16,"ADC1_PC4_VAL:");
- LCD_ShowString(30,170,200,16,16,"ADC1_PA6_VAL:");
- LCD_ShowString(30,190,200,16,16,"ADC1_PA5_VAL:");
- LCD_ShowString(30,210,200,16,16,"ADC1_PA7_VOL:0.000V"); //先在固定位置显示小数点
- LCD_ShowString(30,230,200,16,16,"ADC1_PC4_VOL:0.000V"); //先在固定位置显示小数点
- LCD_ShowString(30,250,200,16,16,"ADC1_PA6_VOL:0.000V"); //先在固定位置显示小数点
- LCD_ShowString(30,270,200,16,16,"ADC1_PA5_VOL:0.000V"); //先在固定位置显示小数点
- while(1)
- {
-
- for(j=0;j<4;j++)
- {
- value[j] = (u16)(ADC_ConvertedValue[j]);
- LCD_ShowxNum(134,130+20*j,value[j],4,16,0); //显示ADCC采样后的原始值
- }
-
- for(k=0; k<4; k++)
- {
- temp[k]=(float)value[k]*(3.3/4096); //获取计算后的带小数的实际电压值,比如3.1111
- adcx=temp[k]; //赋值整数部分给adcx变量,因为adcx为u16整形
- LCD_ShowxNum(134,210+20*k,adcx,1,16,0); //显示电压值的整数部分,3.1111的话,这里就是显示3
- temp[k]-=adcx; //把已经显示的整数部分去掉,留下小数部分,比如3.1111-3=0.1111
- temp[k]*=1000; //小数部分乘以1000,例如:0.1111就转换为111.1,相当于保留三位小数。
- LCD_ShowxNum(150,210+20*k,temp[k],3,16,0X80); //显示小数部分(前面转换为了整形显示),这里显示的就是111.
- printf("\r\n 编号%d \t 编号%d \t AD值: %d\r\n", k,i, value[k]);
- }
- delay_ms(500);
- // HAL_ADC_Stop_DMA(&ADC1_Handler); //传输完成以后关闭串口DMA
- }
- }
复制代码
|
|