OpenEdv-开源电子网

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

为什么采样在定时器中断里面,就跑不出来,放主程序就可以?

[复制链接]

4

主题

25

帖子

0

精华

初级会员

Rank: 2

积分
135
金钱
135
注册时间
2012-9-16
在线时间
21 小时
发表于 2016-1-11 16:49:40 | 显示全部楼层 |阅读模式
1金钱
本帖最后由 zhangrufan 于 2016-1-11 19:33 编辑

#include "sys.h"               
#include "adc.h"




//ADC 外设的数据寄存器
#define ADC1_DR_Address    ((uint32_t)0x4001244C)
//ADC_DR(ADC规则数据寄存器),偏移量=0x4c  ADC1(0x40012400-0x400127ff)
//so ADC1_DR_Address=0x40012400+0x4c


//==========================================================================================
//ADC1_GPIO配置
void ADC1_GPIO_Configuration(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;
  //CH_10->PC0        CH_11->PC1        CH_12->PC2        CH_13->PC3
// RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOA, ENABLE);
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3;        
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;        //adc模式必须是模拟输入
  GPIO_Init(GPIOC, &GPIO_InitStructure);//执行上面的操作


}

//============================================================================================
//外设ADC,DMA时钟开启
void ADC1_RCC_Configuration(void)
{
  /* Enable ADC1 and GPIOC clock */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOA, ENABLE);
}

//===============================================================================================
//ADC1
//*
void ADC1_Init(void)
{
ADC_InitTypeDef ADC_InitStructure;

  //  * ADC1 configuration ------------------------------------------------------*
  //ADC独立模式         相对于双重模式
  ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
  //扫描模式用于多通道采集
  //而这次虽然也是多通道,单是采用非DMA模式,避免扫描模式因读取数据不及时而造成下一个通道的
  //数据覆盖本组数据,所以采用单次转换模式,即:采集完成本组后,并且数据被读走,才开始下一个
  //通道的工作
  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 =1;
  //执行
  ADC_Init(ADC1, &ADC_InitStructure);

  //配置ADC时钟,为PCLK2的8分频,即9Hz
  RCC_ADCCLKConfig(RCC_PCLK2_Div6);
  //  * ADC1 regular channel11 configuration
  //配置ADC1的通道11为55.5个采样周期
  //默认组,adc1 ,通道11,排序为1,55.5周期




  //----------------------使能温度传感器----------------------------
  ADC_TempSensorVrefintCmd(ENABLE);

   ADC_Cmd(ADC1, ENABLE);
  // ADC_SoftwareStartConvCmd(ADC1, DISABLE);
  // * Enable ADC1 reset calibration register *
  //使能ADC1的复位校准寄存器  
  ADC_ResetCalibration(ADC1);
  // * Check the end of ADC1 reset calibration register *
  //等待校准完成
  while(ADC_GetResetCalibrationStatus(ADC1));

  // * Start ADC1 calibration *
  //使能ADC1的开始校准寄存器
  ADC_StartCalibration(ADC1);
  //  * Check the end of ADC1 calibration *
  //等待完成
  while(ADC_GetCalibrationStatus(ADC1));


}
//*/
//===============================================================================================
//说明:3个通道的数据,分别按单次转换,完成,结果存放在全局变量ADCConvertedValue【】中,在主函数中显示
//
//*                                                                                                         
void GetADCSConvertedValues()
{
        uint8_t i;
        for(i=0;i<5;i++)
        {
                switch(i)
                {
                //----------------内部2路模拟输入--------------------------
                case 0:          //通道17(内部1.2v参照电压),规则组序号1,239.5clk,时间长采样准确
                ADC_RegularChannelConfig(ADC1, ADC_Channel_17,1, ADC_SampleTime_1Cycles5);break;
                case 1:         //通道16(内部温度),规则组1.。。。
                ADC_RegularChannelConfig(ADC1, ADC_Channel_16,1, ADC_SampleTime_1Cycles5);break;
                //----------------外部8路模拟输入 -------------------------
               case 2:         //通道4(外部可变电阻电压),规则组序号1,。。。
                ADC_RegularChannelConfig(ADC1, ADC_Channel_10,1, ADC_SampleTime_1Cycles5);break;
                case 3:         //通道5(外部可变电阻电压),规则组序号1,。。。
                ADC_RegularChannelConfig(ADC1, ADC_Channel_11,1, ADC_SampleTime_1Cycles5);break;
                case 4:         //通道6(外部可变电阻电压),规则组序号1,。。。
                ADC_RegularChannelConfig(ADC1, ADC_Channel_10,1, ADC_SampleTime_55Cycles5);break;

                }
                  ADC_Cmd(ADC1, ENABLE); //使能ADC1
                  ADC_SoftwareStartConvCmd(ADC1, ENABLE);        //启动上面设置好的一个通道,进行转换        
                   while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)==RESET);//等待EOC置位   放定时器理就卡在这里了
        //        ADCConvertedValue=ADC_GetConversionValue (ADC1);        //把数据寄存器的值读走
                AC_dataIN[i *64+cyc] = ADC_GetConversionValue (ADC1);
                ADC_ClearFlag(ADC1, ADC_FLAG_EOC);           //清除EOC,DMA时读数据,硬件自动清除
        ADC_SoftwareStartConvCmd(ADC1, DISABLE);
        ADC_Cmd(ADC1, DISABLE);
        }
}

