久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 10429|回復: 20
打印 上一主題 下一主題
收起左側

STC8a單片機雙通道AD采集問題

  [復制鏈接]
跳轉到指定樓層
樓主
ID:282747 發表于 2019-3-20 17:27 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
10黑幣
單片機 stc8a8k
2路電壓采集異常,求大佬指導一下程序,哪邊有問題?
調試設置單通道,能采集單通道電壓,設置雙通道,2個都采集不了求大佬指導一下
#include"stc8f.h"#include <intrins.h>
#include <stdio.h>
#define VCC  2.50
#define uint unsigned int
#define uchar  unsigned char

#define ADC_CHANNEL0         0x00            //轉換通道P1.0
#define ADC_CHANNEL1         0x01            //轉換通道P1.1
#define ADC_CHANNEL2         0x02            //轉換通道P1.2
#define ADC_CHANNEL3         0x03            //轉換通道P1.3
#define ADC_CHANNEL4         0x04            //轉換通道P1.4
#define ADC_CHANNEL5         0x05            //轉換通道P1.5
#define ADC_CHANNEL6         0x06            //轉換通道P1.6
#define ADC_CHANNEL7         0x07            //轉換通道P1.7
#define ADC_CHANNEL8         0x08            //轉換通道P0.0
#define ADC_CHANNEL9         0x09            //轉換通道P0.1
#define ADC_CHANNEL10         0x0a            //轉換通道P0.2
#define ADC_CHANNEL11         0x0b            //轉換通道P0.3
#define ADC_CHANNEL12         0x0c            //轉換通道P0.4
#define ADC_CHANNEL13         0x0d            //轉換通道P0.5
#define ADC_CHANNEL14         0x0e            //轉換通道P0.6

uint a;
bit flag_1= 0;bit flag_2=0;bit flag_3=0; bit flag_4=0;
uchar count=0;  // 變量計數器


void Delay500ms()                //@11.0592MHz
{
        unsigned char i, j, k;

        i = 29;
        j = 14;
        k = 54;
        do
        {
                do
                {
                        while (--k);
                } while (--j);
        } while (--i);
}


void Delay1ms(a)                //@11.0592MHz
{
        unsigned char i, j;

        i = 15;
        j = 90;
        do
        {
                while (--j);
        } while (--i);
}





void UartInit(void)                //9600bps@11.0592MHz
{
        SCON = 0x50;                //8位數據,可變波特率
        AUXR |= 0x40;                //定時器1時鐘為Fosc,即1T
        AUXR &= 0xFE;                //串口1選擇定時器1為波特率發生器
        TMOD &= 0x0F;                //設定定時器1為16位自動重裝方式
        TL1 = 0xE0;                //設定定時初值
        TH1 = 0xFE;                //設定定時初值
        ET1 = 0;                //禁止定時器1中斷
        TR1 = 1;                //啟動定時器1
        TI=1;
}

void ADC_init()
  {
   P1M0 = 0x00;
   P1M1 = 0xff;
   P0M0 = 0x00;
   P0M1 = 0xff;
   ADCCFG = 0x0f;
   ADC_CONTR|=0x80; //開啟AD轉換電源
   Delay1ms(2);
  }

uint ADC_GetResult(unsigned char ch)
{
   uint ADC_Value=0;
   ADC_RES=0;
   ADC_RESL=0;
   ADC_CONTR|= ch;
   ADC_CONTR|= 0x40;//啟動AD轉換
   Delay1ms(1);
   while(!(ADC_CONTR&0x20));
   ADC_CONTR&=~0x20;                  //清完成標志
   ADC_Value=ADC_RES;                                                                //讀取ADC高八位
  ADC_Value=(ADC_Value<<8)|ADC_RESL;//讀取ADC低四位,并且數據合并
  ADC_Value>>=4;                                                                                //數據右移4位,高12位為所需要的數據
  return ADC_Value;  

  }

