资源描述
集美大学机电专业单片机考试复习资料
飞思卡尔AW60单片机复习
1. 串口程序
#include <hidef.h> /* for EnableInterrupts macro */
#include "derivative.h" /* include peripheral declarations */
void MCUInit(void)
{
SOPT = 0b01100000; //$70 System Options Register(write once)
ICGC2 = 0b00110000; //$30 internal 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.计算波特率并设置: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 | SCI1C2_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]);
}
unsigned 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) //接收失败
{
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)
{
return 1; //接收失败
}
m++;
}
return 0; //接收成功
}
void main(void)
{
unsigned char SerialBuff[]="Hello! World!"; //初始化存放接收数据的数组
DisableInterrupts; //禁止总中断
MCUInit();
SCIInit();
EnableInterrupts; //开放总中断
SCISendN(13,SerialBuff); //串口发送"Hello World!"
for(;;)
{
if((SCI1S1&SCI1S1_RDRF_MASK)!=0)
{
PTBD=SCI1D ;
if((SCI1S1&SCI1S1_TDRE_MASK)!=0)
SCI1D=PTBD;
}
else
PTBD=0x00;
}
}
2.按键程序
#include <hidef.h> /* for EnableInterrupts macro */
#include "derivative.h" /* include peripheral declarations */
#define uchar unsigned char
#define uint 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 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);
}
void Delayms(uint MS)
{
uint i,j;
for( i=0;i<MS;i++)
for(j=0;j<1141;j++);
}
void Delay(uint count)
{
uint i,j;
for(j=0; j<count; j++)
{
for(i=0;i<1000; i++);
}
}
void write_com(uchar com)
{
rsclr;
rwclr;
enclr;
PTAD=com;
Delayms(5);
enset;
Delayms(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 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; //输入引脚(列线)有内部上拉电阻
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); //允许输入引脚(列线)的中断可进入
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 KBDef(uint valve)
{
uint KeyPress;
uint i;
i = 0;
KeyPress = 0xff;
while (KBtable[i] != 0x00) //在键盘定义表中搜索欲转换的键值,直至表尾
{
if(KBtable[i] == valve) //在表中找到相应的键值
{
KeyPress = KBtable[i+1];//取出对应的键定义值
break;
}
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("NOP");
asm("NOP");
tmp1 = PTDD;
tmp2 = PTGD;
//整合扫描结果,即键盘输入引脚的4位
tmp = (tmp1 & 0x80); //输入扫描结果 取7位数
tmp1 &= 0x0C;//去2\3两位的数
tmp1 = (tmp1<<3);//移到高位
tmp |= tmp1;
tmp |= (tmp2 & 0x1f);//整合所有数值
//通过观察4根列线中是否出现低电平来判断当前行有无按键
if ((tmp & 0xF0) != 0xF0) //当前行有键按下
{
break; //退出循环不再扫描
}
else //当前行无按键,准备扫描下一行
line = (line << 1) | 0x01;
}
if (i == 5) //无按键,以后将返回0xFF
tmp = 0xFF;
return (tmp);
}
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<KB_count-1; i++) //以下多次扫描消除误差
{
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;
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 void 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)
{
writedate(0x80+j,KBDef(value));//键值转化为定义值并发送
j++;
}
PTDD&=0b01110011;
PTGD&=0b11100000; //键盘初始化键盘中断
KBI1SC |=(1<<1); //开放键盘中断
EnableInterrupts ; //开总中断
}
3. 数码管程序
#include <hidef.h> /* for EnableInterrupts macro */
#include "derivative.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 3
{0xDF,0xEF,0xFD,0xFE};
void Delay(uint16 count)
{
uint8 i;
uint16 j;
for(j=0; j<count; j++)
for(i=0; i<200; i++);
}
void MCUInit(void)
{
SOPT = 0b01110000;
ICGC2 = 0b00110000;
ICGC1 = 0b01111000;
while(!ICGS1_LOCK);
}
void LEDinit(void)
{
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(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 <hidef.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)
#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);
void MCUInit(void)
{
SOPT = 0b01110000;
ICGC2 = 0b00110000;
ICGC1 = 0b01111000;
while(!ICGS1_LOCK);
}
void Delayms(uint MS)
{
uint i,j;
for( i=0;i<MS;i++)
for(j=0;j<1141;j++);
}
void TPM1Init(void)
{
TPM1SC=(0|TPM1SC_TOIE_MASK|TPM1SC_CLKSA_MASK
|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(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 write_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=0XFF;
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 = 0XFF;
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;
fen++;
if(fen==60)
{
fen=0;
shi++;
if(shi==24)
{
shi=0;
}
write_sfm(4,shi);
}
write_sfm(7,fen);
}
write_sfm(10,miao);
Count_200ms=0;
}
temp=TPM1SC;
TPM1SC&=~TPM1SC_TOF_MASK;
EnableInterrupts;
}
5. AD转换程序
#include <hidef.h> /* for EnableInterrupts macro */
#include "derivative.h" /* include peripheral declarations */
typedef unsigned char 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];
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; j<count; j++)
for(i=0; i<200; i++);
}
void MCUInit(void)
{
SOPT = 0b01110000;
ICGC2 = 0b00110000;
ICGC1 = 0b01111000;
while(!ICGS1_LOCK);
}
void ADCInit(void)
{
ADC1CFG = 0b11010001; //低功耗,4分频,长采样,8位模式,总线时钟2分频
ADC1SC1 = 0b00000000;
ADC1SC2 = 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
|ADC1SC1_AIEN_MASK
|ADC1SC1_AIEN_MASK);
// 取ADC1SC1的高三位(取上电复位默认值000)
// 单次转换, 禁止中断, 转换未完成
ADC1SC1 = SC1_3 | channel; //合并上述8位
//2 取A/D转换结果
while ((ADC1SC1 & 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转换结果中取中值
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转换得到的数值量还原为实际的电压值,将电压值的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 LEDinit(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++)
{
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初始化
ADCInit(); //AD模块初始化
LEDinit(); //LED数码块接口初始化
EnableInterrupts;
for(;;)
{
V1Value=ADCAve(15,50); //取得中值滤波法得到的AD转换数值
ADCV_Vol(V1Value,LEDBUF); //将AD转换数值转化为对应的电压值的
LEDshow(LED
展开阅读全文