娇小w搡bbbb搡bbb,《第一次の人妻》,中国成熟妇女毛茸茸,边啃奶头边躁狠狠躁视频免费观看

歷史上的今天

今天是:2024年10月20日(星期日)

正在發生

2021年10月20日 | 【自學51單片機】10 --PWM介紹、51單片機RAM區域劃分

發布者:cw57324588 來源: eefocus關鍵字:51單片機  PWM 手機看文章 掃描二維碼
隨時隨地手機看文章

1、PWM介紹

PWM (Pulse Width Modulation) ,中文名為脈沖寬度調制,它能使用數字信號達到一個模擬信號的效果,脈沖寬度調制就是改變脈沖寬度來實現不同的效果。下面看圖10-1三組脈沖信號

它是一個周期為10ms,頻率為100Hz的波形,每組高低電平脈沖寬度各不相同,也就是占空比(指高電平的時間占整個周期的比例)不同。


在數字電路中,只有0和1兩種狀態,在小燈中,0熄滅,1點亮。當讓小燈亮滅間隔運行時,并且間隔時間不斷減小,頻率大于100Hz,肉眼看起來為一直保持亮狀態,每個周期內不斷改變小燈亮和滅的時間,小燈亮度也會發生變化,這就達到模擬電路的效果,不再是純粹的0和1,還有亮度的不斷變化。


2、51單片機RAM區域劃分

51單片機RAM區域分為片內RAM和片外RAM兩部分。片內RAM和片外RAM的地址不是連起來的。現在幾乎51單片機芯片內部都集成了片外RAM。下面是C51中不同RAM的關鍵字和其地址。


data:片內 RAM 從 0x00~0x7F。

idata:片內 RAM 從 0x00~0xFF。

pdata:片外 RAM 從 0x00~0xFF。

xdata:片外 RAM 從 0x0000~0xFFFF。

-說明:STC89C52RC共有512字節RAM,分為256字節片內RAM和256字節片外RAM,data 是 idata 的一部分,pdata 是 xdata 的一部分。


內部RAM,默認定義的變量為定義在data區域,data區域RAM的訪問直接尋址,執行速度最快。idata為間接尋址,速度比data慢。通常不希望訪問到0x80–0xFF,因為這塊通常用于中斷和函數調用的堆棧,所以通常不用idata區域。

外部RAM,pdata和xdata都是通過間接尋址訪問,xdata的訪問速度最慢,但xdata訪問范圍最廣。


3、數碼管掃描函數算法改進

原代碼

P0 = 0xFF; //顯示消隱

switch(i)

{

case 0: ADDR2 = 0; ADDR1 = 0; ADDR0 = 0; i++; P0 = Ledbuff[0];break;

case 1: ADDR2 = 0; ADDR1 = 0; ADDR0 = 1; i++; P0 = Ledbuff[1];break;

case 2: ADDR2 = 0; ADDR1 = 1; ADDR0 = 0; i++; P0 = Ledbuff[2];break;

case 3: ADDR2 = 0; ADDR1 = 1; ADDR0 = 1; i++; P0 = Ledbuff[3];break;

case 4: ADDR2 = 1; ADDR1 = 0; ADDR0 = 0; i++; P0 = Ledbuff[4];break;

case 5: ADDR2 = 1; ADDR1 = 0; ADDR0 = 1; i=0; P0 = Ledbuff[5];break;

default:break;

}


改進后代碼

P0 = 0xFF;//關閉所有的段選位,顯示消隱

P1 = (P1 & 0xF8) | i; //位選索引值賦值到P1口低三位

P0 = Ledbuf[i];//緩沖區中索引位置的數據送到P0口

i++;  //索引遞增循環,遍歷整個緩沖區

if(i > 5)

{

i = 0;

}


4、長短按鍵應用-模擬定時炸彈小程序

//長短按鍵應用

#include


sbit ADDR3 = P1^3;

sbit ENLED = P1^4;

sbit BUZZ = P1^6;

sbit KEY_IN_1 = P2^4;

sbit KEY_IN_2 = P2^5;

sbit KEY_IN_3 = P2^6;

sbit KEY_IN_4 = P2^7;

sbit KEY_OUT_1 = P2^3;

sbit KEY_OUT_2 = P2^2;

sbit KEY_OUT_3 = P2^1;