void Timer0Init(void)                //1毫秒@11.0592MHz
{
        AUXR |= 0x80;                //定時器時鐘1T模式
        TMOD &= 0xF0;                //設置定時器模式
        TL0 = 0xCD;                //設置定時初值
        TH0 = 0xD4;                //設置定時初值
        TF0 = 0;                //清除TF0標志
        TR0 = 1;                //定時器0開始計時
        EA = 1;                        //開總中斷
        ET0 = 1;           //開定時器T1中斷
}

void Timer0(void) interrupt 1
  {
   TL0 = 0xCD;                //設置定時初值
   TH0 = 0xD4;                //設置定時初值
        count++;                 //每次中斷加1
   if(count>=20)         //如果計數到了100ms
         {
           flag_1= 1;
         }
   if (count>=40)
     {
           flag_2= 1;
         }
   if (count>=60)
          {
           flag_3= 1;
          }
   if (count>=80)
      {
           count=0;
           flag_4= 1;
          }
   }


void main()
{
  float Vin1,Vin2;
  uint AD1=0;
  uint AD2=0;
  ADC_init();
  Timer0Init();
  UartInit();
  printf("串口初始化完畢");
  while(1)
  {
    if(flag_1==1)
          {        
           flag_1=0;
           AD1=ADC_GetResult(ADC_CHANNEL6);
                }                           
        if(flag_2==1)
          {
           flag_2=0;
         Vin1 = VCC*AD1/4090;
          }
        if(flag_3==1)
          {        
           flag_3=0;
          AD2=ADC_GetResult(ADC_CHANNEL5);
          }                           
         if(flag_4==1)
          {        
           flag_4=0;
         Vin2 = VCC*AD2/4090;
           }
        printf ("%.2f,%.2f",Vin1,Vin2);
        Delay500ms();
   }
}

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏2 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:491577 發表于 2019-3-20 21:18 | 只看該作者
紅色部分有問題,應該用else if語句,先寫:
if (count>=80)

flag_4= 1;

else if (count>=60)

flag_3= 1;

......
void Timer0(void) interrupt 1
  {
   TL0 = 0xCD;                //設置定時初值
   TH0 = 0xD4;                //設置定時初值
        count++;                 //每次中斷加1
  if(count>=20)         //如果計數到了100ms
         {
           flag_1= 1;
         }
   if (count>=40)
     {
           flag_2= 1;
         }
   if (count>=60)
          {
           flag_3= 1;
          }
   if (count>=80)
      {
           count=0;
           flag_4= 1;

          }
   }
回復

使用道具 舉報

板凳
ID:282747 發表于 2019-3-20 23:40 來自手機 | 只看該作者
hhh402 發表于 2019-3-20 21:18
紅色部分有問題,應該用else if語句,先寫:
if (count>=80)


不行啊,朋友這樣改,連子程序都進不去
回復

使用道具 舉報

地板
ID:282747 發表于 2019-3-21 00:10 來自手機 | 只看該作者
自己解決了,多通道采集需要把原通道清零
回復

使用道具 舉報

5#
ID:401564 發表于 2019-3-21 09:57 | 只看該作者
shijie240 發表于 2019-3-21 00:10
自己解決了,多通道采集需要把原通道清零

緩存要清除而已,兩個ADC結果保存的寄存器不需要清除的,一次完整的ADC運行之后,這兩個寄存器自然就保存了本次ADC的結果了
回復

使用道具 舉報

6#
ID:282747 發表于 2019-3-21 11:46 | 只看該作者
Y_G_G 發表于 2019-3-21 09:57
緩存要清除而已,兩個ADC結果保存的寄存器不需要清除的,一次完整的ADC運行之后,這兩個寄存器自然就保存了 ...

ADC_CONTR|= ch;通道選擇要清除上一個選擇的通道,要不然進不了下一個,多通道循環采集不了
回復

使用道具 舉報

7#
ID:401564 發表于 2019-3-21 16:29 | 只看該作者
shijie240 發表于 2019-3-21 11:46
ADC_CONTR|= ch;通道選擇要清除上一個選擇的通道,要不然進不了下一個,多通道循環采集不了

