OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
12
返回列表 发新帖
楼主: suqingxiao

STM32测试程序 ADC+DMA+串口发送。全代码奉献(操作寄存器)

[复制链接]

1

主题

22

帖子

0

精华

新手上路

积分
48
金钱
48
注册时间
2013-3-13
在线时间
0 小时
发表于 2013-8-12 16:16:45 | 显示全部楼层
自己照着楼主的代码改了一个适合战舰板子用的寄存器版本的ADC dma的程序不知道为什么,while进不去啊!求解答
逝者如斯夫不舍昼夜
正点原子逻辑分析仪DL16劲爆上市
回复 支持 反对

使用道具 举报

1

主题

22

帖子

0

精华

新手上路

积分
48
金钱
48
注册时间
2013-3-13
在线时间
0 小时
发表于 2013-8-12 16:18:13 | 显示全部楼层
附上ADC的配置和DMA的配置
void  Adc_Init(void)
{    
//先初始化IO口
  RCC->APB2ENR|=1<<2;    //使能PORTA口时钟 
GPIOA->CRL&=0XFFFFFF0F;//PA1 anolog输入
//通道10/11设置  
RCC->APB2ENR|=1<<9;    //ADC1时钟使能   
RCC->APB2RSTR|=1<<9;   //ADC1复位
RCC->APB2RSTR&=~(1<<9);//复位结束     
RCC->CFGR&=~(3<<14);   //分频因子清零
//SYSCLK/DIV2=12M ADC时钟设置为12M,ADC最大时钟不能超过14M!
//否则将导致ADC准确度下降! 
RCC->CFGR|=2<<14;        
ADC1->CR1&=0XF0FFFF;   //工作模式清零
ADC1->CR1|=0<<16;      //独立工作模式  
ADC1->CR1&=1<<8;    //扫描模式   
ADC1->CR2&=1<<1;    //连续转换模式
ADC1->CR2&=~(7<<17);    
ADC1->CR2|=7<<17;    //软件控制转换  
ADC1->CR2|=1<<20;      //使用用外部触发(SWSTART)!!! 必须使用一个事件来触发
ADC1->CR2&=~(1<<11);   //右对齐  

ADC1->SQR1&=~(0XF<<20);
ADC1->SQR1&=0<<20;     //1个转换在规则序列中 也就是只转换规则序列1     
//设置通道1的采样时间
//设置转换序列     
ADC1->SQR3&=0XFFFFFFE0;//规则序列1 通道ch
ADC1->SQR3|=1;
//ADC1->CR2|=1<<22;       //启动规则转换通道  
ADC1->SMPR2&=~(7<<3);  //通道1采样时间清空   
  ADC1->SMPR2|=7<<3;     //通道1  239.5周期,提高采样时间可以提高精确度  
ADC1->CR2|=1<<0;    //开启AD转换器  
ADC1->CR2|=1<<3;       //使能复位校准  
while(ADC1->CR2&1<<3); //等待校准结束   
    //该位由软件设置并由硬件清除。在校准寄存器被初始化后该位将被清除。   
ADC1->CR2|=1<<2;        //开启AD校准    
while(ADC1->CR2&1<<2);  //等待校准结束
//该位由软件设置以开始校准,并在校准结束时由硬件清除  
ADC1->CR2|=1<<8;    //开启ADC DMA转换 
}


void MYDMA_Config(DMA_Channel_TypeDef*DMA_CHx,u32 cpar,u32 cmar,u16 cndtr)
{
RCC->AHBENR|=1<<0; //开启DMA1时钟
delay_ms(5); //等待DMA时钟稳定
DMA_CHx->CPAR=cpar;    //DMA1 外设地址 
DMA_CHx->CMAR=(u32)cmar;  //DMA1,存储器地址
DMA1_MEM_LEN=cndtr;       //保存DMA传输数据量
DMA_CHx->CNDTR=cndtr;     //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|=2<<12;  //高等优先级
DMA_CHx->CCR|=0<<14;  //非存储器到存储器模式
  

//开启一次DMA传输
void MYDMA_Enable(DMA_Channel_TypeDef*DMA_CHx)
{
DMA_CHx->CCR|=1<<0;          //开启DMA传输
}
extern u16 ADC_Buf[512];   
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传输 
}
逝者如斯夫不舍昼夜
回复 支持 反对

使用道具 举报

1

主题

22

帖子

0

精华

新手上路

积分
48
金钱
48
注册时间
2013-3-13
在线时间
0 小时
发表于 2013-8-12 16:18:45 | 显示全部楼层
求大神帮忙看看!到底是怎么回事!哪里出错了!!!!!!!
逝者如斯夫不舍昼夜
回复 支持 反对

使用道具 举报

0

主题

1

帖子

0

精华

新手入门