sbit KEY_OUT_4 = P2^0;


unsigned char code LedChar[] = { //數碼管顯示字符轉換表

0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8,

0x80, 0x90, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E

};


unsigned char LedBuff[]={ //數碼管+獨立LED顯示緩沖區

0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF

};


unsigned char KeySta[4][4] = { //全部矩陣按鍵的當前狀態

{1,1,1,1}, {1,1,1,1}, {1,1,1,1}, {1,1,1,1}

};


unsigned char code KeyCodeMap[4][4] = { //矩陣按鍵編號到標準鍵盤鍵碼的映射表

    { 0x31, 0x32, 0x33, 0x26 }, //數字鍵1、數字鍵2、數字鍵3、向上鍵

    { 0x34, 0x35, 0x36, 0x25 }, //數字鍵4、數字鍵5、數字鍵6、向左鍵

    { 0x37, 0x38, 0x39, 0x28 }, //數字鍵7、數字鍵8、數字鍵9、向下鍵

    { 0x30, 0x1B, 0x0D, 0x27 }  //數字鍵0、ESC鍵、  回車鍵、 向右鍵

};


unsigned long pdata KeyDownTime[4][4] = { //每個按鍵按下的持續時間,單位ms

{0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}

};


bit flag1s = 0; //1s定時標志

bit flagStart = 0;//倒計時啟動標志

bit enBuzz = 0; //蜂鳴器是使能標志

unsigned long CountDown = 0;//倒計時計數器

unsigned char T0RH; //T0重載值的高字節

unsigned char T0RL;// T0重載值的低字節



void ConfigTimer0(unsigned char ms);

void Shownumber(unsigned long num);

void KeyDriver();

void KeyAction(unsigned char keycode);

void Keyscan();

void Ledscan();


void main()

{

EA = 1; //使能總中斷

ENLED = 0;//選擇數碼管和獨立的LED

ADDR3 = 1;

ConfigTimer0(1);//配置T0定時1ms

Shownumber(0);//上電顯示


while(1)

{

KeyDriver();//調用按鍵驅動函數

if(flag1s && flagStart)//倒計時啟動且1秒定時到達時,處理倒計時

{

flag1s = 0;

if(CountDown > 0) //倒計時未到達0時,計數器遞減

{

CountDown--;

Shownumber(CountDown); //刷新倒計時數顯示

if(CountDown == 0) //減到0時,執行聲光警報

{

enBuzz = 1; //啟動蜂鳴器發聲

LedBuff[6] = 0x00;//點亮獨立LED

}

}

}

}

}


//配置并啟動T0,ms-T0定時時間

void ConfigTimer0(unsigned char ms)

{

unsigned long tmp; //臨時變量

tmp = 11059200 / 12; //定時器計數頻率

tmp = (tmp * ms) / 1000;//計算所需要的計數值

tmp = 65536 - tmp + 28; //計算定時器重載值,并補償中斷延時造成的誤差

T0RH = (unsigned char)(tmp >> 8);//定時器重載值拆分為高低字節

T0RL = (unsigned char)tmp;

TMOD &= 0xF0;//清零T0的控制位

TMOD |= 0x01;//配置T0為模式一

TH0 = T0RH; //加載T0重載值

TL0 = T0RL;

ET0 = 1;//使能T0中斷

TR0 = 1;//啟動T0


}


//將一個無符號長整型的數字顯示到數碼管上,num為待顯示數字

void Shownumber(unsigned long num)

{

signed char i;

unsigned char buf[6];

for(i = 0; i < 6; i++)//把長整型數轉換為6位十進制的數組

{

buf[i] = num % 10;

num /= 10;

}

for(i = 5; i >= 1; i--)//從高位起,遇到0轉換為空格,遇到非0則退出循環

{

if(buf[i] == 0)

{

LedBuff[i] = 0xFF;

}

else

{

break;

}

}

for(; i>= 0; i--) //剩余低位都如實轉換為數碼管的顯示字符

{

LedBuff[i] = LedChar[buf[i]];

}

}


//按鍵驅動函數,檢測按鍵動作,調動相應動作函數,需在主循環中調用

void KeyDriver()

