OpenEdv-开源电子网

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

求解 STM8S,配置多通道ADC方法

[复制链接]

5

主题

19

帖子

0

精华

初级会员

Rank: 2

积分
106
金钱
106
注册时间
2016-7-23
在线时间
13 小时
发表于 2016-8-2 09:48:34 | 显示全部楼层 |阅读模式
1金钱
想做一个小东西,,,利用两个ADC通道,分别采集两个按键电压,进行对比操作
但是始终没有掌握 配置方法,求大神解答,谢谢了,还请不要鄙视菜鸟

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

使用道具 举报

5

主题

19

帖子

0

精华

初级会员

Rank: 2

积分
106
金钱
106
注册时间
2016-7-23
在线时间
13 小时
 楼主| 发表于 2016-8-2 12:15:27 | 显示全部楼层
int OneChannelGetADValue(ADC1_Channel_TypeDef ADC1_Channel,ADC1_SchmittTrigg_TypeDef ADC1_SchmittTriggerChannel)
{
     unsigned int ADConversion_Value;
     
     ADC1_Init(ADC1_CONVERSIONMODE_CONTINUOUS , ADC1_Channel, ADC1_PRESSEL_FCPU_D18,\
      ADC1_EXTTRIG_TIM, DISABLE, ADC1_ALIGN_RIGHT, ADC1_SchmittTriggerChannel,DISABLE);
     ADC1_Cmd(ENABLE);
     ADC1_StartConversion();
     ADConversion_Value = ADC1_GetConversionValue();
     return ADConversion_Value;
}
回复

使用道具 举报

5

主题

19

帖子

0

精华

初级会员

Rank: 2

积分
106
金钱
106
注册时间
2016-7-23
在线时间
13 小时
 楼主| 发表于 2016-8-3 09:22:57 | 显示全部楼层
完整实例里面有可参考部分

/****************目前已经可以通过手势操控电机方向**********************/
/***********PB高四位接电机,PB1、PB3接红外对管**************************************************/
/*******串口发送0,电机顺时针转动,发送1,逆时针********/
#include"stm8s.h"//头

int i,j,m,n,p,q,temp;
u16 x;
unsigned char  CCW[8]={0x80,0xc0,0x04,0x60,0x20,0x30,0x10,0x90}; //
unsigned char  CW[8]={0x90,0x10,0x30,0x20,0x60,0x04,0xc0,0x80};//正时钟旋转相序表

int box[2];
void UART2Conf(void);
void USART_SendByte(u8 Data);
void USART_Write(u8*data,u16 len);
void GPIO_configuration();
void judge();
int  OneValue(ADC1_Channel_TypeDef ADC1_Channel,ADC1_SchmittTrigg_TypeDef ADC1_SchmittTriggerChannel);
void delay(u32 i)
{
  u32 j;
  for(j=0;j<i;j++)
  {;}
}




  void main()
  {
      GPIO_configuration();
      UART2Conf();
   
  while(1)
  {
   
   //ADC1_DeInit();

    //judge();

   while(p)
   {
              for(int i=0;i<8;i++)
                {//GPIO_Write(GPIOD, CW[i]);
                GPIO_Write(GPIOB, CCW[i]);
              delay(300);
        }//慢速正转
        USART_Write("顺时针转动方向\n",16);
        judge();
        if(p == 0)
          break;
        
   
   }
   //judge();
   while(q){

              for(int i=0;i<8;i++)
                {//GPIO_Write(GPIOD, CW[i]);
                GPIO_Write(GPIOB, CW[i]);
              delay(300);
   
              }//慢速正转
              USART_Write("逆时针转动方向\n",16);
              judge();
                if(q == 0)
                break;
              
        }
    }

  }



