OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 5642|回复: 3

ADC3 DMA传输 串口显示

[复制链接]

36

主题

96

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
244
金钱
244
注册时间
2012-11-11
在线时间
14 小时
发表于 2014-7-6 01:52:45 | 显示全部楼层 |阅读模式
5金钱
那位神人帮忙看下为什么串口没有数据

#include "stm32f10x_lib.h"
#include "sys.h"
#include "delay.h"

#define USART1_DR_Base  0x40013804  
#define ADC3_DR_Address 0x4001244C //0x40012400+0x4C 

//#define DMA1_MEM_ADD    (u32)ADC_Buf 
//#define DMA1_MEM_SIZE    (u32)sizeof(ADC_Buf) 
u16 ADC_Buf[256];

void MYDMA_Config(DMA_Channel_TypeDef*DMA_CHx);//配置DMA1_CHx 
void MYDMA_Enable(DMA_Channel_TypeDef*DMA_CHx);//使能DMA1_CHx 
void MYDMA_GOnes(DMA_Channel_TypeDef*DMA_CHx); //执行一次DMA    
void  adc_init(void) ;
void  USART_Initaize(u32 pclk2,u32 bound);
void  Uart1_PutChar(u8 ch);
void Uart1_PutString(u8 *Buf, u8 Len);