{

unsigned char i, j;

static unsigned char pdata backup[4][4] = { //按鍵值備份,保存前一次的值

{1,1,1,1}, {1,1,1,1}, {1,1,1,1}, {1,1,1,1}

};

    static unsigned long pdata Timethr[4][4] = { //快速輸入執行的時間閾值

  {1000,1000,1000,1000},{1000,1000,1000,1000},

  {1000,1000,1000,1000},{1000,1000,1000,1000}

};


for(i = 0; i< 4; i++) //循環掃描4*4的矩陣按鍵

{

for(j = 0; j < 4; j++)

{

if(backup[i][j] != KeySta[i][j])//檢測矩陣動作

{

if(backup[i][j] != 0) //矩陣按下時執行動作

{

KeyAction(KeyCodeMap[i][j]);//調用按鍵動作函數

}

backup[i][j] = KeySta[i][j];  //刷新前一次備份值

}   

if(KeyDownTime[i][j] > 0) //檢測執行快速輸入

{

if(KeyDownTime[i][j] >= Timethr[i][j])

{    //達到閾值時執行一次動作

KeyAction(KeyCodeMap[i][j]);//調用按鍵動作函數

Timethr[i][j] += 200; //時間閾值增加200ms,以備下次執行

}

}

else     //按鍵彈起時復位閾值時間                                                                                                                                                                                                                                                                                                                                                                                            

{

Timethr[i][j] = 1000;  //恢復1s的初始閾值時間

}

}

}

}


//按鍵動作函數,根據鍵碼執行相應的操作,keycode為按鍵鍵碼

void KeyAction(unsigned char keycode)

{

if(keycode == 0x26) //向上按鍵,倒計時設定值遞增

{

if(CountDown < 9999) //最大計時9999秒

{

CountDown++;

Shownumber(CountDown);

}

}

if(keycode == 0x28)//向下按鍵,倒計時設定值遞減

{

if(CountDown > 1) //最小計時一秒

{

CountDown--;

Shownumber(CountDown);

}

}

if(keycode == 0x0D)//回車鍵,啟動倒計時

{

   flagStart = 1;  //啟動倒計時

}

if(keycode == 0x1B) //ESC鍵,取消倒計時

{

flagStart = 0; //停止倒計時

LedBuff[6] = 0xFF;//關閉獨立LED

enBuzz = 0; //關閉蜂鳴器

CountDown =0; //倒計時數歸零

Shownumber(CountDown);

}

}

//T0中斷服務函數,完成數碼管,按鍵掃描與秒定時

void InerruptTimer0() interrupt 1

{

static unsigned int tmr1ms = 0;//1s定時器

TH0 = T0RH; //重新加載重載值

TL0 = T0RL;

if(enBuzz == 1)

{

BUZZ = ~BUZZ;//驅動蜂鳴器發聲

}

else

BUZZ = 1;//關閉蜂鳴器


Ledscan();//Led掃描顯示

Keyscan(); //按鍵掃描


if(flagStart)//倒計時啟動時處理1秒定時

{

tmr1ms++;

if(tmr1ms >= 1000)

{

tmr1ms = 0;

flag1s = 1;

}

}  

else  //倒計時未啟動時1秒定時器歸零

{

tmr1ms = 0;

}


}


//LED動態掃描函數,需在定時中斷中調用

void Ledscan()

{

static unsigned char i = 0; //動態掃描索引


P0 = 0xFF;    //關閉所有段選位,顯示消隱

P1 = (P1 & 0xF8) | i;//位選索引值賦值到P1口低3位

P0 = LedBuff[i];//緩沖區中索引位置的數據送到P0口

i++; //索引遞增循環,遍歷整個緩沖區

if(i > 6)

{

i = 0;

}

}


void Keyscan()

