今天早晨把昨天学习的内容又重新写了一遍,防止自己的记忆不够深刻,特此又写了这篇博文,从造成5点点起床到现在终于搞完了,有点小错误也修改过来了,下午再写一遍,差不多就记住了。下面就是今天早晨写的Addma.c文件:这些都是根据昨天整理的步骤来完成的,感觉现在自己的记忆力又有所提高了,这么多东西居然能记住了。
#include "stm32f10x.h" // Device header
uint16_t Data[4];
void Addma_Init(void)
{
//1:/*开启时钟(ADC1,GPIOA,DMA1)*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
//2:/*设置ADC时钟*/
RCC_ADCCLKConfig(RCC_PCLK2_Div6);
//3:/*GPIO初始化*/(模拟输入模式,A0,A1,A2,A3四个端口)
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AIN;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStruct);
//4:/*规则组通道配置*/(序列1放通道0,序列2放通道1,序列3放通道2,序列4放通道3)
ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_28Cycles5);
ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 2, ADC_SampleTime_28Cycles5);
ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 3, ADC_SampleTime_28Cycles5);
ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 4, ADC_SampleTime_28Cycles5);
//5:/*ADC初始化*/(独立模式,数据右对齐,不使用外部触发,连续转换,扫描模式,通道数4)
ADC_InitTypeDef ADC_InitStruct;
ADC_InitStruct.ADC_ContinuousConvMode = ENABLE;
ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStruct.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
ADC_InitStruct.ADC_Mode = ADC_Mode_Independent;
ADC_InitStruct.ADC_NbrOfChannel = 4;
ADC_InitStruct.ADC_ScanConvMode = ENABLE;
ADC_Init(ADC1, &ADC_InitStruct);
//6:/*DMA初始化*/(外设地址:ADC的DR也就是电压值的寄存器
DMA_InitTypeDef DMA_InitStruct;
//数据宽度:16位的半字
//地址自增:外设不自增,内存地址(目标地址)自增
DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR;
DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStruct.DMA_MemoryBaseAddr = (uint32_t)Data;
DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable;
//传输方向:外设为源
DMA_InitStruct.DMA_DIR = DMA_DIR_PeripheralSRC;
//转运次数:4(一次16位)
DMA_InitStruct.DMA_BufferSize = 4;
//DMA_Mode模式:循环模式
DMA_InitStruct.DMA_Mode = DMA_Mode_Circular;
//DMA_M2M存储器到存储器:失能,由ADC外设触发转运
DMA_InitStruct.DMA_M2M = DMA_M2M_Disable;
//优先级:中等)
DMA_InitStruct.DMA_Priority = DMA_Priority_Medium;
DMA_Init(DMA1_Channel1, &DMA_InitStruct);
//7: /*DMA使能*/ DMA_Cmd()
DMA_Cmd(DMA1_Channel1, ENABLE);
//8: /*ADC1触发DMA1使能*/ ADC_DMACmd
ADC_DMACmd(ADC1, ENABLE);
//9: /*ADC使能*/ADC_Cmd()
ADC_Cmd(ADC1, ENABLE);
//10:/*ADC校准*/ 复位校准 开始校准
ADC_ResetCalibration(ADC1);
while(ADC_GetResetCalibrationStatus(ADC1) == SET);
ADC_StartCalibration(ADC1);
while(ADC_GetCalibrationStatus(ADC1) == SET);
//11:/*ADC触发*/ ADC_SoftwareStartConvCmd
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
}
下面是Addma.h文件:
#ifndef __ADDMA_H
#define __ADDMA_H
extern uint16_t Data[];
void Addma_Init(void);
#endif
下面是主函数Main.c文件:
#include "stm32f10x.h" // Device header
#include "OLED.h"
#include "Addma.h"
#include "Delay.h"
int main(void)
{
OLED_Init(); //oled 屏幕初始化
Addma_Init();
OLED_ShowString(1,1,"Val_1:");
OLED_ShowString(2,1,"Val_2:");
OLED_ShowString(3,1,"Val_3:");
OLED_ShowString(4,1,"Val_4:");
while(1)
{
OLED_ShowNum(1,7, Data[0], 4);
OLED_ShowNum(2,7, Data[1], 4);
OLED_ShowNum(3,7, Data[2], 4);
OLED_ShowNum(4,7, Data[3], 4);
Delay_ms(200);
}
}
Oled和Delay的代码和原来的一样,就不展示了,没有的自己去我以前的文章中找吧!都有发出过,之后编译后烧录到单片机内就能实现4路模拟电压的测量了。