我用ADC1采样0,1,2,3,通道,用的是扫描模式,DMA传输数据,配置DMA时,传输数据应该是1还是4呢(红色的数字),我认为是4可是,液晶显示不行ADC1_MYDMA_Config(DMA1_Channel1,(u32)(&ADC1->DR),(u32)buffer,4);显示图片如下
采样的数据总是四个数据循环显示,只是肿么一回事啊??请各位朋友帮我一下,万分感谢
下面是代码主函数部分
GLCD_displayStringLn(Line0,"AD TEST");
ADC1_MYDMA_Config(DMA1_Channel1,(u32)(&ADC1->DR),(u32)buffer,4);
Set_Adc_Channel(ADC1_CH0|ADC1_CH1<<5|ADC1_CH2<<10|ADC1_CH3<<15);
// Set_Adc_Channel(ADC1_CH0);
// Set_Adc_Channel(<<5);
// Set_Adc_Channel(ADC1_CH2<<10);
// Set_Adc_Channel(ADC1_CH3<<15);
ADC1_MYDMA_Enable(DMA1_Channel1);
// AWD_Set_Channel(ADC1_CH1);
// Get_Adc(ADC1_CH1<<5);
// Get_Adc(ADC1_CH2<<10);
// Get_Adc(ADC1_CH3<<15);
// ADC1->CR2|=1<<22; //启动规则转换通道 连续转换模式 */
while(1)
{
// Set_Adc_Channel(ADC1_CH0|ADC1_CH1<<5|ADC1_CH2<<10|ADC1_CH3<<15);
// ADC1->CR2|=1<<22;
/* adcx=Get_Adc(ADC1_CH0);
GLCD_displayChar(24, 160,adcx/1000+0x30);
GLCD_displayChar(24, 140,adcx%1000/100+0x30);
GLCD_displayChar(24, 120,adcx%100/10+0x30);
GLCD_displayChar(24, 100,adcx%10+0x30);
temp=(float)adcx*(3.3/4096);
adcx=temp;
GLCD_displayChar(48, 160,adcx%10+0x30);
temp-=adcx;
temp*=1000;
GLCD_displayChar(48, 140,'.');
GLCD_displayChar(48, 120,(u16)temp/100+0x30);
GLCD_displayChar(48, 100,(u16)temp%100/10+0x30);
GLCD_displayChar(48, 80,(u16)temp%10+0x30); */
if(DMA1->ISR&(1<<1)) //等待通道4传输完成
{
DMA1->IFCR|=1<<1; //清除通道1传输完成标志
ADC1_MYDMA_Enable(DMA1_Channel1);
}
if(ADC1->SR&1<<1)
{
ADC1->SR&=~(1<<1);
}
GLCD_displayChar(24, 160,buffer[0]/1000+0x30);
GLCD_displayChar(24, 140,buffer[0]%1000/100+0x30);
GLCD_displayChar(24, 120,buffer[0]%100/10+0x30);
GLCD_displayChar(24, 100,buffer[0]%10+0x30);
// temp=(float)buffer[0]*(3.3/4096);
// buffer[0]=temp;
// temp-=buffer[0];
// temp*=1000;
// GLCD_displayChar(48, 160,buffer[0]%10+0x30); //整数部分
// GLCD_displayChar(48, 140,'.');
// GLCD_displayChar(48, 120,(u16)temp/100+0x30);
// GLCD_displayChar(48, 100,(u16)temp%100/10+0x30);
// GLCD_displayChar(48, 80,(u16)temp%10+0x30);
GLCD_displayChar(72, 160,buffer[1]/1000+0x30);
GLCD_displayChar(72, 140,buffer[1]%1000/100+0x30);
GLCD_displayChar(72, 120,buffer[1]%100/10+0x30);
GLCD_displayChar(72, 100,buffer[1]%10+0x30);
// temp=(float)buffer[1]*(3.3/4096);
// buffer[1]=temp;
// temp-=buffer[1];
// temp*=1000;
// GLCD_displayChar(96, 160,buffer[1]%10+0x30); //整数部分
// GLCD_displayChar(96, 140,'.');
// GLCD_displayChar(96, 120,(u16)temp/100+0x30);
// GLCD_displayChar(96, 100,(u16)temp%100/10+0x30);
// GLCD_displayChar(96, 80,(u16)temp%10+0x30);
GLCD_displayChar(120, 160,buffer[2]/1000+0x30);
GLCD_displayChar(120, 140,buffer[2]%1000/100+0x30);
GLCD_displayChar(120, 120,buffer[2]%100/10+0x30);
GLCD_displayChar(120, 100,buffer[2]%10+0x30);
// temp=(float)buffer[2]*(3.3/4096);
// buffer[2]=temp;
// temp-=buffer[2];
// temp*=1000;
// GLCD_displayChar(144, 160,buffer[2]%10+0x30); //整数部分
// GLCD_displayChar(144, 140,'.');
// GLCD_displayChar(144, 120,(u16)temp/100+0x30);
// GLCD_displayChar(144, 100,(u16)temp%100/10+0x30);
// GLCD_displayChar(144, 80,(u16)temp%10+0x30);
GLCD_displayChar(168, 160,buffer[3]/1000+0x30);
GLCD_displayChar(168, 140,buffer[3]%1000/100+0x30);
GLCD_displayChar(168, 120,buffer[3]%100/10+0x30);
GLCD_displayChar(168, 100,buffer[3]%10+0x30);
// temp=(float)adcx*(3.3/4096);
// buffer[3]=temp;
// temp-=buffer[3];
// temp*=1000;
// GLCD_displayChar(192, 160,buffer[3]%10+0x30); //整数部分
// GLCD_displayChar(192, 140,'.');
// GLCD_displayChar(192, 120,(u16)temp/100+0x30);
// GLCD_displayChar(192, 100,(u16)temp%100/10+0x30);
// GLCD_displayChar(192, 80,(u16)temp%10+0x30);
LED2=!LED2;
delay_ms(200);
下面是ad部分
#include"ADC.h"
#include "sys.h"
#include "led.h"
#include "delay.h"
/********************************
adc驱动代码
初始化adc这里仅以规则通道为例;默认开启通道0~3
********************************/
void Adc_Init(void)
{
RCC->APB2ENR|=1<<2|1<<9; //开启PA时钟 ,以及ADC时钟
RCC->APB2RSTR|=1<<9;//复位adc1
RCC->APB2RSTR&=~(1<<9);//复位完成,需要将复位关闭,否则将一直保持复位
RCC->CFGR|=1<<15;//设置为6分频给ADC转换时钟 //读取ADC0的值
GPIOA->CRL&=0XFFFF0000; //模拟输入 0,1,2,3
ADC1->CR2|=1<<20;//允许软件外部触发
ADC1->CR2|=1<<19|1<<18|1<<17;//选择为软件触发
ADC1->SQR1&=~(0XF<<20); //清零重置
ADC1->SQR1&=3<<20; //4个转换
//设置通道0~3的采样时间
ADC1->SMPR2&=0XFFFFF000; //通道0,1,2,3,采样时间清空重置
ADC1->SMPR2|=7<<9; //通道3,239.5周期,提高采样时间可以提高精度
ADC1->SMPR2|=7<<6; //通道2,239.5周期,提高采样时间可以提高精度
ADC1->SMPR2|=7<<3; //通道1,239.5周期,提高采样时间可以提高精度
ADC1->SMPR2|=7<<0; //通道0,239.5周期,提高采样时间可以提高精度
ADC1->CR2|=1<<0;//开启转换
ADC1->CR1|=1<<8;//开启扫描模式
ADC1->CR2|=1<<3;//初始化复位校准寄存器
ADC1->CR2|=1<<8;//允许dma访问
while(ADC1->CR2&1<<3); //等待校准结束
ADC1->CR2|=1<<2;//开始校准
while(ADC1->CR2&1<<2); //等待校准结束
//ADC1->CR1|=1<<5;//允许中断
ADC1->CR2|=1<<1;//设置为连续模式
ADC1->SQR1|=3<<20;//开启4个转换
ADC1->CR2|=1<<22;//开始规则转换
// MY_NVIC_Init(2,1,ADC1_2_IRQChannel,2);//设置中断优先级
ADC1->SQR3=0|1<<5|2<<10|3<<15; //这个表明在第一规则通道当中,进行转换的将是16通道的数据
}
//获得ADC值
//ch:通道值0~3
u16 Get_Adc(u32 ch)
{
//设置转换序列
ADC1->SQR3&=0XFFFF8000; //规则序列1通道0,1,2,3 清除源通道
ADC1->SQR3|=ch; //选择转换的通道
ADC1->CR2|=1<<22; //启动规则转换通道
while(!(ADC1->SR&1<<1)); //等待转换结束
return ADC1->DR; //返回adc值
}
//设置通道 并启动 只能是0,1,2,3
void Set_Adc_Channel(u32 ch)
{
ADC1->SQR3&=0XFFFF8000; //规则序列1通道0,1,2,3 清除源通道
ADC1->SQR3|=ch; //选择转换的通道
ADC1->CR2|=1<<22; //启动规则转换通道
}
//设置模拟看门狗的通道
void AWD_Set_Channel(u8 channel)
{
ADC1->CR1|=channel;
}
//模拟中断服务程序
void ADC1_2_IRQHandler(void)
{
if(ADC1->SR&0X1)
{
ADC1->SR&=~(1<<0);
test2();
}
}
//dma和usart1的数据传输
u16 DMA1_MEM_LEN; //保存dma每次数据传送的长度
//dma_channel_typedef*dma_chx 应该是结构体指针指向各通道的寄存器地址
//没有配置中断允许位
void ADC1_MYDMA_Config(DMA_Channel_TypeDef*DMA_CHx,u32 cpar,u32 cmar,u16 cndtr)
{
u32 DR_Base; //作缓冲用,不知道为什么非要不可
RCC->AHBENR|=1<<0; //开启DMA1时钟
__nop(); //等待 DMA1 时钟稳定
__nop(); //经测试最少 2 个 nop
__nop();
delay_ms(100); //等待时钟稳定
DR_Base=cpar;
DMA_CHx->CPAR=DR_Base; //DMA1,外设地址
DMA_CHx->CMAR=(u32)cmar; //DMA1存储器地址
DMA1_MEM_LEN=cndtr; //保存DMA传输数据总量
DMA_CHx->CNDTR=cndtr; //dma,传输数据量
DMA_CHx->CCR=0X00000000; //复位 以便重新设置
#ifdef EN_DMA_INTERRUPT
DMA_CHx->CCR|=1<<1; //开启传输完成中断
#endif
DMA_CHx->CCR&=~(1<<4); //设置方向,从ADC读数据
DMA_CHx->CCR|=0<<5; //非循环模式
DMA_CHx->CCR|=0<<6; //外设地址不增
DMA_CHx->CCR|=1<<7; //存储器地址曾
DMA_CHx->CCR|=1<<8; //外设数据宽度为16位
DMA_CHx->CCR|=1<<10; //存储器数据宽度是16位
DMA_CHx->CCR|=1<<12; //中等有优先级
DMA_CHx->CCR|=1<<14; //非存储器到存储器模式
}
//开启一次传输
void ADC1_MYDMA_Enable(DMA_Channel_TypeDef*DMA_CHx)
{
//只有先关闭DMA传输才能更改寄存器设置
DMA_CHx->CCR&=~(1<<0);
DMA_CHx->CNDTR=DMA1_MEM_LEN;
DMA_CHx->CCR|=1<<0; //开启DMA传输
}
/*********************************
当测量温度时,跟测其他通道的相似,只不过把取得的电压值转换成
温度值,利用公式转换
*******************************************/
怎样才能将采集到的数据同时显示在液晶屏上;各位朋友指点一下吧。
|