完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
/*
**** 通过STM32自带的ADC实现对外部两路电压和内部工作温度的采集 **** ADC电压采集的过程使用DMA **** 通过USART1将电压采集值和温度转换值打印到PC 上 **** 外设为ADC1的通道1 和通道2 和内部自带温度传感器通道16 */ #include"stm32f10x.h" #include #define ADC1_DR_Address (0x40012400+0x4c) volatile u16 sendbuff[3]; //为了让编译器不去优化该变量,这样每次用它时都要回到该变量的内存在去取值 //u32 sendbuff2[3]; // 注意! 因为ADC转换后的值为16位 所以这里的变量类型要设置为16位 /* **** ADC所需GPIO口的设置 */ ADC_GPIO_Configuration() //GPIO的设置 { GPIO_InitTypeDef GPIO_InitStructure; //定义结构体 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1|GPIO_Pin_2; //GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //模拟输入时不用设置速率 GPIO_InitStructure.GPIO_Mode =GPIO_Mode_AIN; //设置输出方式为模拟输入 GPIO_Init(GPIOA, &GPIO_InitStructure); //取GPIO为GPIOA } /* **** ADC1以及DMA的设置 */ ADC_DMA_Configuration() { DMA_InitTypeDef DMA_InitStructure; ADC_InitTypeDef ADC_InitStructure; RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE); //开时钟 DMA和ADC1 RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); DMA_DeInit(DMA1_Channel1); DMA_InitStructure.DMA_PeripheralBaseAddr=ADC1_DR_Address; //设置DMA要传送数据的来源 这里为ADC1的数据寄存器 DMA_InitStructure.DMA_MemoryBaseAddr=(u32)sendbuff; //内存的地址 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //外设为ADC1所以设置为外设为数据源 DMA_InitStructure.DMA_BufferSize=3; //转换后的数据大小3个十六位数据 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设地址固定 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //内存地址自增 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; //设置传输数据宽度为16位 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; //设置传输数据宽度为16位 DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; //循环传输 DMA_InitStructure.DMA_Priority = DMA_Priority_High; //中级优先 DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //禁止内存到内存的传输 DMA_Init(DMA1_Channel1, &DMA_InitStructure); DMA_Cmd(DMA1_Channel1, ENABLE); //使能DMA通道1 // DMA_ITConfig(DMA1_Channel1, DMA_IT_TC, ENABLE); // DMA_ClearFlag(DMA1_FLAG_TC1); ADC_DeInit(ADC1); ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //独立ADC模式 ADC_InitStructure.ADC_ScanConvMode =ENABLE; //开启扫描模式 扫描模式应用于多通道采集 ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; //开启连续转换 ADC_InitStructure.ADC_ExternalTrigConv =ADC_ExternalTrigConv_None; //不使用外部触发转换 ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //采集的数据右对齐 ADC_InitStructure.ADC_NbrOfChannel = 3; //转换的通道数木 ADC_Init(ADC1, &ADC_InitStructure); RCC_ADCCLKConfig(RCC_PCLK2_Div8); //设置ADC采集的时钟 最大是14MHZ //所以8分频 72/8=9 ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_239Cycles5); //配置ADC1的通道1为239.5个采集周期 ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 2, ADC_SampleTime_239Cycles5); //配置ADC1的通道2为239.5个采集周期 ADC_RegularChannelConfig(ADC1, ADC_Channel_16, 3, ADC_SampleTime_239Cycles5); //配置ADC1的通道16为239.5个采集周期 ADC_TempSensorVrefintCmd(ENABLE); ADC_Cmd(ADC1, ENABLE); //使能ADC1 ADC_DMACmd(ADC1, ENABLE); //使能ADC1的DMA传输 ADC_SoftwareStartConvCmd(ADC1, ENABLE); } /* **** ADC的自校准 */ ADC_selfReset() // { ADC_ResetCalibration(ADC1); while(ADC_GetResetCalibrationStatus(ADC1)); ADC_StartCalibration(ADC1); while( ADC_GetCalibrationStatus(ADC1)); ADC_SoftwareStartConvCmd(ADC1, ENABLE); } /* **** USART1的设置 */ USART1_Configuration() {USART_InitTypeDef USART_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; //定义结构体 RCC_APB2PeriphClockCmd( RCC_APB2Periph_AFIO, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_USART1, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //选中第10引脚 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //设置输出速率为50MHz GPIO_InitStructure.GPIO_Mode =GPIO_Mode_AF_PP; //设置输出方式为推挽输出 GPIO_Init(GPIOA, &GPIO_InitStructure); //取GPIO为GPIOC GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //选中第10引脚 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //设置输出速率为50MHz GPIO_InitStructure.GPIO_Mode =GPIO_Mode_IN_FLOATING; //设置输出方式为推挽输出 GPIO_Init(GPIOA, &GPIO_InitStructure); USART_InitStructure.USART_BaudRate = 9600; //9600波特率 USART_InitStructure.USART_WordLength = USART_WordLength_8b; //八个字节 USART_InitStructure.USART_StopBits = USART_StopBits_1; //停止位为1位 USART_InitStructure.USART_Parity = USART_Parity_No; //无校验 USART_InitStructure.USART_HardwareFlowControl =USART_HardwareFlowControl_None; //无硬件流 USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; //接收和发送功能使能 //USART_InitStructure.USART_Clock = USART_Clock_Disable; //USART_InitStructure.USART_CPOL = USART_CPOL_High; //USART_InitStructure.USART_CPHA = USART_CPHA_1Edge; //USART_InitStructure.USART_LastBit = USART_LastBit_Enable; USART_Init(USART1, &USART_InitStructure); USART_Cmd(USART1, ENABLE); //串口使能 } /* **** USART1的重定向 */ int fputc(int ch,FILE *f) //将printf函数指向USART1 发送数据时便可直接调用printf { USART1->SR; USART_SendData(USART1, ch); //ch送给USART1 while(USART_GetFlagStatus(USART1, USART_FLAG_TC)==RESET); //等待发送完毕 return ch; //返回ch } /* 延时 */ void Dealy_Ms(u16 x) //延时 {int i,j; for(i=0;i<1000;i++) for(j=0;j //Getvoltage(advalue) //{ // return (advalue*330/4096); //} int main(void) { float Voltagevalue1=0,Voltagevalue2=0,temperture=0; ADC_GPIO_Configuration(); ADC_DMA_Configuration(); ADC_selfReset(); USART1_Configuration(); printf("----这是一个ADC转换实验!----") ; while(1) { Voltagevalue1=(float)sendbuff[0]/4096*3.3; Voltagevalue2=(float)sendbuff[1]/4096*3.3; temperture=(float)(1.43-sendbuff[2]*3.3/4096)*1000/4.35+25; printf("rn The current ADC channel 1 value=%f Vrn",Voltagevalue1); printf("rn The current ADC channel 2 value=%f Vrn",Voltagevalue2); printf("rn The currenttemperture value=%f 摄氏度 rn",temperture); Dealy_Ms(20000); } } |
|
相关推荐
|
|
2162 浏览 1 评论
AD7686芯片不传输数据给STM32,但是手按住就会有数据。
1997 浏览 3 评论
4593 浏览 0 评论
如何解决MPU-9250与STM32通讯时,出现HAL_ERROR = 0x01U
2140 浏览 1 评论
hal库中i2c卡死在HAL_I2C_Master_Transmit
2659 浏览 1 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-24 20:36 , Processed in 0.686379 second(s), Total 76, Slave 59 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号