STC12手册通读

本文详细介绍了51单片机的相关知识点,包括串口下载程序ISP、波特率发生器、时钟输出、IAP/ISP理解、FLASH程序存储区、工作模式、IO口特性、寻址方式、中断优先级嵌套、UART寄存器、ADC使用等,并提供了多个实例代码。

有了一定的基础之后,总感觉亏欠51点什么。有时候做起东西来也并不是那么的得心应手,特别对于51单片机的寄存器。

今天特地重新翻阅了一遍51的手册,很多东西自己真的没注意到,特地记录。

1.关于串口下载程序ISP

犹记得学习51那会,有次因为下载程序怎么也下载不进去。就跑到交流群里面,问老宋。 老宋告诉我把P10和P11和GND短接起来再下载,然后断开再下载试试。。当时也不明白缘由,今日翻阅手册恍然大悟。 我们是可以通过P10/P11禁止ISP下载程序的!

这里写图片描述

2、关于波特率发生器

89系列的单片机是没有独立的波特率发生器这一说的,但是要注意。89系列的波特率发生器只能让T1或者T2来做,(通常T2的配置较为繁琐,故一般用的都是T1)。然后到了STC12就有了自己的独立波特率发生器BRT。同时还需要注意的是,12单片机没了T2这个定时器!

3、关于时钟输出

12单片机有3种时钟输出方式:
T0 (P34)、T1(P35)以及利用有源晶振接入XTAL1,然后在XTAL2得到输出的脉冲(需要串接一个200欧的电阻)。
这里就提到了12单片机外接有源晶振的情况,要特别注意XTAL2引脚是悬空的。这里写图片描述

对了,还有个时钟输出的三个寄存器。
这里写图片描述

要特别注意配置的三个地方:
这里写图片描述
① 时钟输出只能工作在8位自动重装载模式下
② 溢出率其实就是多少个数溢出一次,所以直接就是SYSCLK/(256-TH1)对应的就是溢出率
③C/T的选择,0一个是内部时钟时钟计数,1是外部输入时钟计数。

eg1: 独立波特率发生器用来时钟输出

#include <stc12.h>

//-----------------------------------------------

/* define constants */
#define FOSC 11059200L
//#define MODE1T                      //Timer clock mode, comment this line is 12T mode, uncomment is 1T mode

#ifdef MODE1T
#define F38_4KHz (256-FOSC/2/38400)    //38.4KHz frequency calculation method of 1T mode
#else
#define F38_4KHz (256-FOSC/2/12/38400) //38.4KHz frequency calculation method of 12T mode
#endif

sbit BRTCLKO  = P1^0;               //BRT clock output pin

//-----------------------------------------------

/* main program */
void main()
{
#ifdef MODE1T
    AUXR = 0x04;                    //BRT work in 1T mode
#endif
    BRT = F38_4KHz;                 //initial BRT
    AUXR |= 0x10;                   //BRT start running
    WAKE_CLKO = 0x04;               //enable BRT clock output

    while (1);                      //loop
}

eg2: T0用来时钟输出 (必须工作在8位自动重装载模式下)

#include <stc12.h>

//-----------------------------------------------

/* define constants */
#define FOSC 11059200L
//#define MODE1T                      //Timer clock mode, comment this line is 12T mode, uncomment is 1T mode

#ifdef MODE1T
#define F38_4KHz (256-FOSC/2/38400)    //38.4KHz frequency calculation method of 1T mode
#else
#define F38_4KHz (256-FOSC/2/12/38400) //38.4KHz frequency calculation method of 12T mode
#endif

sbit T0CLKO  = P1^0;               //T0 clock output pin

//-----------------------------------------------

/* main program */
void main()
{
#ifdef MODE1T
    AUXR = 0x80;                    //T0 work in 1T mode
#endif
    TMOD = 0x02;                    //T0 T1 必须8位自动重装载
    TH0 = F38_4KHz;                 //initial TH0
    TL0 = F38_KHz;
    TR0 = 1;                        //T0 start running
    WAKE_CLKO = 0x01;               //enable T0 clock output

    while (1);                      //loop
}

eg3: 同T0 此处省略。。。

#include <stc12.h>

//-----------------------------------------------

/* define constants */
#define FOSC 11059200L
//#define MODE1T                      //Timer clock mode, comment this line is 12T mode, uncomment is 1T mode

#ifdef MODE1T
#define F18_4KHz (256-FOSC/2/18400)    //18.4K
#define F28_4KHz (256-FOSC/2/28400)    //28.4K
//#define F38_4KHz (256-FOSC/2/38400)    //38.4KHz frequency calculation method of 1T mode

#else
#define F18_4KHz (256-FOSC/2/12/18400) //18.4K
#define F28_4KHz (256-FOSC/2/12/28400) //28.4K
#define F38_4KHz (256-FOSC/2/12/38400) //38.4KHz frequency calculation method of 12T mode
#endif

//sbit T0CLKO  = P3^4;               //T0 clock output pin
//sbit T1CLKO  = P3^5;               //T1 clock output pin
//sbit BRTCLKO  = P1^0;               //BRT clock output pin
//-----------------------------------------------