void judge(){
        i=OneValue(0x01,0x01);
    box[0] = i;
    delay(10);                              //两次之间好像必须有延时 不然会错误  有待考证
    j=OneValue(0x03,0x03);
    box[1] = j;
    delay(10);
  
  if(i <= 500 && j > 500){
         
          while(1){
               temp = OneValue(0x01,0x01);
               delay(10);
               if(temp <= 500){}
               else
                 break;
          }
          while(1){
              m=OneValue(0x01,0x01);
              delay(10);                              //两次之间好像必须有延时 不然会错误  有待考证
              n=OneValue(0x03,0x03);
              delay(10);
              if(m > 500 && n <= 500){
                p = 1;
                q = 0;
                break;
         
              
          }      
      }
   }

    if(i > 500 && j <= 500){
      while(1){
               temp = OneValue(0x03,0x03);
               delay(10);
               if(temp <= 500){}
               else
                 break;
          }
      
      
          while(1){
              m=OneValue(0x01,0x01);
              delay(10);                              //两次之间好像必须有延时 不然会错误  有待考证
              n=OneValue(0x03,0x03);
              delay(10);
              if(m <= 500 && n > 500){
                p = 0;
                q = 1;
                break;
          }   
      }
    }

}

















void GPIO_configuration()
{
  GPIO_DeInit(GPIOC);
  GPIO_Init(GPIOC,GPIO_PIN_LNIB,GPIO_MODE_OUT_PP_HIGH_FAST);
  GPIO_DeInit(GPIOB);
  GPIO_Init(GPIOB, GPIO_PIN_HNIB, GPIO_MODE_OUT_PP_LOW_FAST);

  
}

void UART2Conf(void)
  {
  UART2_DeInit();
  
   UART2_Init(9600 ,
              UART2_WORDLENGTH_8D,
              UART2_STOPBITS_1 ,
              UART2_PARITY_NO,
              UART2_SYNCMODE_CLOCK_DISABLE,
              UART2_MODE_TXRX_ENABLE);
   UART2_ITConfig(UART2_IT_RXNE,ENABLE);
   UART2_Cmd( ENABLE);
   enableInterrupts();
  }

#pragma vector=23
__interrupt void EXIT_UART2_IRQHander(void)//中断函数
{
  x=UART2_ReceiveData8();
  if(x == 0){
      p = 1;
      q = 0;
  }
  if(x == 1){
      p = 0;
      q = 1;
  }
  UART2_ClearITPendingBit(UART2_IT_RXNE);
}


void USART_SendByte(u8 Data)
  {
  while(!UART2_GetFlagStatus(UART2_FLAG_TXE));//发送缓冲区空闲标志位
  UART2_SendData8(Data);
  }

void USART_Write(u8*data,u16 len)
  {
  u16 i;
  for(i=0;i<len;i++)
    {
      while(!UART2_GetFlagStatus(UART2_FLAG_TXE));//发送缓冲区空闲标志位
      UART2_SendData8(data[i]);
    }  
  }

int OneValue(ADC1_Channel_TypeDef ADC1_Channel,ADC1_SchmittTrigg_TypeDef ADC1_SchmittTriggerChannel)
{
     unsigned int ADConversion_Value;
     
     ADC1_Init(ADC1_CONVERSIONMODE_CONTINUOUS , ADC1_Channel, ADC1_PRESSEL_FCPU_D18,\
      ADC1_EXTTRIG_TIM, DISABLE, ADC1_ALIGN_RIGHT, ADC1_SchmittTriggerChannel,DISABLE);
     ADC1_Cmd(ENABLE);
     ADC1_StartConversion();
     ADConversion_Value = ADC1_GetConversionValue();
     return ADConversion_Value;
}
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165309
金钱
165309
注册时间
2010-12-1
在线时间
2108 小时
发表于 2016-8-3 20:14:32 | 显示全部楼层
白彦辉 发表于 2016-8-3 09:22
完整实例里面有可参考部分

/****************目前已经可以通过手势操控电机方向**********************/ ...

自己解决了
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

5

主题

19