{

unsigned char i;

static unsigned char keyout = 0; //矩陣按鍵掃描輸出索引

static unsigned char keybuf[4][4] = {//矩陣按鍵掃描緩沖區

{0xFF,0xFF,0xFF,0xFF},{0xFF,0xFF,0xFF,0xFF},

{0xFF,0xFF,0xFF,0xFF},{0xFF,0xFF,0xFF,0xFF}

};

//將一行的4個按鍵值移入緩沖區

keybuf[keyout][0] = (keybuf[keyout][0] << 1) | KEY_IN_1;

keybuf[keyout][1] = (keybuf[keyout][1] << 1) | KEY_IN_2;

keybuf[keyout][2] = (keybuf[keyout][2] << 1) | KEY_IN_3;

keybuf[keyout][3] = (keybuf[keyout][3] << 1) | KEY_IN_4;

//消抖后更新按鍵狀態

for(i = 0; i < 4; i++) //每行四個按鍵,所以循環四次

{

if((keybuf[keyout][i] & 0x0F) == 0x00)

{ //連續4次掃描值為0,即4*4ms內都是按下狀態時,可認為按鍵已穩定的按下

KeySta[keyout][i] = 0;

KeyDownTime[keyout][i] += 4; //按下的持續時間累加

}

else if((keybuf[keyout][i] & 0x0F) == 0x0F)

{ //連續4次掃描值為1,即4*4ms內都是彈起狀態時,可認為按鍵已穩定的彈起

KeySta[keyout][i] = 1;

KeyDownTime[keyout][i] = 0;//按下持續時間清零

}

}

//執行下一次的掃描輸出

keyout++; //輸出索引遞增

keyout &= 0x03;   //索引值加到4即歸零

switch(keyout)    //根據索引,釋放當前輸出引腳,拉低下次的輸出

{

case 0: KEY_OUT_4 = 1; KEY_OUT_1 = 0;break; 

case 1: KEY_OUT_1 = 1; KEY_OUT_2 = 0;break;

case 2: KEY_OUT_2 = 1; KEY_OUT_3 = 0;break;

case 3: KEY_OUT_3 = 1; KEY_OUT_4 = 0;break;

default: break;

}

}

關鍵字:51單片機  PWM 引用地址:【自學51單片機】10 --PWM介紹、51單片機RAM區域劃分

上一篇:【自學51單片機】12 --- 1602液晶初步認識
下一篇:【自學51單片機】9 -- 步進電機原理、蜂鳴器原理,單片機IO

推薦閱讀

寒露已過,秋冬交替,這是一年中溫度最讓人愜意的季節。但對于身體免疫力較差的人群來說,秋風把各種粉塵、細菌、病毒與秋天的氣息一起吹拂到每個角落,導致過敏體質的人出現各種狀況。即便你家與公司兩點一線,也難以幸免,尤其是在工業發達,工廠排放粉塵顆粒屬性復雜化的今天,對這種威協的防范更為困難。其中細菌是當中的最大“殺手”,據調查,我國每...
“經常尋找‘迷路’的它,掃的不干凈還需人工掃、清理塵盒易揚塵影響我們的健康”作為一款能幫我們減輕家庭負擔的智能掃地機,似乎并沒有讓我們省心省力。致力打造家居清潔服務的一站式解決方案的聯想,推出了全球首款自動集塵的掃拖一體機器人,自動集塵、掃拖一體、導航等高能設計,不僅彌補了用戶體驗上的不足,更是完全碾壓石頭、科沃斯等產品。 究...
iPhone XS 和更高版本的(海外)機型均具有實體 SIM 卡和數字 eSIM 的組合,從而實現了稱為雙卡雙待的功能。這意味著用戶可以在一臺 iPhone 上擁有兩個號碼,這對于有雙卡需求的朋友來說相當實用。根據早些時候在 Reddit 上共享的針對蘋果員工的內部培訓文件顯示,iPhone 12 和 iPhone 12 Pro 在發布時,設備上的雙 SIM 卡模式在激活時...
1 配置負載自動切換開關的必要性當今的市場經濟和社會活動對信息網絡(互聯網、電信網、工業自動化控制網、政府的電子政務網站等)的依賴程度是如此之高,那怕是僅幾分鐘的“網絡癱瘓”就可能會給公司,企業及行政管理機構的銷售,經營管理、社會生活的正常運行、聲譽、及公眾形象帶來難以估量的損失。鑒于公眾對“信息網絡”的正常運營服務所期望的高度...

史海拾趣

問答坊 | AI 解惑

兩款手機充電器拆解分析

前段時間買的手機,配了一塊電池和一個座充,另外跟朋友去買手機送了一個直充轉座充的“小盒子”。都是很便宜的東東。這兩天把這兩款手機充電器拆開了,看了一下里面電路…   先拆開“”小盒子…里面稀稀散散幾個器件,先汗一把 (=o=!) ...…