/* main program */
void main()
{
#ifdef MODE1T
    AUXR = 0x80;                    //T0 work in 1T mode
#endif
    TMOD = 0x22;                    //T0 T1
    BRT = F18_4KHz;
    TH0 = F28_4KHz;                 //initial TH0
    TL0 = T28_4KHz;
    TH1 = F38_4KHz;
    TL1 = F18_4KHz;

    AUXR |= 0x10;
    TR0 = 1;                        //T0 start running
    TR1 = 1;

    WAKE_CLKO = 0x04;
    WAKE_CLKO |= 0x01;               //enable T0 clock output
    WAKE_CLKO |= 0x02;

    while (1);                      //loop
}

4、IAP/ISP的理解

ISP其实就可简单理解为下载程序的那个STC-ISP下载器,在系统编程。
当然也有个ISP系统监控程序区。可参考:STC12复位到ISP自动下载程序

AP开头的单片机在程序运行过程中由程序修改或者擦除整个Flash、

5、FLASH 程序存储区
程序存储区,让传统的只读程序存储器变成可读/写程序存储器,程序运行过程中写入flash的数据和程序一样,具有掉电不丢失的功能。

6、单片机的三种工作模式
三种工作方式: 空闲工作模式,正常工作模式,以及掉电模式
特别注意一下,空闲模式

以前用PCA的时候,没有特意去看,其实这玩意可没那么肤浅。。。

手册上写的也是很清楚的,空闲工作模式下CPU无时钟停止工作,其余模块仍然继续工作,看门狗是否工作要看它的相关寄存器配置。任何一个中断都可以唤醒空闲模式为正常工作。

7、关于IO口
四种工作方式:

准双向/弱上拉、强推挽/强上拉、高阻态/仅为输入、开漏/外加上拉电阻可作为输入

准双向IO口,要正确读取外部状态,必须先保证自己是高电平。
这里写图片描述

IO口使用的注意事项:
值得注意的就是12有别于89的速度问题。
这里写图片描述

让IO口上电复位是低电平的硬件实现
这里写图片描述

8、关于指令集的寻址方式:

立即寻址
直接寻址
间接寻址
寄存器寻址
相对寻址
变址寻址
位寻址

9、关于中断优先级的嵌套问题

传统的8051单片机对中断优先级的设定只要一个寄存器就是IP,故最多可以形成两层嵌套,第一级和最后一级。

12多加了IPH,故可以形成4层嵌套。
这里写图片描述

这里写图片描述

10、关于STC-ISP中的串口初始化函数直接可调用的!

void UartInit(void)     //9600bps@11.0592MHz
{
    AUXR &= 0xF7;       //波特率不倍速
    S2CON = 0x50;       //8位数据,可变波特率
    AUXR |= 0x04;       //独立波特率发生器时钟为Fosc,即1T
    BRT = 0xDC;     //设定独立波特率发生器重装值
    AUXR |= 0x10;       //启动独立波特率发生器
}
void UartInit(void)     //9600bps@11.0592MHz
{
    AUXR &= 0xF7;       //波特率不倍速
    S2CON = 0x50;       //8位数据,可变波特率
    AUXR &= 0xFB;       //独立波特率发生器时钟为Fosc/12,即12T
    BRT = 0xFD;     //设定独立波特率发生器重装值
    AUXR |= 0x10;       //启动独立波特率发生器
}

11、关于C/T
C/T = 0 就是对内部时钟进行计数

C/T = 1 就是对外部脉冲进行计数

12、UART 的寄存器组成
这里写图片描述

13、12的ADC使用

寄存器组成
这里写图片描述

结果寄存器
这里写图片描述

12具有8路10位ADC 就是在P1口的八个

ADRJ = 0
这里写图片描述
ADRJ = 1
这里写图片描述

P1ASF直接控制是否作为模拟功能口使用—相当于IO口和AD口开关选择
这里写图片描述

而CHX 是决定打开哪个AD开关作为模拟输入
这里写图片描述

13、PCA
突然意识到一点,ECF和ECCF0是不一样的,也没有什么“牵制”的关系。
ECF是计数器溢出的中断标志。
而ECCF是发生匹配或者捕获的中断标志!
①、定时器
步长的计算是这样的:步长 = 定时时间 * 计数脉冲频率

#include "reg51.h"
#include "intrins.h"

#define FOSC    11059200L
#define T100Hz  (FOSC / 12 / 100)   //频率设定

typedef unsigned char BYTE;
typedef unsigned int WORD;

sbit PCA_LED    =   P1^1;           //PCA test LED

BYTE cnt;
WORD value;

void PCA_isr() interrupt 7 using 1
{
    CCF0 = 0;                       //Clear interrupt flag
    CCAP0L = value;
    CCAP0H = value >> 8;            //Update compare value
    value += T100Hz;
    if (cnt-- == 0)
    {
        cnt = 100;                  //Count 100 times
        PCA_LED = !PCA_LED;         //Flash once per second
    }
}

