1 8051CPU
8051是一种8位元的单芯片微控制器,属于MCS-51单芯片的一种,由英特尔(Intel)公司于1981年制造。Intel公司将MCS51的核心技术授权给了很多其它公司,所以有很多公司在做以8051为核心的单片机,如Atmel、飞利浦、深联华等公司,相继开发了功能更多、更强大的兼容产品。
总体架构

CPU主要由以下几个部分组成:
 (1)运算器: 运算器由算术/逻辑运算单元ALU、累加器ACC、寄存器B、暂存寄存器、程序状态字寄存器PSW组成。
 (2)控制器: 控制器由指令寄存器IR、指令译码及控制逻辑电路组成。
 (3)其他寄存器: 程序计数器PC、数据指针DPTR、堆栈指针SP、工作寄存器R0~R7

内存映射

SRAM映射到地址范围为0x0000到(SRAMSIZE-1)
XREG区域映射到1KB地址范围(0x6000-0x63FF)中。这些寄存器是附加寄存器,有效地扩展了SFR寄存器空间。一些外围寄存器和大多数无线电控制和数据寄存器都映射在这里。
SFR寄存器映射到地址范围(0x7080-0x70FF)闪存信息页(2KB)陕射到地址范围(0x7800-0x7FFF)中。这是一个只读区域,包含有关设备的各种信息。
SFR寄存器地址总览

2 基础实验
2.1 流水灯
实验目的

相关寄存器
下面我们以 P1.0 控制的 LED1 为例,操作 P1.0 时我们需要掌握相关寄存器的作用和配置方法。