ADC_CONTR|= ch
這個是通道選擇,單片機只有一個ADC電路,但它有15個ADC的IO端口,所以,你是一定要選擇哪個通道進行ADC才能正確的進行ADC,它實際上是一個類似選擇開關的樣子
其實我看不懂你的程序,我是用匯編的,但我感覺你的代碼是有點多了,就是匯編也用不了那么多的代碼量的,更何況是C呢
回復

使用道具 舉報

8#
ID:282747 發表于 2019-3-25 11:42 | 只看該作者
Y_G_G 發表于 2019-3-21 16:29
ADC_CONTR|= ch
這個是通道選擇,單片機只有一個ADC電路,但它有15個ADC的IO端口,所以,你是一定要選擇哪個 ...

我這個是測試代碼,隨便編的
回復

使用道具 舉報

9#
ID:394367 發表于 2019-3-29 13:45 | 只看該作者
學習了,樓主,我也正用到
回復

使用道具 舉報

10#
ID:375092 發表于 2019-3-30 11:20 | 只看該作者
樓主,你不把這個寫在中斷里面,直接在主函數中調用一個函數直接在主函數中直接顯示會比較好,我之前都有做過,最多幾毫秒的延時就夠了,直接改變通道就行了
回復

使用道具 舉報

11#
ID:282747 發表于 2019-4-3 09:50 | 只看該作者
609763691 發表于 2019-3-30 11:20
樓主,你不把這個寫在中斷里面,直接在主函數中調用一個函數直接在主函數中直接顯示會比較好,我之前都有做 ...

我采集的13個通道數據,必須精確的微秒,這個是我的測試程序,項目是在子程序里面的
回復

使用道具 舉報

12#
ID:272876 發表于 2019-4-23 15:43 | 只看該作者
609763691 發表于 2019-3-30 11:20
樓主,你不把這個寫在中斷里面,直接在主函數中調用一個函數直接在主函數中直接顯示會比較好,我之前都有做 ...

分下下你的程序唄大佬
回復

使用道具 舉報

13#
ID:272876 發表于 2019-4-23 15:45 | 只看該作者
我想寫一個7通道的  該怎么搞啊  能不能分享下你的程序
回復

使用道具 舉報

14#
ID:272876 發表于 2019-4-24 15:35 | 只看該作者
shijie240 發表于 2019-3-21 00:10
自己解決了,多通道采集需要把原通道清零

怎么清零原通道 我試了下 沒成功
回復

使用道具 舉報

15#
ID:272876 發表于 2019-4-24 17:25 | 只看該作者
609763691 發表于 2019-3-30 11:20
樓主,你不把這個寫在中斷里面,直接在主函數中調用一個函數直接在主函數中直接顯示會比較好,我之前都有做 ...

能分享下程序嗎
回復

使用道具 舉報

16#
ID:157579 發表于 2019-7-10 16:11 | 只看該作者
您好,關于STC8A單片機雙通道AD采集源碼,您這邊能不能分享一下。
回復

使用道具 舉報

17#
ID:581932 發表于 2019-7-10 21:13 | 只看該作者
樓主。怎么清零通道?我也遇到這個問題了。
我的ADC函數和你差不多的。
uint GetADCresults(uchar adcch)
{
        ADC_RES  = 0;
        ADC_RESL = 0;

        ADC_CONTR |= ADC_START|adcch;               //¿aÆôADC
        Delay(10);
        while(!(ADC_CONTR & ADC_FLAG));            
        ADC_CONTR &= ~ADC_FLAG;                  
        ADC_CONTR &= ~ADC_START;                  
       
        return (ADC_RES<<8 | ADC_RESL);
}
主函數里面調用函數,傳通道值獲得ADC結果,但是兩個通道得到的數據是一樣的。
DZ_Data = GetADCresults(ADCch_dz);
GD_Data = GetADCresults(ADCch_gd);

這兩句之間做了500ms 的延時,結果取出來還是差不多的,有時候還一樣。
請幫忙!~
回復

使用道具 舉報

18#
ID:581305 發表于 2019-7-18 10:56 | 只看該作者
echowilson 發表于 2019-7-10 21:13
樓主。怎么清零通道?我也遇到這個問題了。
我的ADC函數和你差不多的。
uint GetADCresults(uchar adcch) ...