怪事了,stm32f103ve 可以运行起来,103rb不行,怎么回事呢???
求高手解答。

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

72

主题

2711

帖子

2

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
3505
金钱
3505
注册时间
2014-8-4
在线时间
696 小时
发表于 2016-1-11 17:09:13 | 显示全部楼层
放定时器里面,你是把采样也放进去了么,如果都放进去了,进一次定时器采样一次,(仿真时)呈现的现象就是一直卡在while处
以我资质之鲁钝,当尽平心静气、循序渐进、稳扎稳打之力。
回复

使用道具 举报

72

主题

2711

帖子

2

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
3505
金钱
3505
注册时间
2014-8-4
在线时间
696 小时
发表于 2016-1-11 17:09:26 | 显示全部楼层
本帖最后由 龙之谷 于 2016-1-11 17:10 编辑

网速卡,发重复了.....
以我资质之鲁钝,当尽平心静气、循序渐进、稳扎稳打之力。
回复

使用道具 举报

72

主题

2711

帖子

2

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
3505
金钱
3505
注册时间
2014-8-4
在线时间
696 小时
发表于 2016-1-11 17:09:29 | 显示全部楼层
本帖最后由 龙之谷 于 2016-1-11 17:10 编辑

网速卡,发重复了.....
以我资质之鲁钝,当尽平心静气、循序渐进、稳扎稳打之力。
回复

使用道具 举报

69

主题

978

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3772
金钱
3772
注册时间
2015-4-26
在线时间
765 小时
发表于 2016-1-11 17:24:58 | 显示全部楼层
中断里边不要执行太多的代码
我有故事,你有酒吗
回复

使用道具 举报

4

主题

25

帖子

0

精华

初级会员

Rank: 2

积分
135
金钱
135
注册时间
2012-9-16
在线时间
21 小时
 楼主| 发表于 2016-1-11 18:32:15 | 显示全部楼层
龙之谷 发表于 2016-1-11 17:09
放定时器里面,你是把采样也放进去了么,如果都放进去了,进一次定时器采样一次,(仿真时)呈现的现象就是 ...

断开仿真 也是出来不了,
回复

使用道具 举报

4

主题

25

帖子

0

精华

初级会员

Rank: 2

积分
135
金钱
135
注册时间
2012-9-16
在线时间
21 小时
 楼主| 发表于 2016-1-11 19:44:24 | 显示全部楼层
来俩不甜的 发表于 2016-1-11 17:24
中断里边不要执行太多的代码

多通道,定时采样,,还有其他好的方法吗?
回复

使用道具 举报

69

主题

978

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3772
金钱
3772
注册时间
2015-4-26
在线时间
765 小时
发表于 2016-1-12 11:39:06 | 显示全部楼层
zhangrufan 发表于 2016-1-11 19:44
多通道,定时采样,,还有其他好的方法吗?

如果时间误差大,那就在定时器里边置位标志位,主循环中执行ad转换
我有故事,你有酒吗
回复

使用道具 举报

69

主题

978

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3772
金钱
3772
注册时间
2015-4-26
在线时间
765 小时
发表于 2016-1-12 11:41:29 | 显示全部楼层
刚看到你ad没中断啊,你在定时器里开启ad,在ad中断读数据呢                愚者千虑,随便一说,不负任何责任
我有故事,你有酒吗
回复

使用道具 举报

4

主题

25

帖子

0

精华

初级会员

Rank: 2

积分
135
金钱
135
注册时间
2012-9-16
在线时间
21 小时
 楼主| 发表于 2016-1-12 13:35:54 | 显示全部楼层
来俩不甜的 发表于 2016-1-12 11:41
刚看到你ad没中断啊,你在定时器里开启ad,在ad中断读数据呢                愚者千虑,随便一说,不负任何 ...

在定定时器里开启ad转换,然后读取转换值,
回复

使用道具 举报

4

主题

25

帖子

0

精华

初级会员

Rank: 2

积分
135
金钱
135
注册时间
2012-9-16
在线时间
21 小时
 楼主| 发表于 2016-1-12 13:37:05 | 显示全部楼层
来俩不甜的 发表于 2016-1-12 11:39
如果时间误差大,那就在定时器里边置位标志位,主循环中执行ad转换

如果定时300us采集一次的话,主程序 肯定会错过的,主程序不可能不跑别的程序,而且时间肯定超过300us 肯定行不通的吧
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-21 23:15

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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