㈠ 請問:單片機使用c語言編程,怎樣控制led燈的完成亮度強弱變換
/*********************************************************************
模擬PWM輸出控制燈的10個亮度級別
將定時器2溢出定為1/1200秒。每10次脈沖輸出一個120HZ頻率。
這每10次脈沖再用來控制高低電平的10個比值。
這樣,在每個1/120秒的方波周期中,我們都可以改變方波的輸出占空比,從而控制LED燈的10個級別的亮度。
*******************************************************************/
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
#include <reg52.h> //包括一個52標准內核的頭文件
sbit P10 = P1^0; //要控制的LED燈
sbit K1= P3^2; //按鍵K1
uchar scale;//用於保存占空比的輸出0的時間份額,總共10份
char code dx516[3] _at_ 0x003b;//這是為了模擬設置的
//模擬PWM輸出控制燈的10個亮度級別
void main(void) // 主程序
{
uint n;
RCAP2H =0xF3; //賦T2的預置值,溢出1次是1/1200秒鍾
RCAP2L =0x98;
TR2=1; //啟動定時器
ET2=1; //打開定時器2中斷
EA=1; //打開總中斷
while(1) //程序循環
{ ;//主程序在這里就不斷自循環,實際應用中,這里是做主要工作
for(n=0;n<50000;n++); //每過一會兒就自動加一個檔次的亮度
scale++;
if(scale==10)scale=0;
}
}
//1/1200秒定時器2中斷
timer2() interrupt 5
{
static uchar tt; //tt用來保存當前時間在一秒中的比例位置
TF2=0;
tt++;
if(tt==10) //每1/120秒整開始輸出低電平
{
tt=0;
if(scale!=0) //這里加這一句是為了消除滅燈狀態產生的鬼影
P10=0;
}
if(scale==tt) //按照當前占空比切換輸出高電平
P10=1;
}
――――――――――――――――――
在主程序中,每延時一段時間,就自動換一個占空比,以使亮度自動變化,方便觀察。
編譯,運行,看結果。
可以看到,LED的亮度以每種亮度1秒左右不斷變化,共有10個級別。
㈡ 關於51單片機做數碼電壓表時有段程序始終看不懂,請各位單片機高手們指點迷津
void也可以看成是數據類型,只是他是特殊的數據類型,這個類型就是「沒有東西」。
比如一個函數
int a(int b){ }
表示函數的參數是int類型的,返回值是int類型的。如果沒有返回值,也沒有參數,就都把類型名稱寫成void,既然沒有了,那麼也就沒有名稱了,所以b也可以省了,便成了 void a(void) { }。
函數的定義是很基本的c語言知識,這個說起來很啰嗦,隨便看書就能明白了。
void delay(void) 這個函數沒什麼特別意義,只是一個延時而已。因為單片機運行速度很快,數碼管也不是恆定的點亮一個,而是動態掃描的,就是說,先點亮一個位,然後關閉,點亮另一個位。這個過程很快,由於視覺暫留作用,人眼只能看到所有的位都是同時亮的,這個原理和放電影一樣,不過,如果點亮一個後,立即點亮另一個,會因為點亮時間太短,燈還沒全亮就滅了(本人估計的,但應該也是這樣),造成燈光太暗。所以要延時一下。
單片機的電源電壓是5V,那麼所有埠的承受電壓就一定是5V,如果是3.3V單片機,就一定只能承受3.3V,所以測量量程一定是0 至 5V。如果實際測量量程遠遠小於這個范圍,必須用放大器放大。如果量程大於這個范圍,必須分壓。
void convdata(unsigned char i)
這個 i 明顯就是數模轉換得到的結果,作為參數傳遞給這個函數處理。void以及函數參數等名詞術語,說起來就是一本教科書的量,請自行看書,這是很基本的。
dis[0] = i/51 以及後面的兩句,是一個數學問題。(dis[i]就是一個數組,這個不用多言)。
為什麼是51呢?看他的注釋「將0-255級換算成0.00-5.00的電壓數值」。
也就是說,如果測得的電壓是5V,那麼數模轉換的結果就是255,這是一個8位數的最大值,這個數模轉換器的最大值就是8位,所以5V的電壓轉換得到就是255.
然後就可以照推了,如果測得的值是2.5V,那麼得到的值就是255 / 2 = 127.5。也就是說,實際測得的值和這個轉換值的關系是正比的,他們的比值就是 255 / 5 = 51 ,所以用測到的值去除以51,就得到實際值。明白了嗎?如果這樣說還不明白,那就沒辦法了~
然後,為什麼後面又要搞那兩條式子呢?這是因為,要把一個數值在數碼管上顯示出來,必須把一個數值上每一個位的數字單獨處理給數碼管顯示。比如,上面除以51後,得到的數可能會有小數,比如1.45,那麼要把這個數用數碼管顯示出來,就必須把 1、4、5和小數點都單獨取出來。
以這個(i%51)*10/51*2為例:
i%51 , 是 i 除以 51 後的余數。這個數再除以51,再乘以10,再取整,就是第一個小數了。他這個式子把"乘以10"放在前面,是因為如果先除以51,那麼因為i 和 51 都是int類型,結果也必將是int類型,沒有小數,再乘以10也沒意義了。至於後面為什麼還要乘以2,這個還真不清楚,不過他這個dis數組是用來查表的,就是後面的tab[],要看他的表是怎麼定義的。他第一個數沒有乘以2,但是這個數和小數點的顯示有關,可能不顯示小數點的就要乘以2。
後面的求第二個小數,參照這個解釋自己理解一下。
㈢ 單片機實現正弦波的C程序
在把PC上 用C語言 編寫一個程序 生成 一個周期 正弦信號 的離散值
用一個位元組 8位 表示
即 0 ~ 255 表示正弦 信號 -1 到 1之間的值
單片程序 把這組0 ~ 255的 數字 放在一個 數組里
用循環 向 某個 IO口輸出 這個數組
IO口接 DAC數模轉換 器