查看全部問答∨

模塊電源,開關電源軟啟動電路設計與應用

開關電源 ,模塊電源 ,軍品電源  穩壓電源 開關電源以其體積小巧、性能卓越、使用方便的顯著特點,在通信、網絡、工控、鐵路、軍事等領域日益得到廣泛的應用。很多系統設計人員已經意識到,正確合理地設計開關電源,可以省去電源設計 ...…

查看全部問答∨

電子密碼鎖1602顯示

初始密碼為000000,按1輸入密碼,按2修改密碼,仿真和電路圖都做好了,可惜的是我畫的pcb板跳線實在多,不好意思拿出來了!那位哪做的更好的,不妨做一下吧! [ 本帖最后由 冷楓yj 于 2009-5-17 09:23 編輯 ]…

查看全部問答∨

在硬盤中,每個磁道的面積是相同的嗎?如果不是,那各磁道之間容量的關系是什么?

在硬盤中,每個磁道的面積是相同的嗎?如果不是,那各磁道之間容量的關系是什么? 謝謝…

查看全部問答∨

終于可以踏上回家行程,祝福兄弟姐妹們新年快樂!全家幸福!

終于可以踏上回家行程,祝福兄弟姐妹們新年快樂!全家幸福!…

查看全部問答∨

ARM裸板編程時要實現snmp,mib文件是不是必須的?

MIB是代理保存的設備狀態信息,那么如果設備自身信息以其他方式組織,比如共享內存、全局變量、結構體,那么只要發包時包含自身信息不是就可以了,是不是就可以不要什么mib文件,不必非得按照MIB文件的格式組織吧? 現在我想裸板編程,移植lwip,在 ...…

查看全部問答∨

低格10秒后硬盤的mbr手寫恢復問題 求助 小弟叩首

    昨天用填充零低格硬盤時選錯了硬盤,10秒之后覺得不對強行關機,把低格后的硬盤接在另一臺電腦上后,用WinHex查看mbr,不出所料,全部是0.從自己機器硬盤復制前446個字節后,后面64位分區表搞不定了。     我用數據修復軟 ...…

查看全部問答∨

sql ce 下目錄快照怎么設置拉??

我是一個新手拉  剛剛接觸EVC編程拉  哪個好心的幫幫忙拉  設置目錄快照后  可以檢查數據庫是不是連接正確拉  好象要一個用戶名 還有什么數據庫文件拉…

查看全部問答∨

最近竟然買到MSP430的假片

本帖最后由 ddllxxrr 于 2016-1-7 17:12 編輯 片子是在淘寶上買的MSP430F1232,高速晶振在沒有軟件設置的時候竟然起振了,Jtag一直都連不上去。后來果斷換了一家實體店,片子一換上去就好了。以前買過51的假片,現在竟然買到430的啦!無良賣家是在 ...…

查看全部問答∨

外部中斷通道0到4與外部中斷5到9有何區別

                                 外部中斷通道0 到4 與 通道 5 到 9 有何區別,如果在5到9之間的一個通道需要外部中斷,中斷入口函數和0到4 的入口函 ...…

查看全部問答∨
小廣播
設計資源 培訓 開發板 精華推薦

最新單片機文章
何立民專欄 單片機及嵌入式寶典

北京航空航天大學教授,20余年來致力于單片機與嵌入式系統推廣工作。

 
EEWorld訂閱號

 
EEWorld服務號

 
汽車開發圈

 
機器人開發圈

電子工程世界版權所有 京ICP證060456號 京ICP備10001474號-1 電信業務審批[2006]字第258號函 京公網安備 11010802033920號 Copyright ? 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
主站蜘蛛池模板: 精河县| 上思县| 大城县| 洛宁县| 富锦市| 宝丰县| 金平| 长沙市| 东至县| 柳河县| 荣昌县| 海盐县| 汾阳市| 德保县| 宿迁市| 鹤岗市| 湖北省| 康定县| 开阳县| 屯门区| 南汇区| 雅安市| 枞阳县| 宜城市| 韩城市| 山丹县| 徐水县| 台安县| 万安县| 武鸣县| 普定县| 墨竹工卡县| 郯城县| 武陟县| 保靖县| 新泰市| 兖州市| 抚松县| 囊谦县| 图木舒克市| 海盐县|