积分
21
金钱
21
注册时间
2014-5-8
在线时间
0 小时
发表于 2014-5-13 14:49:16 | 显示全部楼层
回复【29楼】正点原子:
---------------------------------
我把这个程序放到战舰板子上,由于战舰的AD输入口是PA.1,所以将adc_init(void) 中

 GPIOA->CRL&=0XFFFFFFF0;//PA.0 anolog输入

改为
GPIOA->CRL&=0XFFFFFF0F;

但是改过的程序仍然是检测为PA.0的电压输入,本人小白求原子哥指导
回复 支持 反对

使用道具 举报

8

主题

73

帖子

0

精华

初级会员

Rank: 2

积分
126
金钱
126
注册时间
2014-2-27
在线时间
0 小时
发表于 2014-6-10 15:16:42 | 显示全部楼层
楼主程序里有一句不对吧,
ADC初始化在选择采集通道数目的时候也就是
ADC->SQR1=0xFFF0FFFF;
这句是不是应该改为
ADC->SQR1=0xFF0FFFFF;
选择通道数目应该是从第二十位到二十三位。
文可提笔控萝莉,武能床头定人妻,进可欺身压正太,退能提臀迎众基
回复 支持 反对

使用道具 举报

72

主题

2711

帖子

2

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
3505
金钱
3505
注册时间
2014-8-4
在线时间
696 小时
发表于 2014-10-26 17:58:13 | 显示全部楼层
very good,mark
以我资质之鲁钝,当尽平心静气、循序渐进、稳扎稳打之力。
回复 支持 反对

使用道具 举报

8

主题

32

帖子

0

精华

初级会员

Rank: 2

积分
114
金钱
114
注册时间
2013-11-29
在线时间
7 小时
发表于 2014-11-1 11:59:06 | 显示全部楼层
表示没看懂,大神能留个联系方式么?
回复 支持 反对

使用道具 举报

11

主题

55

帖子

0

精华

初级会员

Rank: 2

