1、集美大学机电专业单片机考试复习资料
飞思卡尔AW60单片机复习
1. 串口程序
#include
2、l clock generation 2 ICGC1 = 0b01111000; //$78 internal clock generation while(!ICGS1_LOCK); //等待FLL稳定 PTBDD=0xff ; PTBD=0xff ; } void SCIInit() { unsigned int ubgs,baud=9600; unsigned char sysclk=20; //1.计算波特率并设置:
3、ubgs = fsys/(波特率*16)(其中fsys=sysclk*1000000) ubgs = sysclk*(10000/(baud/100))/16; //理解参考上一行,此处便于CPU运算 SCI1BDH= (unsigned char)((ubgs & 0xFF00) >> 8); SCI1BDL= (unsigned char)(ubgs & 0x00FF); SCI1C1= 0; //无校验,正常模式(开始信号 + 8位数据(先发最低位) + 停止信号) SCI1C2= (0| SCI1C2_TE_MASK | S
4、CI1C2_RE_MASK );//允许发送,允许接收,查询方式收发 } void SCISend1(unsigned char ch) { while(!(SCI1S1 & SCI1S1_TDRE_MASK));//判断发送缓冲区是否为空 SCI1D = ch; } void SCISendN(unsigned char n, unsigned char ch[]) { unsigned i; for (i = 0; i < n; i++) SCISend1(ch[i]); } uns
5、igned char SCIRe1(unsigned char *p) { unsigned int k; unsigned char i; for (k = 0; k < 0x0b; k++)//有时间限制 if((SCI1S1 & SCI1S1_RDRF_MASK) != 0)//判断接收缓冲区是否满 { i = SCI1D; *p = 0x00; break; } if (k >= 0x0b)
6、//接收失败 { i = 0xff; *p = 0x01; } return i; } unsigned char SCIReN(unsigned n,unsigned char ch[]) { unsigned char m; unsigned char fp; //接收标志 m = 0; while (m < n) { ch[m] = SCIRe1(&fp); if (fp == 1)
7、 { return 1; //接收失败 } m++; } return 0; //接收成功 } void main(void) { unsigned char SerialBuff[]="Hello! World!"; //初始化存放接收数据的数组 DisableInterrupts; //禁止总中断 MCUInit(); SCIInit(); EnableInterrupts;
8、 //开放总中断 SCISendN(13,SerialBuff); //串口发送"Hello World!" for(;;) { if((SCI1S1&SCI1S1_RDRF_MASK)!=0) { PTBD=SCI1D ;
9、
if((SCI1S1&SCI1S1_TDRE_MASK)!=0)
SCI1D=PTBD;
}
else
PTBD=0x00;
}
}
2.按键程序
#include
10、 unsigned int unsigned char table[]="I love mcu!"; unsigned char table1[]=" very much!"; #define rsout PTCDD |= (1<<4) #define rsset PTCD |= (1<<4) #define rsclr PTCD &=~(1<<4) #define rwout PTCDD |= (1<<6) #define rwset PTCD |= (1<<6) #define rwclr PTCD &=~(1<<6) #define enout
11、 PTFDD |= (1<<6) #define enset PTFD |= (1<<6) #define enclr PTFD &=~(1<<6) void mcu_init(void) { PTADD = 0XFF; rsout; rwout; enout; } void MCUInit(void) { SOPT = 0b01110000; ICGC2 = 0b00110000; ICGC1 = 0b01111000; while(!ICGS1_LOCK); }
12、void Delayms(uint MS)
{
uint i,j;
for( i=0;i 13、layms(5);
enclr;
}
void write_data(uchar date)
{
rsset;
rwclr;
PTAD=date;
Delayms(5);
enset;
Delayms(5);
enclr;
}
void initlcd(void)
{
write_com(0x38);
Delayms(5);
write_com(0x01);
Delayms(5);
write_com(0x06);
Delayms(5);
write_com(0x0c);
Delayms(5);
}
14、
void writedate(uint adress,uint date)
{
write_com(adress);
write_data(date);
}
void KBInit(void)
{
PTDD &= 0b01110011; //键盘口复位
PTGD &= 0b11100000;
PTDDD &= 0b01110011; //定义列线(7-4位)为输入
PTGDD &= 0b11101111;
PTDPE |= 0b10001100; //输入引脚(列线)有内部上拉电阻
15、
PTGPE |= 0b00010000;
PTGDD |= 0b00001111; //行线(3-0位)为输出
KBI1SC &=~(1<<1); //屏蔽键盘中断(KBIE = 0)
KBI1PE = (0
|KBI1PE_KBIPE7_MASK
|KBI1PE_KBIPE6_MASK
|KBI1PE_KBIPE5_MASK
|KBI1PE_KBIPE4_MASK); //允许输入引脚(列线)的中断可进 16、入
KBI1SC = (0
|KBI1SC_KBACK_MASK); //清除键盘中断请求(KBACK = 1)
}
const uint KBtable[] =
{
0xEE,'9',0xDE,'A',0xBE,'B',0x7E,'C',
0xED,'6',0xDD,'7',0xBD,'8',0x7D,'D',
0xEB,'3',0xDB,'4',0xBB,'5',0x7B,'E',
0xE7,'0',0xD7,'1',0xB7,'2',0x77,'F',
0x00
};
uint K 17、BDef(uint valve)
{
uint KeyPress;
uint i;
i = 0;
KeyPress = 0xff;
while (KBtable[i] != 0x00) //在键盘定义表中搜索欲转换的键值,直至表尾
{
if(KBtable[i] == valve) //在表中找到相应的键值
{
KeyPress = KBtable[i+1];//取出对应的键定义值
break;
}
18、 i += 2; //指向下一个键值,继续判断
}
return KeyPress;
}
uint KBScan1(void)
{
uint line,i,tmp,tmp1,tmp2;
line=0b11111110; //使第一根行线为0(低电平)
for (i = 1; i <= 4; i++) //最多将扫描4根行线
{
PTGD = line; //输出开始扫描
asm("N 19、OP");
asm("NOP");
tmp1 = PTDD;
tmp2 = PTGD;
//整合扫描结果,即键盘输入引脚的4位
tmp = (tmp1 & 0x80); //输入扫描结果 取7位数
tmp1 &= 0x0C;//去2\3两位的数
tmp1 = (tmp1<<3);//移到高位
tmp |= tmp1;
tmp |= (tmp2 & 0x1f);//整合所有数值
//通过观察4 20、根列线中是否出现低电平来判断当前行有无按键
if ((tmp & 0xF0) != 0xF0) //当前行有键按下
{
break; //退出循环不再扫描
}
else //当前行无按键,准备扫描下一行
line = (line << 1) | 0x01;
}
if (i == 5) //无按键,以后将返回0xFF
tmp = 0xFF;
return (t 21、mp);
}
uint KBScanN(uint KB_count)
{
uint i,KB_value_last,KB_value_now;
if (0 == KB_count || 1 == KB_count) //先扫描一次得到的键值,便于下面比较
return KBScan1();
KB_value_now = KB_value_last = KBScan1();
for (i=0; i 22、 Delay(15);
KB_value_now = KBScan1();
if (KB_value_now == KB_value_last)
return KB_value_now; //返回扫描的键值
else
KB_value_last = KB_value_now;
}
return 0xFF; //返回出错标志
}
void main(void)
{
uint num=0;
DisableInterrupts 23、
MCUInit();
mcu_init();
Delayms(30);
initlcd();
write_com(0x80+0x40);
for(num=0;num<11;num++)
{
write_data(table[num]);
Delayms(20);
}
KBInit(); // 键盘初始化
KBI1SC |=(1<<1); // 开键盘中断
EnableInterrupts; // 开总中断
for(;;) ;
}
interrupt 22 vo 24、id isrKeyBoard(void)
{
uint value;
uint i;
static int j=0;
for(i=0; i<50000; i++);
DisableInterrupts; //关总中断
KBI1SC &=~(1<<1); //屏蔽键盘中断
KBI1SC|= KBISC_KBACK_MASK; //清中断标志位
value = KBScanN(10); //扫描键值,存于value中
if(value!=0xff)
{
25、 writedate(0x80+j,KBDef(value));//键值转化为定义值并发送
j++;
}
PTDD&=0b01110011;
PTGD&=0b11100000; //键盘初始化键盘中断
KBI1SC |=(1<<1); //开放键盘中断
EnableInterrupts ; //开总中断
}
3. 数码管程序
#include 26、ative.h" /* include peripheral declarations */
typedef unsigned char uint8;
typedef unsigned short int uint16;
const uint8 Dtable[10] =
// 0 1 2 3 4 5 6 7 8 9
{0x3F,0x06,0x5B,0x4F,0x66, 0x6D,0x7D,0x07,0x7F,0x6F};
const uint8 CStable[4] =
// 0 1 2 27、 3
{0xDF,0xEF,0xFD,0xFE};
void Delay(uint16 count)
{
uint8 i;
uint16 j;
for(j=0; j 28、
PTBDD = 0xFF; //数据口为输出
PTDDD |= 0x33; //位选口为输出
}
void LEDshow1(uint8 i, uint8 c)
{
PTDD = CStable[i];
PTBD = Dtable[c];
}
void LEDshow(uint8 *Buf)
{
uint8 i,c;
for (i = 0;i <= 3;i++)
{
c = Buf[i]-'0';
LEDshow1(i,c);
Delay 29、100);
}
}
void main(void)
{
uint8 LEDBUF[4];
LEDBUF[0]='2';
LEDBUF[1]='0';
LEDBUF[2]='1';
LEDBUF[3]='2';
DisableInterrupts;
MCUInit();
LEDinit();
EnableInterrupts;
for(;;)
{
LEDshow(LEDBUF);
}
}
4. 电子钟程序
#include 30、f.h> /* for EnableInterrupts macro */
#include "derivative.h" /* include peripheral declarations */
#define uchar unsigned char
#define uint unsigned int
unsigned char table[]=" 2012-5-3";
unsigned char table1[]=" 00:00:00";
#define rsout PTCDD |= (1<<4)
#define rsset PTCD |= (1<<4) 31、
#define rsclr PTCD &=~(1<<4)
#define rwout PTCDD |= (1<<6)
#define rwset PTCD |= (1<<6)
#define rwclr PTCD &=~(1<<6)
#define enout PTFDD |= (1<<6)
#define enset PTFD |= (1<<6)
#define enclr PTFD &=~(1<<6)
uchar shi=0,fen=0,miao=0;
uint Count_200ms=0;
void mcu_init(void);
voi 32、d MCUInit(void)
{
SOPT = 0b01110000;
ICGC2 = 0b00110000;
ICGC1 = 0b01111000;
while(!ICGS1_LOCK);
}
void Delayms(uint MS)
{
uint i,j;
for( i=0;i 33、 |TPM1SC_PS2_MASK|TPM1SC_PS1_MASK); //TPM1时钟源选择系统时钟(20MHZ), 分频因子64
TPM1MODH=0xF4;
TPM1MODL=0x24; //根据时钟源及分频因子,将TPM1的定时时间设定为200ms
TPM1CNTH=0x00;
TPM1CNTL=0x00;
}
void write_com(uchar com)
{
rsclr;
rwclr;
enclr;
PTAD=com;
Delayms(5);
enset;
Delayms 34、5);
enclr;
}
void write_data(uchar date)
{
rsset;
rwclr;
PTAD=date;
Delayms(5);
enset;
Delayms(5);
enclr;
}
void initlcd(void)
{
write_com(0x38);
Delayms(5);
write_com(0x01);
Delayms(5);
write_com(0x06);
Delayms(5);
write_com(0x0c);
Delayms(5);
}
void w 35、rite_sfm(uchar add,uchar date)
{
uchar si,ge;
si=date/10;
ge=date%10;
write_com(0x80+0x40+add);
write_data(0x30+si);
write_data(0x30+ge);
}
void main(void)
{
uint num=0;
DisableInterrupts;
MCUInit();
mcu_init();
Delayms(30);
initlcd();
TPM1Init();
PTBDD=0XF 36、F;
PTBD=0XFF;
EnableInterrupts;
write_com(0x80);
for(num=0;num<12;num++)
{
write_data(table[num]);
Delayms(20);
}
write_com(0x80+0x40);
for(num=0;num<12;num++)
{
write_data(table1[num]);
Delayms(20);
}
for(;;)
{}
}
void mcu_init(void)
{
PTADD = 0XF 37、F;
rsout;
rwout;
enout;
}
interrupt 11 void TPM1_200msover(void)
{
uint temp;
DisableInterrupts;
Count_200ms++;
while(Count_200ms==5)
{
PTBD=~PTBD;
miao++;
if(miao==60)
{
miao=0;
38、 fen++;
if(fen==60)
{
fen=0;
shi++;
if(shi==24)
{
shi=0;
}
write_sfm(4,shi);
}
write_sfm(7,fen);
39、}
write_sfm(10,miao);
Count_200ms=0;
}
temp=TPM1SC;
TPM1SC&=~TPM1SC_TOF_MASK;
EnableInterrupts;
}
5. AD转换程序
#include 40、 uint8; // 8 位无符号数
typedef unsigned short int uint16; // 16 位无符号数
typedef unsigned long int uint32; // 32 位无符号数
typedef char int8; // 8 位有符号数
typedef short int int16; // 16 位有符号数
typedef int int32; // 32 位有符号数
uint8 LEDBUF[4 41、];
const uint8 Dtable[10] =
// 0 1 2 3 4 5 6 7 8 9
{0x3F,0x06,0x5B,0x4F,0x66, 0x6D,0x7D,0x07,0x7F,0x6F};
//片选表 (电平为低片选)
const uint8 CStable[4] =
// 0 1 2 3
{0xDF,0xEF,0xFD,0xFE};
void Delay(uint16 count)
{
uint8 i;
uint16 j;
for(j=0; 42、 j 43、2 = 0b00000000; //软件触发,禁止比较功能
}
uint8 ADCValue(uint8 channel)
{
uint8 SC1_3;
uint8 resultH;
uint8 result; //1 选取通道号AD0-AD27 = 00000-11011
channel &= 0b00011111; //取通道号变量的低五位(实际通道号)
SC1_3 =ADC1SC1
&(ADC1SC1_COCO_MASK
44、 |ADC1SC1_AIEN_MASK
|ADC1SC1_AIEN_MASK);
// 取ADC1SC1的高三位(取上电复位默认值000)
// 单次转换, 禁止中断, 转换未完成
ADC1SC1 = SC1_3 | channel; //合并上述8位
//2 取A/D转换结果
while ((ADC 45、1SC1 & ADC1SC1_COCO_MASK) == 0); //未完成则执行空操作
resultH = ADC1RH;
result =ADC1RL;
return result;
}
uint8 ADCMid(uint8 channel) //中值滤波
{
uint8 i,j,k,tmp;
//1 取三次A/D转换结果
i = ADCValue(channel);
j = ADCValue(channel);
k = ADCValue(channel);
//2 从三次A/D转换结果中 46、取中值
tmp = (i > j) ? j : i;
tmp = (tmp > k) ? tmp : k;
return tmp;
}
uint8 ADCAve(uint8 channel, uint8 n) //均值滤波
{
uint16 i;
uint32 j;
j = 0;
for (i = 0; i < n; i++)
j += ADCMid(channel);
j = j/n;
return (uint8)j;
}
//将AD转换得到的数值量还原为实际的电压值,将电压 47、值的BCD码存储显示缓冲区
void ADCV_Vol(uint8 ADC_V,uint8 *p)
{
uint8 V,V1;
V=(uint8)(ADC_V/51);
V1=ADC_V%51;
*p=V;
V=(uint8)(V1*10)/51;
V1=(V1*10)%51;
*(p+1)=V;
V=(uint8)(V1*10)/51;
V1=(V1*10)%51;
*(p+2)=V;
V=(uint8)(V1*10)/51;
*(p+3)=V;
}
void LE 48、Dinit(void)
{
PTBDD = 0xFF; //数据口为输出
PTBPE=0xff; //为B口输出配置上拉电阻
PTBDS=0xff;
PTDDD |= 0x33; //位选口为输出
}
void LEDshow1(uint8 i, uint8 c)
{
PTDD = CStable[i];
PTBD = Dtable[c];
}
void LEDshow(uint8 *Buf)
{
uint8 i,c;
for (i = 0;i <= 3;i++)
49、{
c = Buf[i];
LEDshow1(3-i,c);
Delay(10);
}
}
void main(void)
{
uint8 V1Value;
LEDBUF[0]='0';
LEDBUF[1]='0';
LEDBUF[2]='0';
LEDBUF[3]='0';
DisableInterrupts;
MCUInit(); //MCU初始化
A 50、DCInit(); //AD模块初始化
LEDinit(); //LED数码块接口初始化
EnableInterrupts;
for(;;)
{
V1Value=ADCAve(15,50); //取得中值滤波法得到的AD转换数值
ADCV_Vol(V1Value,LEDBUF); //将AD转换数值转化为对应的电压值的
LEDshow(LED






