第10章-實(shí)例練習(xí)與經(jīng)驗(yàn)積累(下:課后作業(yè)+推薦app)







//作業(yè)2,寫不同燈的PWM
#include <reg52.h>
typedef unsigned char u8;
typedef unsigned int u16;
typedef unsigned long u32;
typedef signed char i8;
typedef signed int i16;
typedef signed long i32;
//晶振頻率
#define SYS_CLK 11059200
//計(jì)數(shù)頻率
#define TIMER_CLK (SYS_CLK/12)
sbit PWMOUT=P0^7;
sbit ADDR0=P1^0;
sbit ADDR1=P1^1;
sbit ADDR2=P1^2;
sbit ADDR3=P1^3;
sbit ENLED=P1^4;
u8 highTH0RL,highTL0RL;//高電平重裝初值
u8 lowTH0RL,lowTL0RL;//低電平重裝初值
u8 TH1RL,TL1RL;//T1重裝值
u32 PeriodCnt;//某Hz的PWM對應(yīng)的計(jì)數(shù)值
void ConfigPWM( u16 freq, u8 dc )?
{
//use T0 sent PWM
u16 high,low;
ET0=TR0=0;
TMOD&=0xF0;
TMOD|=0x01;
PeriodCnt=TIMER_CLK/freq;//一個(gè)周期的計(jì)數(shù)值
high= PeriodCnt*dc/100;//高電平計(jì)數(shù)值
low= (PeriodCnt-high);//低電平計(jì)數(shù)值
high=65536-high;//高電平重裝初值
low=65536-low;//低電平重裝初值
highTH0RL=(u8)(high>>8);
highTL0RL=(u8)high;
TH0=lowTH0RL=(u8)(low>>8);
TL0=lowTL0RL=(u8)low;
PWMOUT=0;
ET0=TR0=1;
}
void ConfigTimer1( u16 ms )
{
//use T1 change T0`S PWM
u32 tmp=TIMER_CLK*ms/1000;
tmp = 65536 -tmp;
TMOD&=0x0F;
TMOD|=0x10;
TH1=TH1RL=(u8)(tmp>>8);
TL1=TL1RL=(u8)tmp;
ET1=TR1=1;
}
void ClosePWM(void)?
{
ET0=TR0=0;
PWMOUT=1;
}
void main(void)
{
EA=1;
ENLED=0;
ADDR3=1;
ADDR2=1;
ADDR1=1;
ADDR0=0;
ConfigPWM(100,10);//100Hz,占空比10
ConfigTimer1(50);//50ms
while(1);
}
void Timer0_ISR(void) interrupt 1
{
if(PWMOUT)
{
//change to 0
PWMOUT=0;
TH0=lowTH0RL;
TL0=lowTL0RL;
}
else
{
//change to 1
PWMOUT=1;
TH0=highTH0RL;
TL0=highTL0RL;
}
}
void AdjuctDutyCycle( u8 dc )?
{
u16 high,low;
ET0=TR0=0;
high= PeriodCnt*dc/100;//高電平計(jì)數(shù)值
low= (PeriodCnt-high);//低電平計(jì)數(shù)值
high=65536-high;//高電平重裝初值
low=65536-low;//低電平重裝初值
highTH0RL=(u8)(high>>8);
highTL0RL=(u8)high;
TH0=lowTH0RL=(u8)(low>>8);
TL0=lowTL0RL=(u8)low;
PWMOUT=0;
ET0=TR0=1;
}
void Timer1_ISR(void) interrupt 3
{
//占空比列表,
code u8 dcArray[]={1,2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97};
static i8 index=0;
static bit dir=1;
TH1=TH1RL;
TL1=TL1RL;
AdjuctDutyCycle(dcArray[index]);
if(dir)
{
index++;
if(index==sizeof(dcArray)/sizeof(u8))
{
index=sizeof(dcArray)/sizeof(u8)-1;
dir=0;
}
}
else
{
index--;
if(index<0)
{
index=0;
dir=1;
}
}
}
//作業(yè)3 ,在之前記得,已經(jīng)寫過了,
//作業(yè)4改,吸收吳堅(jiān)鴻老師的思路,實(shí)現(xiàn)按鍵不放,多次觸發(fā)
#include <reg52.h>
typedef unsigned char u8;
typedef unsigned int u16;
typedef unsigned long u32;
typedef signed char i8;
typedef signed int i16;
typedef signed long i32;
// 跟堂作業(yè) c4炸彈
#include "reg52.h"
sbit BUZZ = P1 ^ 6;
sbit ADDR3 = P1 ^ 3;
sbit ENLED = P1 ^ 4;
sbit KEYIN1 = P2 ^ 4;
sbit KEYIN2 = P2 ^ 5;
sbit KEYIN3 = P2 ^ 6;
sbit KEYIN4 = P2 ^ 7;
sbit KEYOUT1 = P2 ^ 3;
sbit KEYOUT2 = P2 ^ 2;
sbit KEYOUT3 = P2 ^ 1;
sbit KEYOUT4 = P2 ^ 0;
#define SYS_CLK 11059200
#define TIMER_CLK (SYS_CLK / 12)
u8 code LedChar[16] =
? ? {
0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8,
0x80, 0x90, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E};
u8 LedBuff[8] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
u8 code KeyCodeMap[4][4] =
? ? {
{0x31, 0x32, 0x33, 0x26}, // 數(shù)字1,2,3,UP
{0x34, 0x35, 0x36, 0x25}, // 數(shù)字4,5,6,LEFT
{0x37, 0x38, 0x39, 0x28}, // 數(shù)字7,8,9,DOWN
{0x30, 0x1B, 0x0D, 0x27}, // 數(shù)字0,ESC,ENTER,RIGHT
};
u8 key;
bit enBuzz = 0;
bit flag1s = 0;
bit flagStart = 0;
u8 TH0RL = 0;
u8 TL0RL = 0;
u16 CountDown = 0;
void ConfigTimer0(u16 ms)
{
u32 tmp;
tmp = TIMER_CLK * ms / 1000;
tmp = 65536 - tmp;
tmp += 18; // 補(bǔ)償值
TH0 = TH0RL = (u8)(tmp >> 8);
TL0 = TL0RL = (u8)tmp;
TMOD &= 0xF0;
TMOD |= 0x01;
ET0 = TR0 = 1;
}
void ShowNumber(u32 num)
{
u8 i, j;
u8 buf[6];
for (i = 0; i < 6; i++)
{
buf[i] = num % 10;
num /= 10;
}
for (i = 5; i >= 1; i--)
{
if (buf[i] == 0)
LedBuff[i] = 0xFF;
else
break;
}
for (j = 0; j <= i; j++)
{
LedBuff[j] = LedChar[buf[j]];
}
}
void KeyAction(u8 keycode)
{
if (keycode == 0x26) // up
{
if (CountDown < 9999)
{
CountDown++;
ShowNumber(CountDown);
}
}
else if (keycode == 0x28) // down
{
if (CountDown > 1)
{
CountDown--;
ShowNumber(CountDown);
}
}
else if (keycode == 0x0D) // enter
{
flagStart = 1;
}
else if (keycode == 0x1B) // esc
{
enBuzz = 0;
LedBuff[6] = 0xFF;
flagStart = 0;
CountDown = 0;
ShowNumber(CountDown);
}
}
void KeyDriver(void)
{
if (key)
{
KeyAction(key);
key = 0;
}
}
void main(void)
{
EA = 1;
ENLED = 0;
ADDR3 = 1;
ConfigTimer0(1); // 1ms
ShowNumber(0);
while (1)
{
KeyDriver();
if (flagStart && flag1s)
{
flag1s = 0;
if (CountDown > 0)
{
CountDown--;
ShowNumber(CountDown);
if (CountDown == 0)
{
enBuzz = 1;
LedBuff[6] = 0;
}
}
}
}
}
void LedScan(void)
{
static u8 i = 0;
P0 = 0xFF;
P1 = (P1 & 0xF8) | i;
P0 = LedBuff[i];
i++;
i &= 0x07; // 0000-0111
}
void KeyScan(void)
{
static u8 hang = 0;
u8 lie;
static u16 cnt = 0;
static u8 step = 0;
switch (step)
{
case 0:
switch (hang)
{
case 0:
KEYOUT4 = 1;
KEYOUT1 = 0;
break;
case 1:
KEYOUT1 = 1;
KEYOUT2 = 0;
break;
case 2:
KEYOUT2 = 1;
KEYOUT3 = 0;
break;
case 3:
KEYOUT3 = 1;
KEYOUT4 = 0;
break;
}
step++;
case 1:
if (KEYIN1 && KEYIN2 && KEYIN3 && KEYIN4)
{
cnt = 0;
hang++;
hang &= 0x03;
step = 0;
}
else
{
cnt++;
switch (cnt)
{
case 1200:
cnt -= 200;
case 40:
case 1000:
if (KEYIN1 == 0)
lie = 0;
else if (KEYIN2 == 0)
lie = 1;
else if (KEYIN3 == 0)
lie = 2;
else if (KEYIN4 == 0)
lie = 3;
key = KeyCodeMap[hang][lie];
}
}
}
}
void Timer0_ISR(void) interrupt 1
{
static u16 tmr1s = 0;
TH0 = TH0RL;
TL0 = TL0RL;
if (enBuzz)
BUZZ = !BUZZ;
else
BUZZ = 1;
LedScan();
KeyScan();
if (flagStart)
{
tmr1s++;
if (tmr1s >= 1000)
{
tmr1s = 0;
flag1s = 1;
}
}
else
{
tmr1s = 0;
}
}