积分
197
金钱
197
注册时间
2014-12-29
在线时间
45 小时
发表于 2014-12-29 19:42:24 | 显示全部楼层
[mw_shl_code=c,true]u8 Sbuf[100]="888888888888888888888888888888"; void NVIC_Config(void) { NVIC_InitTypeDef NVIC_InitStructure; //DMA优先级 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_3); NVIC_InitStructure.NVIC_IRQChannel= DMA1_Channel4_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority= 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority= 1; NVIC_InitStructure.NVIC_IRQChannelCmd= ENABLE; NVIC_Init(&NVIC_InitStructure); /*Configure one bit for preemption priority -------------------------------- */ NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); /*UART1 -------------------------------------------------------------------- */ NVIC_InitStructure.NVIC_IRQChannel= USART1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority= 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority= 3; NVIC_InitStructure.NVIC_IRQChannelCmd= ENABLE; NVIC_Init(&NVIC_InitStructure); } void uart1Init(u32 bound) { //GPIO端口设置 GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; USART_ClockInitTypeDef USART_ClockInitStructure; NVIC_Config(); RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO , ENABLE); //使能USART1,GPIOA时钟 //USART1_TX PA.9 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出 GPIO_Init(GPIOA, &GPIO_InitStructure); //USART1_RX PA.10 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入 GPIO_Init(GPIOA, &GPIO_InitStructure); //USART 初始化设置 USART_InitStructure.USART_BaudRate = bound;//一般设置为9600; USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式 USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位 USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位 USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制 USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式 // USART_ClockInitStructure.USART_Clock = USART_Clock_Disable; // USART_ClockInitStructure.USART_CPOL = USART_CPOL_Low; // USART_ClockInitStructure.USART_CPHA = USART_CPHA_2Edge; // USART_ClockInitStructure.USART_LastBit= USART_LastBit_Disable; // USART_ClockInit(USART1,&USART_ClockInitStructure); USART_Init(USART1, &USART_InitStructure); //初始化串口 USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启中断 USART_Cmd(USART1, ENABLE); //使能串口 } void usart1SendGeneralStr(void) { DMA_InitTypeDef DMA_InitStructure; // memcpy(Sbuf, cmd, strlen((char *)cmd)); RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); /* DMA channel6configuration */ DMA_DeInit(DMA1_Channel1); DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)(&USART1->DR); //外设地址 DMA_InitStructure.DMA_MemoryBaseAddr = (u32)Sbuf; DMA_InitStructure.DMA_DIR =DMA_DIR_PeripheralDST; //外设作为目的地址 //DMA_DIR_PeripheralSRC; //外设作为DMA的源端 DMA_InitStructure.DMA_BufferSize =100; //BufferSize; //传输大小 DMA_InitStructure.DMA_PeripheralInc =DMA_PeripheralInc_Disable; //外设递增模式禁止 DMA_PeripheralInc_Enable; //外设地址增加 DMA_InitStructure.DMA_MemoryInc =DMA_MemoryInc_Enable; //内存地址自增 DMA_MemoryInc_Enable DMA_MemoryInc_Disable DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; //传输方式:字节 DMA_PeripheralDataSize_Word; //字(32位) DMA_InitStructure.DMA_MemoryDataSize =DMA_MemoryDataSize_Byte; //内存存储方式:字节 DMA_MemoryDataSize_Word; DMA_InitStructure.DMA_Mode =DMA_Mode_Normal; //DMA_Mode_Normal 正常模式,只传送一次; DMA_Mode_Circular:循环模式,不停的传送; DMA_InitStructure.DMA_Priority =DMA_Priority_Medium; DMA_InitStructure.DMA_M2M =DMA_M2M_Disable; //DMA_M2M_Enable ;DMA_M2M_Disable DMA_Init(DMA1_Channel4,&DMA_InitStructure); DMA_ITConfig(DMA1_Channel4,DMA_IT_TC, ENABLE); //传输完成则进入DMA1_Channel4中断; USART_DMACmd(USART1,USART_DMAReq_Tx,ENABLE); //采用DMA方式发送 DMA_Cmd(DMA1_Channel4,ENABLE); } //主函数中的循环 while(1) { usart1SendGeneralStr(); }[/mw_shl_code]
原子哥,为什么我这样只能发送一次,不会在main函数中循环不停地发送呢?找了半天还是没找出原因,谢谢。
回复 支持 反对

使用道具 举报

1

主题

32

帖子

0

精华

初级会员

Rank: 2

积分
57
金钱
57
注册时间
2014-12-16
在线时间
0 小时
发表于 2015-1-28 16:20:54 | 显示全部楼层
回复【58楼】wyfzgybd:
---------------------------------
 DMA_InitStructure.DMA_Mode                     =DMA_Mode_Normal;              //DMA_Mode_Normal 正常模式,只传送一次;
是不是这里有问题,第一次的时候 DMA_InitStructure.DMA_Mode是没有设置的,到第二次的时候已经有值了,而且它默认只传一次,所以就不传了
正在入门.........
回复 支持 反对

使用道具 举报

4

主题

18

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
216
金钱
216
注册时间
2015-3-23
在线时间
68 小时
发表于 2015-4-24 12:11:47 | 显示全部楼层
好资料啊!谢谢啦!
回复 支持 反对

使用道具 举报

4

主题

11

帖子

0

精华

新手上路

积分
47
金钱
47
注册时间
2014-10-8
在线时间
0 小时
发表于 2015-5-7 20:42:26 | 显示全部楼层
回复【2楼】正点原子:
---------------------------------
这个程序测了一下1秒能采150个数据    扫描模式+连续转换模式  采样率可以改吗?
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2015-5-8 00:34:31 | 显示全部楼层
回复【61楼】逍遥剑客:
---------------------------------
这个不是我写的。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

23

主题

87

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
306
金钱
306
注册时间
2014-9-24
在线时间
39 小时
发表于 2015-6-21 15:56:06 | 显示全部楼层
请问楼主,你有没有发现你的程序在DMA转换完成之后,DMA中的CNDTR寄存器不为0
回复 支持 反对

使用道具 举报

11

主题

52

帖子

0

精华

初级会员

Rank: 2

积分
89
金钱
89
注册时间
2015-7-6
在线时间
5 小时
发表于 2015-8-10 15:14:30 | 显示全部楼层
感谢分享!!
回复 支持 反对

使用道具 举报

1

主题

2

帖子

0

精华

新手入门

积分
26
金钱
26
注册时间
2015-9-6
在线时间
0 小时
发表于 2015-9-6 15:42:25 | 显示全部楼层
下载的ADC+DMA+串口里由于 #include "stm32f10x_lib.h"是用以前的库,在keil4报错有什么好的解决方法不,不大改的那种。
回复 支持 反对

使用道具 举报

1

主题

7

帖子

0

精华

新手上路

积分
33
金钱
33
注册时间
2015-5-7
在线时间
1 小时
发表于 2015-10-16 10:20:27 | 显示全部楼层
u16 ADC_Buf[512]; 
这里的512是不是打错了??应该是5吧,不然一次就是读512个数据。
回复 支持 反对

使用道具 举报

17

主题

170

帖子

0

精华

高级会员

Rank: 4

积分
562
金钱
562
注册时间
2018-7-8
在线时间
118 小时
发表于 2018-11-15 16:37:24 | 显示全部楼层
正点原子 发表于 2012-3-18 00:59
回复【19楼】冰是睡着的水:
---------------------------------
1,均值滤波.
2,ASCII的0的内码,就是0X30.

学习了。。
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-21 22:00

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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