//主函数的内容: 
int main(void) 
{     
u16 times=0;
u16 t;
u32 temp =0;
u16 adcx; 
u8 table[5];
u8 *p;
p= table;
Stm32_Clock_Init(9);//88M 
delay_init(72);     //延时初始化 
USART_Initaize(72,9600); //设置波特率 
adc_init(); 
  while (1) 
    { 
   if(DMA2->ISR&(1<<17)) //传输完成了 
{  
times++;  
for(t=0;t<5;t++)
{
temp = temp + ADC_Buf[t];

temp = temp /5;
adcx=temp*330/4096;;
table[0]=adcx / 100 + 0x30;
table[1]='.';
table[2]=adcx % 100/10 + 0x30;
table[3]= adcx %10 + 0x30;
table[4]='V';
Uart1_PutString(p,5);
Uart1_PutString("\r\n",2);
temp =0;
DMA2->IFCR|=1<<17;
MYDMA_GOnes(DMA2_Channel5);

             
    }  
               
 }  
    
void  adc_init(void) 
{     
RCC->APB2ENR|=1<<2;    //使能PORTA口时钟  
GPIOA->CRL&=0XFFFFFFF0;//PA.0 anolog输入  
//通道10/11设置   
RCC->APB2ENR|=1<<9;    //ADC3时钟使能 
__nop();
__nop();      
RCC->APB2RSTR|=1<<9;   //ADC3复位 
RCC->APB2RSTR&=~(1<<9);//复位结束   
RCC->CFGR|=3<<14;      //SYSCLK/DIV2=88M/8=11Mhz 得到ADC采样率位43.65Khz    
  
ADC3->CR1&=0XF0FFFF;   //独立工作模式 
ADC3->CR1|=1<<8;       //扫描模式    
ADC3->CR2|=1<<1;       //连续转换模式  
ADC3->CR2|=0x000E0000; //软件控制转换 由bit21控制 
ADC3->CR2|=1<<20;      //使用用外部触发(SWSTART)!!! 必须使用一个事件来触发 
ADC3->CR2&=~(1<<11);   //右对齐 

ADC3->SQR1&=0xFFF0FFFF;//1个转换在规则序列中   
ADC3->SQR3&=0XFFFFFFE0;//规则序列1=通道0 
ADC3->SQR3|=0;     
ADC3->SMPR2|=0X07;     //通道0的转换时间为:239.5+12.5个ADC时钟周期     
ADC3->CR2|=1<<0;       //开启AD转换器,第一次唤醒AD转换器   
ADC3->CR2|=1<<3;       //使能复位校准   
while(ADC3->CR2&1<<3); //等待校准结束    
    //该位由软件设置并由硬件清除。在校准寄存器被初始化后该位将被清除。     
ADC3->CR2|=1<<2;       //开启AD校准     
while(ADC3->CR2&1<<2); //等待校准结束 
//该位由软件设置以开始校准,并在校准结束时由硬件清除     
ADC3->CR2|=1<<8;    //开启ADC DMA转换 

MYDMA_Config(DMA2_Channel5);//配置DMA通道1 
MYDMA_Enable(DMA2_Channel5);//开启DMA通道1  
ADC3->CR2|=1<<0;    //开启AD转换    


//获得ADC值 
u16 get_adc(void)    
{      
ADC3->CR2|=1<<22;       //启动规则转换通道  
while(!(ADC3->SR&1<<1));//等待转换结束       
return ADC3->DR; //返回adc值          


//DMA1的各通道配置 
//DMA_CHxMA1的通道 参考手册 
void MYDMA_Config(DMA_Channel_TypeDef*DMA_CHx) 

RCC->AHBENR|=1<<1;//开启DMA2时钟 
__nop();                    //等待 DMA1 时钟稳定
    __nop();                    //经测试最少 2 个 nop
    __nop();
   __nop();                    //经测试最少 2 个 nop
    __nop();
// DMA_CHx->CPAR=ADC3_DR_Address;//DMA1 外设地址 ADC3_DR_Address 
    DMA_CHx->CPAR=(u32)&ADC3->DR;//DMA1 外设地址 ADC3_DR_Address
DMA_CHx->CMAR=(u32)ADC_Buf ;   //DMA1,ADC 存储器地址 
DMA_CHx->CNDTR=(u32)sizeof(ADC_Buf) ;  //DMA1,传输数据量 
DMA_CHx->CCR=0X00000000;//复位 
DMA_CHx->CCR|=0<<4;  //从外设器件读数据 
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<<13; //高优先级 
DMA_CHx->CCR|=0<<14; //非存储器到存储器模式    

//开启 DMA传输 
void MYDMA_Enable(DMA_Channel_TypeDef*DMA_CHx) 

DMA_CHx->CCR|=1<<0;  //开启DMA传输 
}    
//开启一次DMA传输 
//单次DMA转换之后,必须把DMA关闭,再次启动,才能实现第二次DMA传输!!! 
void MYDMA_GOnes(DMA_Channel_TypeDef*DMA_CHx) 
{    
DMA_CHx->CCR&=~(1<<0);  //关闭DMA传输 
DMA_CHx->CNDTR=(u32)sizeof(ADC_Buf) ;  //DMA1,传输数据量 
DMA_CHx->CCR|=1<<0;  //开启DMA传输 


void  USART_Initaize(u32 pclk2,u32 bound)
{
float temp;
u16 mantissa;
u16 fraction;   
temp=(float)(pclk2*1000000)/(bound*16);//得到USARTDIV
mantissa=temp; //得到整数部分
fraction=(temp-mantissa)*16; //得到小数部分  
    mantissa<<=4;
mantissa+=fraction; 
RCC->APB2ENR|=1<<2;   //使能PORTA口时钟  
RCC->APB2ENR|=1<<14;  //使能串口时钟 
GPIOA->CRH&=0XFFFFF00F; 
GPIOA->CRH|=0X000008B0;//IO状态设置
 
RCC->APB2RSTR|=1<<14;   //复位串口1
RCC->APB2RSTR&=~(1<<14);//停止复位     
//波特率设置
  USART1->BRR=mantissa; // 波特率设置  
USART1->CR1|=0X200C;  //1位停止,无校验位.
//使能接收中断
USART1->CR1|=1<<8;    //PE中断使能
USART1->CR1|=1<<5;    //接收缓冲区非空中断使能    
MY_NVIC_Init(3,3,USART1_IRQChannel,2);//组2,最低优先级 
}
void  Uart1_PutChar(u8 ch)
{
USART1->DR = (u8) ch;  
while((USART1->SR&0X40)==0);//循环发送,直到发送完毕  
}

void Uart1_PutString(u8 *Buf, u8 Len)
{
u8 i;
for(i= 0; i<Len; i++)
{
Uart1_PutChar(*Buf++);
}
}


最佳答案

查看完整内容[请看2#楼]

自己老眼昏花时钟忘记开启了额
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

36

主题

96

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
244
金钱
244
注册时间
2012-11-11
在线时间
14 小时
 楼主| 发表于 2014-7-6 01:52:46 | 显示全部楼层
自己老眼昏花时钟忘记开启了额
回复

使用道具 举报

1

主题

13

帖子

0

精华

新手上路

积分
37
金钱
37
注册时间
2014-12-22
在线时间
0 小时
发表于 2015-3-27 10:44:29 | 显示全部楼层
想问下temp = temp + ADC_Buf[t];这一句中ADC_Buf[t]从哪里来的啊,没看到被赋值啊,没看懂,
回复

使用道具 举报

10

主题

30

帖子

0

精华

初级会员

Rank: 2

积分
92
金钱
92
注册时间
2012-6-7
在线时间
0 小时
发表于 2015-3-27 11:34:04 | 显示全部楼层
回复【3楼】杨泽松yzs:
---------------------------------
自己定义的一块内存区域,用于ADC外设和内存之间的DMA传输,不懂的话可以看一下中文手册,和原子哥的DMA例程。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-24 15:35

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表