帖子

0

精华

初级会员

Rank: 2

积分
106
金钱
106
注册时间
2016-7-23
在线时间
13 小时
 楼主| 发表于 2016-8-4 17:36:46 | 显示全部楼层

瞎整的,目前需要的现象是出来了,就先贴个程序,没准有一点点参考价值
回复

使用道具 举报

3

主题

11

帖子

0

精华

新手上路

积分
43
金钱
43
注册时间
2016-2-18
在线时间
6 小时
发表于 2016-8-6 08:23:23 | 显示全部楼层
看到这个帖子好久了一直没有人来通俗易懂的解决,我的解决方法
u16 *ADC1_address =(u16 *)(ADC1_BaseAddress+10);  
/*
  把得到的数值送入这个指针里。
(  #define ADC1_BaseAddress        0x53E0  ) 把ADC 的地址给 一个  新地址。
  这句在STM8S.H 文件中 的 2473 行,如果你这个文件改动过就不一定了。
  也就是编译时正确的不会出错。
*/

void ADC_Init(void)
{
        ADC1->CR2 = 0x0A;//禁用外部触发,内部定时器事件,数据右对
        //齐,使用扫描模式
        ADC1->CR1 = 0x00;//时钟两分频,单次转换,禁用AD转换
        ADC1->CSR = 0x06; //无模拟看门狗事件,转换结束中断禁用,禁止AWD模拟看门狗中断,选择转换通道AIN0-AIN3
}

/**
   初始化,这个就不多说了, 我是想 用两个AD通道的 PB5  PB6 那扫描是实际上是从第一个通道开始 到你选择的通道结束
  怎么从选择的通道中取出 PB5  PB6 的值 这就是  +10 的原因。
  为什么要 +10  ????
  为什么 ???????
  这也是 这贴子一直回答不完善的地方。
  手册----模拟数字ADC  ----24.11  ADC_DBxRH  ADC_DBxRH  高低位数据缓冲器------  有个地址偏移量  :0x00+ 2* 通道号。
   明白没有 ?????
  我想要PB5 PB6  2*5 = 10  是不是
  (u16 *)(ADC1_BaseAddress+10);   
明白为什么加 10 了没有
  如何取出值 ????
  
**/


void ADC_CMD(u8 a)
{
        if(a!=0)
                ADC1->CR1 = 0x01; //开启AD转换
        else
                ADC1->CR1 = 0x00;
        delay(10);
}
/*
* 上面的就是启用不启用AD 转换
  自己看看 选用把。
*/


void GetAdcValue(u16 *ADCValues)
{
        u8 i;
//        ADC1->CSR &= 0x7F;
        ADC1->CSR = 0x06;  //0000 0110
        ADC1->CR1 |= 0x01; //0000 0001  开始转换
        while((ADC1->CSR & 0x80)==0);//转换结束
        /*
        ADC 采集使用两个通道
        */
        for(i=0;i<2;i++)
        {
                /*
                *(ADCValues+i*2) = 0x00FF&(*(ADC1_address+i*2));
                *(ADCValues+i*2) = (*(ADCValues+i*2)<<2)|(u16)(0x00FF&(*(ADC1_BaseAddress+i*2+1)));
                */
                *(ADCValues+i) = *(ADC1_address+i);
        }
}

/*
* 这就是把转换后的数值 给数组 ,需要用了,直接在数组中取值
  我觉的还没明白?????

*/



pressure1 = (ADCValues[0]/1024.0*5.0-0.175)*100;
                                                       
pressure2 = (ADCValues[1]/1024.0*5.0-0.175)*100;


/*
*  上面就是把得到的值取出来给变量 便于使用  
  pressure2 = ADCValues[1]/1024 *3.3 ;
   这样就得到了两个ADC 通道采集的值。
*/

实测,能得到2个值,不明白或说的有错误,望大家拍砖
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2024-11-23 05:21

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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