void main()
{
    CCON = 0;                       //Initial PCA control register
                                    //PCA timer stop running
                                    //Clear CF flag
                                    //Clear all module interrupt flag
    CL = 0;                         //Reset PCA base timer
    CH = 0;
    CMOD = 0x00;                    //Set PCA timer clock source as Fosc/12
                                    //Disable PCA timer overflow interrupt
    value = T100Hz;
    CCAP0L = value;
    CCAP0H = value >> 8;            //Initial PCA module-0
    value += T100Hz;
    CCAPM0 = 0x49;                  //PCA module-0 work in 16-bit timer mode and enable PCA interrupt

    CR = 1;                         //PCA timer start run
    EA = 1;
    cnt = 0;

    while (1);
}

②外部中断
设置好哪个沿触发就好

#include "reg51.h"
#include "intrins.h"

typedef unsigned char BYTE;
typedef unsigned int WORD;
sbit PCA_LED    =   P1^0;           //PCA test LED

void PCA_isr() interrupt 7 using 1
{
    CCF0 = 0;                       //Clear interrupt flag
    PCA_LED = !PCA_LED;             //toggle the test pin while CEX0(P1.3) have a falling edge
}

void main()
{
    CCON = 0;                       //Initial PCA control register
                                    //PCA timer stop running
                                    //Clear CF flag
                                    //Clear all module interrupt flag
    CL = 0;                         //Reset PCA base timer
    CH = 0;
    CMOD = 0x00;                    //Set PCA timer clock source as Fosc/12
                                    //Disable PCA timer overflow interrupt
                                    //触发方式选择
    CCAPM0 = 0x11;                  //PCA module-0 capture by a negative tigger on CEX0(P1.3) and enable PCA interrupt
//  CCAPM0 = 0x21;                  //PCA module-0 capture by a rising edge on CEX0(P1.3) and enable PCA interrupt
//  CCAPM0 = 0x31;                  //PCA module-0 capture by a transition (falling/rising edge) on CEX0(P1.3) and enable PCA interrupt

    CR = 1;                         //PCA timer start run
    EA = 1;

    while (1);
}

③PWM

频率各个通道都是一样的,唯一可调就是通过CCAPnH的占空比

PWM默认输出频率 = 系统时钟/12/256
PWM输出占空比 = (1-CCAPnH/256)
CCAPnH = (1-占空比)*256

void PwnInit()
{
    //PWM1
    CCON=0x00;//PCA初始化
    CL=0;//PCA的16位计数器低八位
    CH=0;//PCA的16位计数器高八位
    CMOD=0x00;//选择 系统时钟/12 为计数脉冲,则PWM的频率f=sysclk/256/12;

    CCAP0H=0x80;//占空比控制50%
    CCAP0L=0x80;  
    PCA_PWM0=0x00;//控制占空比的第九位为0

    //P13作为PWM0输出
    CCAPM0=0x42; //允许
    //CCAPM0=0x40; //禁止

    //PWM2  
    CCAP1H=0x80;//占空比控制
    CCAP1L=0x80;  
    PCA_PWM1=0x00;//控制占空比的第九位为0

    //P14作为PWM1输出
    CCAPM1=0x42;//允许
    //CCAPM1=0X40;//禁止

    CR=1;//启动PCA计数器
}

④高速脉冲输出模式
PCA计数器步长值 = 计数脉冲频率/(2*Fout)


#include "reg51.h"
#include "intrins.h"

#define FOSC    11059200L
#define T100KHz ((FOSC / 2)/ 2 / 100000)

typedef unsigned char BYTE;
typedef unsigned int WORD;
sbit PCA_LED    =   P1^0;           //PCA test LED

BYTE cnt;
WORD value;

void PCA_isr() interrupt 7 using 1
{
    CCF0 = 0;                       //Clear interrupt flag
    CCAP0L = value;
    CCAP0H = value >> 8;            //Update compare value
    value += T100KHz;
}

void main()
{
    CCON = 0;                       //Initial PCA control register
                                    //PCA timer stop running
                                    //Clear CF flag
                                    //Clear all module interrupt flag
    CL = 0;                         //Reset PCA base timer
    CH = 0;
    CMOD = 0x02;                    //Set PCA timer clock source as Fosc/2
                                    //Disable PCA timer overflow interrupt
    value = T100KHz;
    CCAP0L = value;                 //P1.3 output 100KHz square wave
    CCAP0H = value >> 8;            //Initial PCA module-0
    value += T100KHz;
    CCAPM0 = 0x4d;                  //PCA module-0 work in 16-bit timer mode and enable PCA interrupt, toggle the output pin CEX0(P1.3)

    CR = 1;                         //PCA timer start run
    EA = 1;
    cnt = 0;

    while (1);
}

14、硬件SPI的实验

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

①关于单主单从
这里写图片描述

②关于互为主从
这里写图片描述

这里写图片描述

SS被忽略的情况
这里写图片描述

③一主多从
这里写图片描述

SPI配置一览表
这里写图片描述

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ReCclay

如果觉得不错,不妨请我喝杯咖啡

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值