ADC_CONTR |= ADC_START|adcch; 這里有問題
回復

使用道具 舉報

19#
ID:117310 發表于 2019-9-12 23:36 | 只看該作者
我也是做八通道順序采集,開始沒有在循環結束時候加禁用ADC指令時候,第八通道電壓不對,而且零點也有十幾個字,加了禁用后,零點只有一個字,但是第一個通道沒有數據,始終是0,不知道怎么回事了?


        ADCCFG = 0x20; //設置ADC結果右對齊,轉換速度為最快
        for (i = 0; i < 8; i++)
            {
                ADC_CONTR = (0x80 | i );                       //使能ADC模塊并設置通道
                ADC_CONTR |= 0x40;                          //啟動AD轉換
                _nop_();
                _nop_();
                while (!(ADC_CONTR & 0x20));                //查詢ADC完成標志
                ADC_CONTR &= ~0x20;                         //清完成標志
                ADC[i] = (ADC_RES << 8) | ADC_RESL;
            }
                ADC_CONTR = 0x00;//禁用ADC模塊
            //8個AD結果顯示輸出
        for (i = 0; i < 8; i++)
            {
                UartSend(ADC[i]>>8);
                UartSend(ADC[i]);
            }            
        UartSendStr("\r\n");//輸出回車換行符
回復

使用道具 舉報

20#
ID:189860 發表于 2021-10-26 16:27 | 只看該作者
回復19#,你在選擇通道的時候要先將ADC_CONTR &=0XF0;這樣將低四位清了,再或上通道號才能真正的到你要的通道。不然一直或或的,你想想或成什么通道了?
回復

使用道具 舉報

21#
ID:562627 發表于 2022-9-19 17:17 | 只看該作者
6726234500 發表于 2019-4-24 15:35
怎么清零原通道 我試了下 沒成功

uint ADC_GetResult(unsigned char ch)
{
   uint ADC_Value=0;
   ADC_RES=0;
   ADC_RESL=0;
   ADC_CONTR|= ch;
   ADC_CONTR|= 0x40;//啟動AD轉換
   Delay1ms(1);
   while(!(ADC_CONTR&0x20));
   ADC_CONTR&=~0x20;                  //清完成標志
   ADC_Value=ADC_RES;                                                                //讀取ADC高八位
  ADC_Value=(ADC_Value<<8)|ADC_RESL;//讀取ADC低四位,并且數據合并
  ADC_Value>>=4;                                                                                //數據右移4位,高12位為所需要的數據
  ADC_RES=0;                           //清除ADC高8位數據
ADC_RESL=0;                           //清除ADC低4位數據
  return ADC_Value;  

  }

即轉換1次清除1次數據
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 日韩中文av在线 | 日韩成人av在线播放 | 在线精品国产 | 欧美日韩在线精品 | 精品一区二区三区av | 日本一区二区三区四区 | 欧美日韩1区 | 亚洲高清在线观看 | 国产丝袜一区二区三区免费视频 | 日韩午夜影院 | 日韩一级精品视频在线观看 | 亚洲一区电影 | 狠狠av| 伦理午夜电影免费观看 | 亚洲精品久久久久久首妖 | 日韩成人一区二区 | 国产精品久久久久久久久图文区 | 久久精品国产久精国产 | 亚洲日本成人 | 精品久久久久久国产 | 久久久天天| 国产福利在线看 | 亚洲日本中文 | 亚洲瑟瑟| 欧州一区| 欧美激情综合 | 日韩免费一级 | 欧美中文 | 国产精品成人在线观看 | 国产精品一区二区在线播放 | 亚洲成人av在线播放 | 久久精品国产久精国产 | 精品美女视频在线观看免费软件 | h视频免费在线观看 | 成人欧美在线 | 国产目拍亚洲精品99久久精品 | 国产xxx在线观看 | 日批免费在线观看 | 99热播精品 | 成人三级在线播放 | 久久www免费视频 |