摘要:對于電壓或者電流連續變化的信號,就需要通過模數轉換電路,變成單片機可以識別的數字電平信號。目前來說,常見的有兩種方式,一種是并行比較,一種是逐次比較。具有成本低元件簡單等優勢,而且容易做出高精度的轉換器,所以被廣泛使用。
模擬量—>數字量(ADC模塊)
5V 單片機 CPU 電路是二進制的,運算過程中,電壓只有2種:高電平 5V 和低電平 0V 。對于電壓或者電流連續變化的信號,就需要通過模數轉換電路,變成單片機可以識別的數字電平信號。 MP3 就是用 ADC 采樣保存的失真文件。
模擬量變成數字量,通常都是用比較器來負責轉換。目前來說,常見的有兩種方式,一種是并行比較,一種是逐次比較。
**并行比較器:**速度比較快,但是采用的元件非常非常多。成本會非常高。所以,實用性不是很廣泛
**逐次比較器:**通過反饋控制,多次運算后,轉換出結果。具有成本低、元件簡單等優勢,而且容易做出高精度的轉換器,所以被廣泛使用。
先來玩個游戲 :狗蛋拿了些花生米,跟你說,想吃就要先猜對有多少個。告訴你最多是 255 顆,你猜的時候,可以告訴你多了或者少了。那么,怎么猜才能最快猜出花生米的數量?
猜的時候,為了方便計算, 我們多加 0.5 顆花生米。
==第一步:==猜 255 ÷ 2 +0.5=128. 狗蛋告訴你,多了 (0) 。
第二步:猜 128 ÷ 2=64. 狗蛋告訴你,少了 (1)。
第三步:猜 (128 + 64) ÷ 2=96. 狗蛋 告訴 你,多了 (0) 。
第四步:猜 (96 + 64) ÷ 2=80. 狗蛋 告訴 你,少了 (1) 。
第五步:猜 (96 + 80) ÷ 2=88. 狗蛋 告訴 你,少了(1)。
第六步:猜 (96 + 88) ÷ 2=92. 狗蛋 告訴 你,多了(0)。
第七步:猜 (92+ 88) ÷ 2=90. 狗蛋 告訴 你,多了(0) 。
第八步:猜 (90+ 88) ÷ 2=89. 狗蛋 告訴 你,猜對 (?) 。
得出結果: 如果不加 0.5 ,實際計算公式得結果是 88.65234375 。實際上88.65比89小所以是 1
四舍五入, 89>88.65, 取 ?= 1 ;得出結果就是 0 1 0 1 1 0 0 1 =89=0x59;
1.ADC口配置成ADC輸入模式或者高阻模式
2.ADC控制寄存器:ADC_CONTR.控制電源,轉換速度,標志位,啟動位,通道選擇[2:0]
3.ADC采樣結果輸出寄存器ADC_RES,ADC_RESL。可以是[1:0]+[7:0],也可以是[7:0]+[1:0].
4.ADC轉換,跟中斷有關的寄存器IE
5.輔助寄存器AUXR1,主要是控制結果寄存器的存儲格式
我是準備用ADC0來檢測電池電壓的,具體看老師需求,然后把示數顯示到數碼管上面,因為之前我出過數碼管博客,大家可能還有點印象,不知道的看真正的數碼管
//ADC初始化void ADC_Init(){ P1M1 |= 0x0f; P1M0 &= ~0x0f;//P1.0腳ADC0 P1ASF |= 0x0f;// P1M1 |= 0x02;// P1M0 &= ~0x02;//P1.1腳ADC1// P1ASF |= 0x02; CLK_DIV |= 0x20; ADC_RES = 0; ADC_RESL = 0;}
//ADC讀數據底層驅動void ADC_Read_Data_Drive(){ //轉換之前先把轉換結果寄存器清零 ADC_RES = 0; ADC_RESL = 0; //啟動轉換 ADC_CONTR = 0x88;//轉換速度我用最慢的 //等到ADC_FLAG為1 while(!(ADC_CONTR&0x10)); //然后把數據傳到緩存變量里面去 ADC_Read_Data = ADC_RES<<8; ADC_Read_Data = ADC_Read_Data+ADC_RESL; }
采集電壓
#include "all.h"//有數據那我們就得存u16 xdata ADC_Read_Data = 0;u16 xdata ADC_Filter_Data = 0;//ADC初始化void ADC_Init(){ P1M1 |= 0x0f; P1M0 &= ~0x0f;//P1.0腳ADC0 P1ASF |= 0x0f;// P1M1 |= 0x02;// P1M0 &= ~0x02;//P1.1腳ADC1// P1ASF |= 0x02; CLK_DIV |= 0x20; ADC_RES = 0; ADC_RESL = 0;}//ADC讀數據底層驅動void ADC_Read_Data_Drive(){ //轉換之前先把轉換結果寄存器清零 ADC_RES = 0; ADC_RESL = 0; //啟動轉換 ADC_CONTR = 0x88;//轉換速度我用最慢的 //等到ADC_FLAG為1 while(!(ADC_CONTR&0x10)); //然后把數據傳到緩存變量里面去 ADC_Read_Data = ADC_RES<<8; ADC_Read_Data = ADC_Read_Data+ADC_RESL; }//全局的ADC濾波數據結構體指針ADC_Data* adc_filter;//ADC濾波數據底層驅動void ADC_Filter_Data_Drive(){ /*u16 ADC_Min = 0; u16 ADC_Max = 0; u16 ADC_Tmp = 0; u16 ADC_Result = 0;*/ //設置兩個循環變量 u8 i = 0; u8 j = 0; ADC_Filter_Data = 0; ADC_Read_Data_Drive(); for(i = 0;i<4;i++)//外層8次循環 { adc_filter->ADC_Result = 0; adc_filter->ADC_Min = adc_filter->ADC_Max = ADC_Read_Data; for(j = 0;j<4;i++)//內層8次循環 { adc_filter->ADC_Tmp = ADC_Read_Data; if (adc_filter->ADC_Tmp < adc_filter->ADC_Min) { adc_filter->ADC_Result += adc_filter->ADC_Tmp; adc_filter->ADC_Min = adc_filter->ADC_Tmp; } else if (adc_filter->ADC_Tmp > adc_filter->ADC_Max) { adc_filter->ADC_Result += adc_filter->ADC_Tmp; adc_filter->ADC_Max = adc_filter->ADC_Tmp; } else { adc_filter->ADC_Result += adc_filter->ADC_Tmp; } } adc_filter->ADC_Result /= 4; ADC_Filter_Data += adc_filter->ADC_Result; } ADC_Filter_Data /= 4;}
#ifndef ADC_Drive#define ADC_Drivetypedef struct ADC_Filter_Data{ u16 ADC_Min; //ADC最小值 u16 ADC_Max; //ADC最大值 u16 ADC_Tmp; //ADC臨時值 u16 ADC_Result; //ADC結果} ADC_Data;//外部聲明extern void ADC_Init();extern void ADC_Read_Data_Drive();extern void ADC_Filter_Data_Drive();extern u16 xdata ADC_Read_Data;extern u16 xdata ADC_Filter_Data;#endif
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/124049.html
摘要:復位后初值是子函數調用,中斷響應過程調用子函數處理中斷響應的時候,程序計數器的值以及相關數據會先壓入堆棧,然后去處理子函數中斷服務。聯動文章身家過億的帝都富豪對小碼農說你時空復雜度會了嗎 ...
摘要:行列總共使用個口,可以掃描個按鍵的開關狀態,這就是矩陣鍵盤的優勢。口之間必須串聯電阻。 文章目錄 小碼農為了總裁,咳咳,為了知識敢說按鍵不會嗎?==**帝都富豪與...
摘要:否則可能會導致電平顛倒完美的計數糟糕的線條再來一個測試組我們來實現一個呼吸燈的效果呼吸燈波形為了賢淑妻子,咳咳,賢淑才女,小碼農必定讓控制時間什么是脈寬調制中間動的線是電流線,電流通斷,電流小就暗,電流大就亮。 ...
摘要:目前,所有型號串口的輸入是輸出是。串口全雙工通信是沒有時鐘脈沖的,只能依靠晶振脈沖定時器的溢出脈沖。中斷中讀取,清標志,然后返回給計算機,等待發送完畢防重疊最少時間次位定時器時間。實現燒錄程序的目的。 ...
閱讀 1255·2021-11-22 13:54
閱讀 1440·2021-11-22 09:34
閱讀 2721·2021-11-22 09:34
閱讀 4033·2021-10-13 09:39
閱讀 3352·2019-08-26 11:52
閱讀 3376·2019-08-26 11:50
閱讀 1543·2019-08-26 10:56
閱讀 1925·2019-08-26 10:44