下面我们以 P1.0 控制的 LED1 为例,操作 P1.0 时我们需要掌握相关寄存 器的作用和配置方法。
/****************************************************************************
* 文 件 名: main.c
* 作    者: 
* 网    站: 
* 修    订: 
* 版    本: 1.0
* 描    述: 操作IO口控制4盏LED灯的全亮和全灭、闪烁、流水灯
****************************************************************************/
#include <ioCC2541.h>#define uchar unsigned char 
#define uint unsigned int #define LED1 P1_0       //定义P1.0口为LED1控制端
#define LED2 P1_1       //定义P1.1口为LED2控制端
#define LED3 P0_4       //定义P0.4口为LED3控制端/****************************************************************************
* 名    称: Delay_ms()
* 功    能: 以毫秒为单位延时,系统时钟不配置时默认为16M(用示波器测量相当精确)
* 入口参数: msec 延时参数,值越大,延时越久
* 出口参数: 无
****************************************************************************/
void DelayMs(uint len)
{ while(len--)for (int i=0; i<535; i++);
}/****************************************************************************
* 名    称: LedOnOrOff()
* 功    能: 点亮或熄灭所有LED灯    
* 入口参数: mode为1时LED灯亮  mode为0时LED灯灭, 共阴极
* 出口参数: 无
****************************************************************************/
void LedOnOff(uchar mode)
{LED1 = mode;LED2 = mode;LED3 = mode;
}/****************************************************************************
* 名    称: InitLed()
* 功    能: 设置LED灯相应的IO口
* 入口参数: 无
* 出口参数: 无
****************************************************************************/
void InitLed(void)
{P1DIR |= 0x03;      //P1.0、P1.1定义为输出P0DIR |= 0x10;      //P0.4定义为输出LedOnOff(0);      //使所有LED灯默认为熄灭状态
}/****************************************************************************
* 程序入口函数
****************************************************************************/
void main(void)
{uchar i;InitLed();               //设置LED灯相关IO口while(1)                 //死循环{  LED1 = !LED1;         //流水灯,初始化时LED为熄灭执行后则点亮DelayMs(200);         LED2 = !LED2;         DelayMs(200);            LED3 = !LED3;        DelayMs(200);         for (i=0; i<2; i++)   //所有灯闪烁2次{LedOnOff(0);    //关闭所有LED灯DelayMs(200);LedOnOff(1);    //打开所有LED灯DelayMs(200);}LedOnOff(0);    //使所有LED灯熄灭状态DelayMs(200);LedOnOff(1);       DelayMs(500);LedOnOff(0);    //使所有LED灯熄灭状态DelayMs(200);}
}
2.2 按键控制 LED 跑马灯
/****************************************************************************
* 文 件 名: main.c
* 作    者:
* 网    站: 
* 修    订: 
* 版    本: 1.0
* 描    述: 按下按键S1控制LED1.LED2.LED3实现跑马灯效果
****************************************************************************/
#include <ioCC2540.h>#define uchar unsigned char 
#define uint unsigned int #define LED1 P1_0        // 定义P1.0口为LED1控制端
#define LED2 P1_1        // 定义P1.1口为LED2控制端
#define LED3 P0_4        // 定义P0.4口为LED3控制端
#define KEY1 P0_1        // 定义P0.1口为S1控制端
#define ON      1
#define OFF     0/****************************************************************************
* 名    称: DelayMS()
* 功    能: 以毫秒为单位延时,系统时钟不配置时默认为16M(用示波器测量相当精确)
* 入口参数: msec 延时参数,值越大,延时越久
* 出口参数: 无
****************************************************************************/
void DelayMS(uint len)
{ while(len--)for (int i=0; i<535; i++);
}/****************************************************************************
* 名    称: LedOnOrOff()
* 功    能: 点亮或熄灭所有LED灯    
* 入口参数: mode为1时LED灯亮  mode为0时LED灯灭
* 出口参数: 无
****************************************************************************/
void LedOnOrOff(uchar mode)
{LED1 = mode;LED2 = mode;LED3 = mode; 
}/****************************************************************************
* 名    称: InitLed()
* 功    能: 设置LED相应的IO口
* 入口参数: 无
* 出口参数: 无
****************************************************************************/
void InitLed(void)
{P1DIR |= 0x03;  // P1.0、P1.1定义为输出P0DIR |= 0x10;  // P0.4定义为输出LedOnOrOff(0);  // 使所有LED灯默认为熄灭状态  
}/****************************************************************************
* 名    称: InitKey()
* 功    能: 设置按键相应的IO口
* 入口参数: 无
* 出口参数: 无
****************************************************************************/
void InitKey(void)
{P0SEL &= ~0x02;     //设置P0.1为普通IO口  P0DIR &= ~0x02;     //按键接在P0.1口上,设P0.1为输入模式 P0INP &= ~0x02;     //打开P0.1上拉电阻
}/****************************************************************************
* 名    称: KeyScan()
* 功    能: 读取按键状态
* 入口参数: 无
* 出口参数: 0为抬起   1为按键按下
****************************************************************************/
uchar KeyScan(void)
{if (KEY1 == 0){DelayMS(10);      //延时10MS去抖if (KEY1 == 0){while(!KEY1); //松手检测return 1;     //有按键按下}}return 0;             //无按键按下
}/****************************************************************************
* 程序入口函数
****************************************************************************/
void main(void)
{InitLed();		      //设置LED灯相应的IO口InitKey();            //设置按键S1相应的IO口while(1){DelayMS(2);if (KeyScan())    //扫描按键当前状态,按下按钮 松开 后执行{LED1 = ON;    //点亮LED1      DelayMS(200); LED1 = OFF;   //熄灭LED1 LED2 = ON;                DelayMS(200); LED2 = OFF;            LED3 = ON;           DelayMS(200); LED3 = OFF; }}
}
2.3 外部中断
原理同上



 
/****************************************************************************
* 文 件 名: main.c
* 描    述: 通过按键S1产生外部中断改变LED1状态
****************************************************************************/
#include <ioCC2541.h>#define uchar unsigned char 
#define uint unsigned int#define LED1 P1_0       // P1.0口控制LED1
#define KEY1 P0_1       // P0.1口控制S1/****************************************************************************
* 名    称: DelayMS()
* 功    能: 以毫秒为单位延时,系统时钟不配置时默认为16M(用示波器测量相当精确)
* 入口参数: msec 延时参数,值越大,延时越久
* 出口参数: 无
****************************************************************************/
void DelayMS(uint len)
{ while(len--)for (int i=0; i<535; i++);
}/****************************************************************************
* 名    称: InitLed()
* 功    能: 设置LED灯相应的IO口
* 入口参数: 无
* 出口参数: 无
****************************************************************************/
void InitLed(void)
{P1DIR |= 0x01;   //P1.0定义为输出口LED1 = 0;        //LED1灯灭 
}/****************************************************************************
* 名    称: InitKey()
* 功    能: 设置KEY相应的IO口,采用中断方式 
* 入口参数: 无
* 出口参数: 无
****************************************************************************/
void InitKey()
{P0IEN |= 0x02;    // P0.1 设置为中断方式 1:中断使能PICTL |= 0x02;    //下降沿触发   IEN1 |= 0x20;    //允许P0口中断; P0IFG = 0x00;    //初始化中断标志位EA = 1;          //打开总中断
}/****************************************************************************
* 名    称: P0_ISR(void) 中断处理函数 
* 描    述: #pragma vector = 中断向量,紧接着是中断处理程序
****************************************************************************/
#pragma vector = P0INT_VECTOR    
__interrupt void P0_ISR(void) 
{ DelayMS(10);     //延时去抖LED1 = ~LED1;    //改变LED1状态P0IFG = 0;       //清中断标志 P0IF = 0;        //清中断标志 
} /****************************************************************************
* 程序入口函数
****************************************************************************/
void main(void)
{InitLed();   //设置LED灯相应的IO口InitKey();   //设置S1相应的IO口while(1){}
}
2.4 定时器 T1-查询方式
 
 
定时器T1的时钟频率为32MHz / 128 = 250kHz。
在这个配置下,当T1计数器溢出时,中断标志位IRCON会被置位。通过查询IRCON的值是否大于0,代码检测是否发生了定时器T1的中断。
在每次中断发生时,count会自增,并且当count累积到一定值时,LED1会翻转状态,实现LED的周期性闪烁。在这段代码中,count达到1时LED状态翻转,因此要实现约1秒的周期性闪烁,需要count累积到1。
/****************************************************************************
* 文 件 名: main.c
* 描    述: 定时器T1通过查询方式控制LED1周期性闪烁
****************************************************************************/
#include <ioCC2541.h>#define uchar unsigned char 
#define uint unsigned int#define LED1 P1_0       // P1.0口控制LED1/****************************************************************************
* 名    称: InitLed()
* 功    能: 设置LED灯相应的IO口
* 入口参数: 无
* 出口参数: 无
****************************************************************************/
void InitLed(void)
{P1DIR |= 0x01;      //P1.0定义为输出LED1 = 0;           //使LED1灯下电默认为熄灭     
}/****************************************************************************
* 名    称: InitT1()
* 功    能: 定时器初始化,系统不配置工作时钟时默认是2分频,即16MHz
* 入口参数: 无
* 出口参数: 无
****************************************************************************/
void InitT1()
{T1CTL = 0x0d;       //128分频,自动重装 0x0000-0xFFFF T1STAT= 0x21;       //通道0,中断有效   
}/****************************************************************************
* 程序入口函数
****************************************************************************/
void main(void)
{uchar count=0;InitLed();		     //调用初始化函数InitT1();while(1){if(IRCON > 0){ IRCON=0;if(count++ >= 1) //约1s周期性闪烁,示波器测大约为1025MS{count=0;LED1 = !LED1;  //LED1闪烁        }} }
}