硬件: 在STC89C52RC上
GPIO中的LED相关引脚:P20~P27
关于GPIO的相关认识,以点灯程序来初步认识GPIO引脚
GPIO:通用输入输出接口,也就是51单片机上的引脚。
点灯:首先通过简单的引脚配置理解GPIO的含义,单片机的外设引脚控制相关的外设,例如LED灯的亮灭。
void ledAllOff(unsigned char ledNum)
{
P2 = 0xFF;
}
void ledAllOn(unsigned char ledNum)
{
P2 = 0x00;
}
void ledOn(unsigned char ledNum)
{
P2 = ~(ledNum)
}
int main(void)
{
ledAllOff();
ledOn(0x0F); //点亮低4位
}
关于硬件名词的一些认识:51单片机属于一种MCU
关于CPU、SOC、MPU、MCU
CPU:是用来控制和计算的核心,只负责这些
SOC:(片上系统)是CPU和外设的集合,可以理解为CPU+外设
MPU:微处理单元,是SOC的子集,只包含CPU
MCU:微控制单元(单片机)是SOC的子集,只包含CPU和外设
关于51的方言关键字:xdata
xdata可以将数据定义在SRAM中
示例:xdata unsigned char ledNum[4] = {0x01, 0x02, 0x04, 0x08};
关于代码存放位置的理解:(汇编)
代码编译以后会生成一堆机器指令:存放在ROM
MOV r0, #1
MOV r1, #2
add r2, r1, r0
MOV &i r2
这些MOV、add、#1等指令存放在ROM里,在C语言内存映射中理解为代码区
P2既不存储在RAM也不存储在ROM,P2是寄存器
RAM、ROM、寄存器的区别:
特点:
访问速度:
易失性:
在51单片机中总线个数为
#define P2 *((unsigned char *)0xA0);
P2 的地址
对于寄存器的理解:
控制硬件
按键控制:
if((P1 & (1 << 4)) == 0) //如果P1(按键1按下)的第4位为0,则执行下面的语句
{
P0 = 0x01;
}
else
{
P0 = 0x00;
}
指令周期和机器周期
指令周期:1/CPU频率
机器周期:取决于晶体振荡器51单片机的指令周期是由12个机器周期组成
12M的机器周期就是1M的指令周期
什么是中断:
在中央处理器CPU执行的过程中,外部发生更为紧急的事物,可以打断CPU的正在运行的工作,转而去执行更为紧急的事情,执行结束之后回到原来的状态。
ARM不允许中断嵌套(s3c2440)
中断服务程序:发生中断之后的处理程序中断向量表:中断处理程序地址表(函数指针数组)
UART串口通信
51单片机串口通信:有2个互相独立的接收、发送缓冲器,可以同时发送和接收数据。(全双工串行通信口)
串行通信有四种工作方式:两种方式的波特率可变,另外两种固定。
波特率由内部定时器/计数器产生。
CH340:TTL转USB串口
串口的相关寄存器: 1200,n,8,1
设置波特率:SM0:0, SM1:1
#include <reg51.h>
void uart_init(void)
{
SCON |= (1 << 6);
SCON &= ~(1 << 7);
SCON |= (1 << 4);
//SCON &= ~(1 << 5);
PCON |= (1 << 7);
PCON &= ~(1 << 6);
TCON |= (1 << 6);
TMOD |= (1 << 5);
TMOD &= ~(1 << 4);
TH1 = 204;
TL1 = 204;
}
void uartChar(unsigned char n)
{
SBUF = n;
while ( (SCON & (1 << 1)) == 0);
SCON &= ~(1 << 1);
}
void uartString(char *s, unsigned int len)
{
unsigned int i;
for (i = 0; i < len; i++)
{
uartChar(s[i]);
}
}
int main(void)
{
uart_init();
while(1)
{
sendChar('A');
delay(0xFFFF);
}
return 0;
}
编写UART串口通信流程:
确定波特率,奇偶检验,数据位,结束位
由SCON以及PCON设置以上参数
TCON 设置定时器1
TMOD 确定定时器1的工作模式,是否8位自动重装,16位
使用中断实现串口通信
//使用串口中断实现串口通信(接收时的中断)
// 打开IE寄存器中的串口中断控制器
xdata unsigned char recvBuffer[24] = {0};
int pos = 0;
void uart_handler(void) interrupt 4 //中断执行函数
{
if (SCON & (1 << 0) != 0)
{
//P2 = SBUF;
recvBuffer[pos++] = SBUF;
SCON &= ~(1 << 0);
}
}
int main()
{
while (1)
{
if (pos != 0)
{
delay(0xFFFF);
if (recvBuffer[0] == 0 && recvBuffer[1] == 1)
{
sendChar("ok",2);
}
recvBuffer[0]
pos = 0;
memset(recvBuffer, 0, sizeof(recvBuffer));
}
}
}
逻辑分析:发送端直接发不使用中断,sendChar(); 接收端使用中断接收,避免轮询方式浪费资源。