51单片机笔记
1. 矩阵键盘
H3 H2 H1 H0 L3 L2 L1 L0
1 1 1 1 0 0 0 0 0XF0
1 1 1 0 0 0 0 0 0XE0
0 0 0 0 1 1 1 1 0X0F
0 0 0 0 1 1 1 0 0X0E
temp=0xe0+0x0e=0xee (H0,L0)
2. 定时器/计数器
2.1 定时器
void inittimer0()
{
TMOD=0x10;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
ET0=1;
EA=1;
TR0=1;
}
void timer0_isr() interrupt 1
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
cnt++;
if(cnt==20)
{
num++;
cnt=0;
}
}
2.2 计数器
void initcounter0()
{
TOMD=0x60;
TH0=256-3;
TL0=256-3;
ET0=1;
EA=1;
TR0=1;
}
void counter0_isr() interrupt 1
{
num++;
}
3. 中断
3.1 外部中断
void initex()
{
IT0=1;
EX0=1;
EA=1;
}
void ex_isr interrupt 0
{
}
4. 串形口通信
5. LCD1602
6. 点阵
点阵0-9数字显示(高电平有效)
0x00, 0x7E, 0xFF, 0xC3, 0xC3, 0xFF, 0x7E, 0x00,
0x00, 0x00, 0x43, 0xFF, 0xFF, 0x03, 0x00, 0x00,
0x00, 0x63, 0xC7, 0xCF, 0xDB, 0xF3, 0x63, 0x00,
0x00, 0x42, 0xDB, 0xDB, 0xDB, 0xFF, 0x66, 0x00,
0x00, 0x3E, 0x46, 0xFF, 0xFF, 0x06, 0x06, 0x00,
0x00, 0xF6, 0xF7, 0xD3, 0xD3, 0xDF, 0xDE, 0x00,
0x00, 0x7E, 0xFF, 0xDB, 0xDB, 0xDF, 0x4E, 0x00,
0x00, 0xC0, 0xC0, 0xC7, 0xFF, 0xF8, 0xC0, 0x00,
0x00, 0xFF, 0xFF, 0xDB, 0xDB, 0xFF, 0xFF, 0x00,
0x00, 0x72, 0xFB, 0xDB, 0xDB, 0xFF, 0x7E, 0x00,
code:告诉单片机,我定义的数据要放在ROM(程序存储区)里面,写入后就不能再更改
7. A/D和D/A工作原理
7.1 D/A:数字量/模拟量转换器
数字量:一系列的0和1组成的二进制代码表示某个信号大小的量
模拟量:温度、压力、位移、图像等
7.1.1 倒T形电阻解码网络D/A转换器
7.1.2 DAC0832
电流型 8位 T型电阻解码网络 D/A转换器芯片
7.2 A/D:模拟量/数字量转换器
7.2.3 ADC0808/0809
8位CMOS逐次逼近型A/D转换器芯片
8. 直流电机
输入或输出为直流电能的旋转电机
8.1 L293D
停止:电机自然停下
刹停:电机突然停下
9. 步进电机
电脉冲信号转变为角位移或线位移
9.1 L298
9.2 四相步进电机
10. LCD12864
10.1 基本代码
#define LCD_databus P0
sbit DI = P2^2;
sbit RW = P2^3;
sbit EN = P2^4;
sbit CS1 = P2^0;
sbit CS2 = P2^1;
void Read_busy()
{
P0 = 0X00;
DI = 0;
RW = 1;
EN = 1;
while(P0 & 0x80)
{;}
EN = 0;
}
void write_LCD_command(uint8 value)
{
Read_busy();
DI = 0;
RW = 0;
LCD_databus = value;
EN = 1;
_nop_();
_nop_();
_nop_();
EN = 0;
}
void write_LCD_data(uint8 value)
{
Read_busy();
DI = 1;
RW = 0;
LCD_databus = value;
EN = 1;
_nop_();
_nop_();
_nop_();
EN = 0;
}
void Set_page(uint8 page)
{
page = 0xB8 | page;
write_LCD_command(page);
}
void Set_line(uint8 startline)
{
startline = 0xC0 | startline;
write_LCD_command(startline);
}
void Set_column(uint8 column)
{
column = column & 0x3F;
column = column | 0x40;
write_LCD_command(column);
}
void SetOnOff(uint8 onoff)
{
onoff = 0x3E | onoff;
write_LCD_command(onoff);
}
void SelectScreen(uint8 screen)
{
switch(screen)
{
case 0:CS1 = 0;CS2 = 0;break;
case 1:CS1 = 0;CS2 = 1;break;
case 2:CS1 = 1;CS2 = 0;break;
default:break;
}
}
void ClearScreen(uint8 screen)
{
uint8 i,j;
SelectScreen(screen);
for(i=0;i<8;i++)
{
Set_page(i);
Set_column(0);
for(j=0;j<64;j++)
{
write_LCD_data(0x00);
}
}
}
void InitLCD()
{
Read_busy();
SelectScreen(0);
SetOnOff(0);
SelectScreen(0);
SetOnOff(1);
SelectScreen(0);
ClearScreen(0);
Set_line(0);
}
void show_ch(uint8 screen,uint8 page,uint8 column,uint8 *p)
{
uint8 i;
SelectScreen(screen);
Set_page(page);
Set_column(column);
for(i=0;i<16;i++)
{
write_LCD_data(p[i]);
}
Set_page(page+1);
Set_column(column);
for(i=0;i<16;i++)
{
write_LCD_data(p[i+16]);
}
}
11. IIC
同步串行通信,半双工
11.1 主机和从机
主机:产生时钟、起始信号和终止信号
从机:可编程的IIC地址检测,停止位检测
支持不同速率的通讯速度,标速(最高100kHz)、快速(400kHz)
11.2 SDA和SCL的数据传输
SDA:串行数据线 传输数据
SCL :串行时钟线 数据同步
SDA上在SCL的每个时钟周期传输一位数据
SDA上的数据传输 必须在SCL高电平时进行
SDA上的数据高低电平翻转 必须在SCL低电平时进行
每次传送一个字节(8位),先传送最高位
每一个被传送的字节后面必须跟一个应答位(共9位)
起始信号:SCL高电平,SDA高电平→低电平
终止信号:SCL高电平,SDA低电平→高电平
起始、终止信号均由主机发出,在起始信号产生后,总线就处于被占用的状态;在终止信号产生后,总线就处于空闲状态
11.3 基本代码
具体使用方法见 EEPROM 12.2/3
void IIC_Delay()
{
_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();
}
void IIC_Init()
{
SDA = 1;
SCL = 1;
}
void IIC_Start()
{
SCL = 1;
SDA = 1;
IIC_Delay();
SDA = 0;
IIC_Delay();
SCL = 0;
IIC_Delay();
}
void IIC_Stop()
{
SCL = 0;
SDA = 0;
IIC_Delay();
SCL = 1;
IIC_Delay();
SDA = 1;
IIC_Delay();
}
void IIC_ACK()
{
unsigned char i=0;
SCL = 1;
IIC_Delay();
while((SDA==1)&&(i<255))
{
i++;
}
SCL = 0;
IIC_Delay();
}
void IIC_Write_Byte(unsigned char j)
{
unsigned char i,temp;
temp = j;
SCL = 0;
IIC_Delay();
for(i=0;i<8;i++)
{
temp <<= 1;
SDA = CY;
IIC_Delay();
SCL = 1;
IIC_Delay();
SCL = 0;
IIC_Delay();
}
SDA = 1;
IIC_Delay();
}
unsigned char IIC_Read_Byte()
{
unsigned char i,j,k=0;
SCL = 0;
IIC_Delay();
for(i=0;i<8;i++)
{
SCL = 1;
IIC_Delay();
if(SDA == 1)
j = 1;
else
j = 0;
k = (k<<1) | j;
SCL = 0;
}
return(k);
}
12. EEPROM
采样IIC协议的接口与单片机相连,在proteus上可以体现出EEPROM的断点储存效果
下面的代码中IIC功能函数参考 IIC:11.3
12.1 器件地址
以24C02C为例:
高4位固定:1010 //不同类型器件高4位不同,由半导体公司生产时固定
低4位由A0、A1、A2和R/W(读/写位)决定 //用户可自定义
实际为7位地址,最后一位决定对EEPROM读或写
如图所示连接方式,地址为:1010 0000(0xa0),读数据时,地址为1010 0001(0xa1)
12.2 写数据
一次写一个字节,需要指定所写字节在EEPROM中的地址(24C02C储存数据最多为256个字节)
IIC_Init();
IIC_Start();
IIC_Write_Byte(0xa0);
IIC_ACK();
IIC_Write_Byte(0x00);
IIC_ACK();
IIC_Write_Byte(0xfe);
IIC_ACK();
IIC_Write_Byte(0x01);
IIC_ACK();
IIC_Write_Byte(0xfd);
IIC_ACK();
IIC_Write_Byte(0x02);
IIC_ACK();
IIC_Write_Byte(0xfb);
IIC_ACK();
IIC_Stop();
12.3 读数据
一次读一个字节,需要指定所读字节在EEPROM中的地址
IIC_Init();
IIC_Start();
IIC_Write_Byte(0xa0);
IIC_ACK();
IIC_Write_Byte(0x00);
IIC_ACK();
IIC_Start();
IIC_Write_Byte(0xa1);
IIC_ACK();
a = IIC_Read_Byte();
IIC_Write_Byte(0x01);
IIC_ACK();
IIC_Start();
IIC_Write_Byte(0xa1);
IIC_ACK();
b = IIC_Read_Byte();
IIC_Write_Byte(0x02);
IIC_ACK();
IIC_Start();
IIC_Write_Byte(0xa1);
IIC_ACK();
c = IIC_Read_Byte();
IIC_Stop();
14. SPI
高速的,全双工,同步的通信总线
4根线:
- SDO – 主设备数据输出,从设备数据输入
- SDI – 主设备数据输入,从设备数据输出
- SCK – 时钟信号,由主设备产生
- CS – 从设备使能信号,由主设备控制
15. 位符操作 & |
15.1 基本概念
1&1=1 1&0=0 0&0=0
1|1=1 1|0=1 0|0=0
15.2 基本代码
int n = 0x2d;
printf("原来的数为:%d\n",n);
int res = n|(1<<2);
printf("第3位改为1:%d\n",res);
int r2 = n&~(1<<3);
printf("第4位改为0:%d\n",r2);
int r3 = n|(1<<4);
printf("第5位改为1:%d\n",r3);
int r4 = n&~(1<<2);
printf("第3位改为0:%d\n",r4);
16. 位移操作 << >>
16.1 左移<<
i << j
i中所有的位向左移动j个位置,而右边填入0
16.2 右移>>
i中所有的位向右移j位
(1)对于unsigned类型,左边填入0
(2)对于signed类型,左边填入原来的最高位
所有小于int的类型,默认以int型操作
x <<= 1;
x <<= n;
x >>= 1;
x >>= n;
```c
ntf("第3位改为1:%d\n",res);
int r2 = n&~(1<<3);
printf("第4位改为0:%d\n",r2);
int r3 = n|(1<<4);
printf("第5位改为1:%d\n",r3);
int r4 = n&~(1<<2);
printf("第3位改为0:%d\n",r4);
16. 位移操作 << >>
16.1 左移<<
i << j
i中所有的位向左移动j个位置,而右边填入0
16.2 右移>>
i中所有的位向右移j位
(1)对于unsigned类型,左边填入0
(2)对于signed类型,左边填入原来的最高位
所有小于int的类型,默认以int型操作
x <<= 1;
x <<= n;
x >>= 1;
x >>= n;
|