|
1.1安装keil
注意:将OUTPUT中HEX文件打钩才能烧制到芯片去
1.2.单片机的闪烁实验
1)用bit,sbit(更常用特殊功能寄存器的位)
格式:sbit led=P0^0;(注意是等号以及用分号结尾)
表示对一个端口的位进行操作。
2)头文件#include"reg52(51).h"
3)typedef用法
格式:typedef unsigned char u8;
u18代替了类型unsigned char,书写简洁起来,同时注意以分号结尾
4)宏定义define
格式:#define A P0
注意#,还有没有分号结尾
5)循环左移/右移
_crol_(a,b);//a表示左移的值,b表示左移的位数
_cror_(a,b);//循环左移右移要用一定要加上头文件#include"intrins.h"
1.3.流水灯的实现
1)循环代码实现:
#include"reg52.h"
#define led P0 //led现在代表P0的所有位
typedef unsigned char u8; //0-255
typedef unsigned int u16; //0-65535
void delay(u16 i)
{
while(i--);
}
void main()
{
u8 i; //keil默认i=0
led=0x01; //P0端口此时从P0^7-P0^0的电位是
//0000 0001,说明此时只有PO^0是亮的
delay(50000);
while(1)
{
for(i=0;i<8;i++)
{
led=(0x01<<i); //<<为左移符号
// 第一次i=0,i++后i=1,故左移一位
//0x01(16进制) 0000 0001 左移一位
//后 0000 0010
delay(50000);
}
}
}
2)用循环左移右移函数实现:
#include"reg52.h"
#include"intrins.h" //注意头文件一定要加切不要记错 intrins
#define led P0
typedef unsigned char u8;
typedef unsigned int u16;
void delay(u16 i)
{
while(i--);
}
void main()
{
u8 i;
led=0x01; //P0端口此时从P0^7-P0^0的电位是0000 0001,
//说明此时只有PO^0是亮的
delay(50000);
while(1)
{
for(i=0;i<7;i++) //只能七次,第八次就移出P0口进入PSW中,
//此时P0=0x00,即全灭
{
led=_crol_(led,1);
delay(50000);
}
for(i=0;i<7;i++)
{
led=_cror_(led,1);
delay(50000);
}
}
}
3)什么时候用头文件intrins?
一般_nop_();空指令啊,最常用的就是这个了,还有移位的时候
extern void _nop_ (void);
extern bit _testbit_ (bit);
extern unsigned char _cror_ (unsigned char, unsigned char);
extern unsigned int _iror_ (unsigned int, unsigned char);
extern unsigned long _lror_ (unsigned long, unsigned char);
extern unsigned char _crol_ (unsigned char, unsigned char);
extern unsigned int _irol_ (unsigned int, unsigned char);
extern unsigned long _lrol_ (unsigned long, unsigned char);
extern unsigned char _chkfloat_(float);
extern void _push_ (unsigned char _sfr);
extern void _pop_ (unsigned char _sfr);
这个头文件就几个函数,后面的两个堆栈的。中间的_irol__是移位啊。
1.4.蜂鸣器,用P1^5实现:
#include"reg52.h"
#include"intrins.h"
#define led P0
sbit beep=P1^5;
typedef unsigned char u8;
typedef unsigned int u16;
void delay(u16 i)
{
while(i--);
}
void main()
{
while(1)
{
beep=~beep; //~取反符号
delay(20);
}
}
1.5.点亮继电器
#include"reg52.h"
#include"intrins.h"
#define led P0
sbit relay=P1^4;
typedef unsigned char u8;//0-255
typedef unsigned int u16;//0-65535
void main()
{
relay=0;
while(1)
{
}
}
1.6静态数码管
#include"reg52.h"
#include"intrins.h"
#define led P0
typedef unsigned char u8;
typedef unsigned int u16;
u8 code smgduan[16]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,
0x7c,0x39,0x5e,0x79,0x71}; //共阴的
void delay(u16 i)
{
while(i--);
}
void main()
{
u8 i;
while(1)
{
for(i=0;i<16;i++)
{
P0=~smgduan[i];
delay(50000);
}
}
}
1.7.动态数码管
注意延时不应该太长,delay_100。
注意74LS138的输出引脚为J15;8个动态数码管的选通引脚为J16,出厂时默认将二者连接了,以后单独使用74LS138时要拆除管帽。
J16低电平有效,同样的J15输出的是低电平。
#include"reg52.h"
typedef unsigned char u8;//0-255
typedef unsigned int u16;//0-65535
sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;
u8 code smgduan[16]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,
0x7c,0x39,0x5e,0x79,0x71}; //共阴的
void delay(u16 i)
{
while(i--);
}
void DigDispaly()
{
u8 i;
for(i=0;i<8;i++)
{
switch(i)
{
case 0:LSA=0;LSB=0;LSC=0;break;
case 1:LSA=1;LSB=0;LSC=0;break;
case 2:LSA=0;LSB=1;LSC=0;break;
case 3:LSA=1;LSB=1;LSC=0;break;
case 4:LSA=0;LSB=0;LSC=1;break;
case 5:LSA=1;LSB=0;LSC=1;break;
case 6:LSA=0;LSB=1;LSC=1;break;
case 7:LSA=1;LSB=1;LSC=1;break;
}
P0=smgduan[i];
delay(100);
P0=0x00; //消除重影
}
}
void main()
{
while(1)
{
DigDispaly();
}
}
1.8.独立按键
#include"reg52.h"
#include"intrins.h"
typedef unsigned char u8;
typedef unsigned int u16;
sbit led=P0^0;
sbit k1=P1^0;
void delay(u16 i)
{
while(i--);
}
void code keyptos()
{
if(k1==0)
{
delay(1000);//消抖
if(k1==0)
{
led=~led;
}
while(!k1);
}
}
void main()
{
led=0;
while(1)
{
keyptos();
}
}
1.9.矩阵键盘
#include"reg52.h"
#include"intrins.h"
#define GPIO_DIG P0
#define GPIO_KEY P1
typedef unsigned char u8;//0-255
typedef unsigned int u16;//0-65535
u8 code smgduan[16]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,
0x7c,0x39,0x5e,0x79,0x71}; //共阴的静态数码管
u8 KeyValue;
void delay(u16 i)
{
while(i--);
}
void KeyDown()
{
char a=0;
GPIO_KEY=0x0f;
if(GPIO_KEY!=0x0f)
{
delay(1000);//消除抖动
if(GPIO_KEY!=0x0f)
{
switch(GPIO_KEY)
{
case 0x07:KeyValue=0;break;
case 0x0b:KeyValue=1;break;
case 0x0d:KeyValue=2;break;
case 0x0e:KeyValue=3;break;
}
GPIO_KEY=0xf0;
switch(GPIO_KEY)
{
case 0x70:KeyValue=KeyValue;break;
case 0xb0:KeyValue=KeyValue+4;break;
case 0xd0:KeyValue=KeyValue+8;break;
case 0xe0:KeyValue=KeyValue+12;break;
}
while(a<50&&GPIO_KEY!=0xf0)
{
delay(1000);
a++;
} //强制退出
}
}
}
void main()
{
while(1)
{
KeyDown();
GPIO_DIG=~smgduan[KeyValue];//共阳极的矩阵键盘
}
}
2.1.并行转串行
#include"reg52.h"
#include"intrins.h"
#define GPIO_LED P0
sbit IN_PL=P1^6;
sbit IN_Data=P1^7;
sbit SCK=P3^6;
typedef unsigned char u8;//0-255
typedef unsigned int u16;//0-65535
u8 Read74HC165()
{
u8 indata=0;
u8 i;
IN_PL=0;
_nop_();
IN_PL=1;
_nop_();
for(i=0;i<8;i++)
{
indata=indata<<1; //技巧:当为读操作时,应当把
//indata=indata<<1写在最初,当为写操
//作时应把indata=indata<<1放到
//indata|=IN_Data之后
SCK=0; // SCK=0;_nop_(); SCK=1;三条命令描
//述上升沿有效
_nop_();
indata|=IN_Data;
SCK=1;
}
return indata;
}
void main()
{
u8 h165Value;
GPIO_LED=0;
while(1)
{
h165Value=Read74HC165();
if(h165Value!=0xff)
{
GPIO_LED=~h165Value;
}
}
}
2.2.串口转并口
#include"reg51.h"
#include"intrins.h"//注意头文件一定要加切不要记错 intrins
sbit SRCLK=P3^6;
sbit RCLK=P3^5;
sbit SER=P3^4;
typedef unsigned char u8;//0-255
typedef unsigned int u16;//0-65535
void delay(u8 i)
{
while(i--);
}
void Hc595endBtye(u8 dat)
{
u8 a=0;
for(a=0;a<8;a++)
{
SER=dat>>7;//右移自动补零
dat<<=1; //dat左移一位
SRCLK=0;
_nop_();
_nop_();
SRCLK=1;
}
RCLK=0;
_nop_();
_nop_();
RCLK=1;
}
void main()
{
u8 ledNum;
ledNum=0x34;
while(1)
{
Hc595endBtye(ledNum);
ledNum=_crol_(ledNum,1);
delay(50000);
}
}