单片机笔记

安装驱动后,C盘有WCH.CN文件夹

单片机 Micro Controller Unit MCU
RAM random access memory 随机存取存储器
ROM read only memory 只读存储器
    
STC89C52RC/LE52RC
    8位
    RAM 512B
    ROM 8K
    11.0592MHz工作频率 由晶振提供,铭刻在单片机晶振外壳上
    管脚
        P0~P3,每P八个引脚
        Vcc 40 电源正极
        Gnd 20 电源负极
        XTAL 外接晶振
        RST 复位
    正负极间有滤波电容滤波

引脚    元件连接和传输电信号

端口    物理连接点:引脚,电缆
    逻辑连接点:软件实现

串口    串行通信的接口

=================================================

LED灯点亮
    创建程序选择的单片机为2Microchip里的AT89C51RC2
        为Source Group 1 添加新文件Main.c由c语言编写
        添加头文件#include <REGX52.H>,定义了芯片内的寄存器
            sfr    (C语言关键字) 特殊功能寄存器声明 Special Function Register
            sbit    (C语言关键字) 特殊位声明    Special Bit
        P2 = E //1111 1110
        E为注释中二进制数对应的16进制数,不区分大小写
        每一个数字代表一个引脚 最低位为P2.0引脚,0为低电位
    设置中,创建HEX文件
    
    开发板上,LED模块四个为一组,每组有四个电阻和LED灯
        正极先连接LED灯然后连接一个1KΩ的电阻
        之后依次连接单片机的P20~P27引脚
        电阻实物上标有102,为10 * 10^2Ω,对应的473,47 * 10^3Ω
        电阻起到限流作用
        正极给高电平5v
        负极是单片机IO口默认同样为5V高电平
        负极给低电平即在代码中令寄存器对应的位位0,电路连通,LED灯亮起

    STC-ISP中,设定芯片型号为STC89C52RC/LE52RC,调整串口,导入HEX文件,下载,开启按钮

=================================================

LED灯闪烁
    开发板晶振频率为11.0592MHz
    利用STC-ISP自带的软件延时计算器生成延时代码
        调整系统频率,开发板上的晶振有铭刻 
        输入定时长度
        设置8051指令集
        生成C代码
        生成的代码中有其他头文件的函数_nop_()
    导入头文件INTRINS.h
    导入延时函数,C语言需要把主函数放在其他函数下面,或者先声明函数然后把主函数放在所有函数体上面
    代码中引用函数
    STC-ISP中,调整串口,下载程序

=================================================

LED流水灯
    多次调整P2引脚的电位实现流水灯
    利用STC-ISP自带的软件延时计算器,生成延时1ms的代码,将延时主体循环固定次,固定次数位需要延时的毫秒数

=================================================

独立按键开关LED
    开发板原理图中,独立按键连接引脚P3.0~P3.3,默认按键断开,一端接单片机IO口,高电平,另一端接地
    当对应按键按下后,电路联通,相当于此引脚接地,变为低电平
    我改变IDE,用了vsCode,添加了Keil插件
    头文件reg52.h中,用sfr定义P0~P3四组,每组8个的引脚
        用sbit单独定义了每个引脚
    利用if判断独立按键引脚的电平,来控制led灯的亮灭
        头未见reg52.h中 ,P31是K1按键
        判断语句为 P31 == 1
    按位左移
        0011 1100 <<  1        ==>        0111 1000
    按位与和按位或
        以按位与举例
            0001 1000 & 0001 0000        ==>        0001 0000

=================================================

按钮松手时亮,在按一次,松手时灭
    按键消抖,因为有抖动10ms左右,所以设置按下时先延时20ms
        设置循环判定条件为按钮低电平,实现按住时一直执行
        松手后结束循环,再次消抖
        让当前的LED灯状态取反
    实现为
        delay(xx);
        while(按键 == 1);
        delay(xx);

=================================================

独立按键控制LED显示二进制
    P2引脚默认值为0xff,+1后为0x00,全低电平,led全亮
        -1后为1111 1110 对应最低为为0,LED1亮起

=================================================

按键控制LED位移
    用左移位运算符实现
    两个按键控制左右移动,都可以用左移运算符实现

=================================================

数码管显示
    一个数码管顺时针12点方向为a然后是bcdef中间是g,点为dp
        有两种连接引脚方式,共阴极和共阳极
        引脚上下两排,下派左到右为1-5,上排左到右为10-6,即逆时针排布
        公共引脚是3号和8号
        其他引脚按所处位置就近连接
            a段连7 b段连6 c段连4 d段连2 e段连1 f段连10 g段连9 dp段连5
                dp 为 小数点 decimal point 缩写
    四联数码管
        8进4出,进端口高电平让对应段亮起
        出端口低电平让对应数码管启用
        因为公共入口的原因,无法让任意两个数码管显示不同的数
            利用余辉效应,高频调用不同的进出串口
        我是用的开发板根据介绍,四联数码管为共阴极
    74HC138译码器
        3线-8线译码器,利用输入3线控制输出8线
        P22 P23 P24对应的ABC为输入端 Y1~Y7为输出端
        G1 G2为使能端口,有效时译码器工作
            G1接高电平,G2A G2B接低电平为有效
        C高位,A低位,排列CBA根据各自输入的电平,转换为二进制,令对应输出端口有效
            有效为0,无效为1
    74HC245
        双向数据缓冲器
        CE 芯片使能端 Chip Enable 低电平有效
        A端口与B端口一一对应
        DIR 方向端口 高电平 A -> B 低电平相反
    利用138译码器控制选择要显示的LED,再用P0引脚控制显示的段

    令第三个数码管显示数字6
        原理图显示,第三个数码管是LED6
        74H138译码器中,对应引脚LED6的是Y5端口
        ABC端口应为101,对应引脚赋值相同
        显示数字6需要将b段和dp之外的段置为高电平
        对应P00~P07引脚电平为1011 1110
        因为需要高位对高位,所以整体取逆 0111 1101
            P2=0x7d

=================================================

动态数码管显示

高速切换数码管,令不同的数码管显示不同的数字,利用留影效应

=================================================

模块化编程

把各个模块的代码放在不同的.c文件中
在.h文件中,提供外部可调用函数的声明
预编译
    #define PI 3.14 定义PI 为3.14
    #ifndef __XX_H__ 如果没有则定义__XX_H__    两侧各有两个下划线
    #endif    与#ifndef,#if配对
自己写的头文件用""引用,自带的用<>引用

=================================================

LCD1602调试工具

LCD_Init();                初始化
LCD_ShowChar(1,1,'A');            显示一个字符
LCD_ShowString(1,3,"Hello");        显示字符串
LCD_ShowNum(1,9,123,3);            显示十进制数字
LCD_ShowSignedNum(1,13,-66,2);        显示有符号十进制数字
LCD_ShowHexNum(2,1,0xA8,2);        显示十六进制数字
LCD_ShowBinNum(2,4,0xAA,8);        显示二进制数字

先导入头文件和函数文件
头文件是声明各种函数,函数文件集成了上述函数的实现方法
在主函数中,先运行初始化函数

=================================================

矩阵键盘

八个P1引脚控分别控制四行和四列每行列个四个按键的一个引脚,共计16个按键

用LCD1602来调试矩阵键盘,显示输出
创建用来控制矩阵键盘的函数文件MatrixKey.c文件
在头文件head.h中添加MatrixKey.c的声明

创建能返回按键编号的函数KeyNumber()
    先令全部引脚高电平,依次令每个列引脚低电平,判断行引脚是否接地来测试出哪个案件被按下

注释中的@brief是简介 @param 是对参数的解释
    @brief之类的解释一般放在函数上方

=================================================

矩阵键盘密码锁

利用将整个保存密码的变量乘10再加上最新的输入的数,来完整显示密码
利用变量count限制输入,只能输入4个数,放置顶掉最开始输入的数
S11和S12为确认和取消键,与正确密码比较,对 显示OK 错 显示 ERROR 长度不足用空格“ ”补足

=================================================

定时器

三个定时器 Timer T0,T1,T2  T0,T1兼容传统单片机
    T0 T1四种工作模式
        模式0:13位定时器,计数器
        模式1:16位定时器,计数器
        模式2:8位自动重装模式
        模式3:两个8位计数器

TL0 TH0 TimerLow TimerHigh 各8Bits 存储0~65535
    TF0 TimerFlag 标志位

外部引脚提供脉冲时,单片机的定时器就是计数器

C/T=1: Count 计数器 高电平
C/T=0: Timer 定时器 低电平

定时器相关寄存器
    寄存器是一段特殊的RAM存储器
        寄存器可以存储和读取数据
        寄存器连接导线,控制着电路的连接方式
    
    TCON:定时器/计数器控制寄存器    TimerControl    可位寻址:能对每一位单独赋值0/1,即头文件有对其每位单独定义变量
        定时器/计数器T0,T1的控制寄存器
            bit    B7    B6    B5    B4    B3    B2    B1    B0
            name    TF1    TR1    TF0    TR0    IE1    IT1    IE0    IT0
        
            TF:TimerFlag    TR:TimerReady    IE:InterruptEnable
            数字为1的管理定时器1,0的管理定时器0
        TR0:定时器T0的运行控制位,TR0 = 1时,T0开始计数,=0禁止计数
        TF0:T0溢出中断标志,T0计数出现溢出时,硬件令TF0 = 1,然后向CPU请求中断
    
    TMOD:定时器/计数器工作模式
        位        符号    功能
        TMOD.3        GATE    TMOD.3控制定时器0,置1时只用在INT0脚位高及TR0控制位置1时才可打开定时器/计数器0
                        GATE输出非门,GATE与INT0或门输出,然后与TR0与门输出
                        GATE=0非门输出1,则或门输出为1,TR0=1时,与门输出1,TR0=0时,与门输出0
                        此时外部引脚INT0不起影响

                        GATE=1非门输出0,或门输出受外部引脚INT0控制,此时想打开T0需要TR0与INT0同时=1

                        GATE=0时,TR0单独控制T0开启关闭
                        GATE=1时,TR0与外部引脚INT0共同控制T0开启关闭
        TMOD.2        C/T    控制定时器0的功能模式,定时器或计数器,清零为定时器,置1为计数器
        TMOD.1/TMOD.0    M1 M0    定时器/计数器0
                0  0    13位定时器/计数器
                0  1    16位定时器/计数器
                1  0    8位自动重装载定时器
                1  1    定时器0作为双8位定时器/计数器 TL0作为8位定时器/计数器 TH0作为8位定时器,由定时器1控制为控制

=================================================

中断

使CPU对外界紧急事件有实时处理能力
    处理完后,再回到原来被中断的地方,继续原来的工作
请求CPU终端的请求叫做中断源
多个中断请求存在,优先级被最高的中断请求最先执行

中断嵌套
    CPU处理中断时,发生另一个更高优先级中断时,能暂停当前中断服务时,就去更高优先级的中断
中断源:外部0,外部1,外部2,外部3,定时器0,定时器1,定时2,串口    共8个
中断优先级:4个

中断寄存器
    符号    描述
    IE    Interrupt Enable
    IP    Interrupt Priority Low
    IPH    Interrupt Priority High

    IE 中断允许寄存器
        EA:Enable All
            总中断允许控制位,EA=1,CPU开放中断,=0,屏蔽所有中断申请
        ET0:Enable Timer0
            T0的溢出中断允许位,=1,允许T0中断;=0禁止
    IP 中断优先级控制寄存器低    (可位寻址)
        PT0H(Priority Timer0 High),PT0(Priority Timer0 Low):T0中断优先级控制位
        PT0H    PT0    状态
        0    0    优先级0,最低优先级
        0    1    优先级1,较低优先级
        1    0    优先级2,较高优先级
        1    1    优先级3,最高优先级

=================================================

按键控制流水灯模式

构建函数Timer0Init()控制定时器T0
    配置T0功能和模式TCON和TMOD
        TMOD &= 0xF0;
    配置T0请求时间TL0和TH0
        让T0每隔1ms发出一次中断请求,因为TL0和TH0储存范围是0~65535,它转换的16位数的高八位和低八位分别存在TH0和TL0中,所以设置TL0和TH0的数值,转换为10进制就是计数器计数的初始值,然后与655345做差,并依据晶振频率就可以实现晶振频率的差值倍的时间间隔发出中断请求
        假设计时器每隔1us+1,则初始值设为64535可让T0每隔1ms产生一次中断请求
        单片机晶振11.0592MHz,利用STC-ISP计算得出TL0和TH0的数值,定时器时钟选择12T

        产生中断后,TL0和TH0都会清零,需要在合适的位置重新赋值,比如在中断函数内
    配置中断请求允许ET0和EA
    配置T0中断请求优先级PT0
    
    函数 void Timer0_Routine() interrupt 1
        Timer0_Routine()是中断产生后要执行的函数的函数名,可自定义
        interrupt 1是C51预先定好的中断编号,对应的是Timer0

    在函数内设置静态变量T0Count来保留此变量,并实现不会被其他函数引用和不会被函数重复执行而被重新定义

    添加头文件INTRINS.h,提供了_cror_循环右移,和_crol_循环左移

    循环左移举例:
        a = 0x01;
        a = _crol_(a,1);    //a = 0000 0001 左移一位 ==> a = 0000 0010, a = 0x02

=================================================

定时器时钟

利用不断发生中断,产生1s的间隔,每过一秒,变量+1,同时清零,利用LCD显示变量,达到时钟的作用

=================================================

串口通信

STC-ISP自带串口助手,选择的串口要与下载程序文件的串口号保持一致

51单片机自带UART(Universal Asynchronous Receiver Transmitter 通用异步收发器)

DB9接口的引脚定义,蓝色梯形接口,下底5个针口,上底4个
    流控 设备A对设备2数据流速度控制

简单双向串口通信有两根通信线 发送端TXD(Transmit Exchange Data) 接收端RXD(Recive Exchange Data)
    在两个设备间交叉连接(A设备 的TXD连接 B设备 的RXD)
数据单向传输 只需要一根通信线
电平标准不一致,需要电平转换芯片
    电平标准是数据1和数据0的表达方式
        TTL电平(Transistor Transistor Logic 晶体管-晶体管逻辑)
            +5V表示1,0V表示0
        RS232电平
            -3~-15V表示1,+3~+15V表示0
        RS485电平
            两线压差+2~+6V表示1,-2~-6V表示0
            差分信号    传输线A对传输线B的电平

名称        引脚定义            通信方式        特点
UART        TXD RXD            全双工 异步    点对点通信
I^2C        SCL SDA            半双工 同步    可挂载多个设备
SPI        SCLK MOSI MISO CS    全双工 同步    可挂载多个设备
1-Wire(单总线)    DQ            半双工 异步    可挂载多个设备
CAN(CAN总线)                        稳定性好
USB                            广泛

全双工:    通信双方可以在同一时刻互相传输数据
半双工:    通信双方可以互相传输数据,但必须分时复用一根数据线
单工:    通信只能由一方发送到另一方,不能反向传输(遥控器)

异步:    通信双发各自约定通信速率
同步:    通信双方靠一根时钟线来约定通信速率

总线:    连接各个设备的数据传输线路

STC89C52有1个UART,四种工作模式:
    模式0:同步移位寄存器
    模式1:8位UART,波特率可变(常用)
    模式2:9位UART,波特率固定
    模式3:9位UART,波特率可变

波特率:    串口通信的速率

奇校验:    数据        校验
    0000 0011    1
    则回传数据应该是保证整个数据链(数据+校验)1的个数位奇数
    但回传数据若是 0000 0101 1 无法检验成功
偶校验:    与奇校验同理,保证1的个数为偶数

SBUF:    串口数据缓存寄存器,物理上是两个独立的寄存器,但占用相同的地址。
    写操作时,写入的是发送寄存器,读操作时,读出的是接受寄存器

串行口相关寄存器
    符号    描述            地址    复位值
    SCON    Serial Control        98H    0000 0000B
    SBUF    Serial Buffer        99H    xxxx xxxxB
    PCON    Power Control        87H    00x1 0000B
    IE    Interrupt Enable    A8H    0x00 0000B
    IPH    中断优先级寄存器高    B7H    xx00 0000B
    IP    中断优先级寄存器低    B8H    xx00 0000B

SCON:串行控制寄存器(可位寻址)
    SFR name    bit    B7    B6    B5    B4    B3    B2    B1    B0
    SCON        name    SM0/FE    SM1    SM2    REN    TB8    RB8    TI    RI

    SM0/FE:FE(frame error,帧错误)当PCON寄存器中的SMOD0/PCON.6位为1时(PCON寄存器bit6位为SMOD0),该位用于帧错误检测。
            当检测到一个无效停止位时,通过UART接收器设置该位。它必须由软件清零。
        当PCON寄存器中的SMOD0/PCON.6位为0时,该位和SM1一起指定串行通信的工作方式。
            SM0    SM1    工作方式    功能说明                波特率
            0    0    方式0    同步以为串行方式:移位寄存器    SYSclk/12
            0    1    方式1    8位UART,波特率可变        
            1    0    方式2    9位UART
            1    1    方式3    9位UART,波特率可变
        SM2:允许方式2或方式3多机通信的控制位
        REN:允许/禁止串行接受控制位.为1允许串行接收,可启动串行接收器RxD.为0,禁止接收
        TB8:方式2,3中,为要发送的第9位数据
        RB8:方式2,3中,为接收到的第9位数据
        TI:串行口1发送中断标志.方式0中,每当发送完8位数据,由内部硬件自动置1.方式1,2,3中,发送停止位开始时置1.必须用软件置0
        RI:接收中断请求标志位.方式0中,串行接收到第8位结束时由内部硬件自动置位RI = 1,向主机请求中断,响应中断后必须用软件复位,即RI = 0.

PCON:电源控制寄存器    不可位寻址
    SFRname    Address    bit    B7    B6    B5    B4    B3    B2    B1    B0
    PCON    87H    name    SMOD    SMOD0        POF    GF1    GF0    PD    IDL

    SMOD:波特率选择位.用软件置位SMOD = 1,则使串行通信方式1,2,3波特率加倍.SMOD = 0,各工作方式波特率加倍.复位时SMOD = 0.
    SMOD0:帧错误检测有效控制位.SMOD0 = 1,SCON寄存器中的SMO0/FE位用于FE(帧错误检测)功能;SMOD0 = 0,SCON寄存器中的SM0/FE位用于SMO0功能,和SM1一起指定串行口的工作方式.复位时SMOD0 = 0.

=================================================

串口向电脑发送数据

配置串口通信函数
    SCON = 0x40; 0100 0000    设置方式1
        SM0 = 0,SM1 = 1(B7 B6为0,1),让SCON工作方式为1,8位UART,波特率可变
        SM2 = 0,REN = 1,TB8 = 0,RB8 = 0,TI = 0,RI = 0
    TMOD &= 0x0F    与运算 0000 1111 高四位清零,低四位不变
    TMOD |= 0x20    或运算 0010 0000 设置定时器工作模式为8位自动重装载定时器
    TL1 = 0xFA
    TH1 = 0xFA    1111 0100 1111 0100 设置定时器1初值
    ET1 = 0    禁止定时器中断,属于中断允许寄存器IE的B3
        TR1 = 1    定时器1开始计时,属于定时器/计数器中断控制寄存器的B6
    STC-ISP中设置串口波特率计算器,系统频率位晶振频率11.0592,波特率位4800(不懂)
        UART位串口1,UART数据位为8位数据,波特率发生器为8位自动重载,定时器时钟位12T
        选择波特率倍速
        生成代码    
    8位自动重装载定时器,高八位存放初值,低八位计数,每次计数完成后自动重装AR会将值赋给计数器CNT
    波特率计算    生成代码中波特率的设定初值为FA,对应十进制为250,计数上限为256,即每6次产生一次溢出
            溢出频率为1/6us(微秒)=0.16667MHz,波特率不加倍,总体除以32=0.00520833MHz=5208.33Hz,接近波特率4800
            手册中提供的方式1波特率公式 [(2^SMOD)/32]*定时器1的溢出率,SMOD=1,波特率加倍

配置串口通信发送字节函数
    SBUF = Byte    将无符号字符类型变量Byte写入SBUF寄存器中

=================================================

电脑通过串口控制LED

打开REN
    SCON = 0x50;    0101 0000 设置方式1,打开REN,允许串行接收
打开中断    EA=1 打开总中断 ES=1 打开串行口1中断
创建UART中断函数    中断号为4
在STC-ISP的串口助手中,发送缓冲区的数据是写入SBUF寄存器中
利用RI来判断是否是接收产生的中断(发送与接收占用同一个中断通道),并在接收后执行命令

STC-ISP的串口助手文本模式发送的两个十六进制数会按照ASCII码转换,HEX模式则发送实际数据

=================================================

LED点阵屏

    该模块,P0口为负极控制列,74HC595为正极控制行
    运行时,用P0口低电平选中列,用74HC595的控制行,点亮LED灯

74HC595串转并模块
    输出引脚QA~QH8个,QH'用来多片级联
    OE(字母上加横线表示低电平有效,下降沿有效)    输出使能    Output Enable,接低电平允许输出
    RCLK Register Clock
    SRCLR(低电平有效)    串行清零    Serial Register Clear 
    SRCLK    串行时钟    Serial Clock 
    SER    串行数据    Serial Data Input

    SERCLK每有一个上升沿,便让SER数据移位一次,当移位8次后,RCLK有上升沿就将SER的数据从8个输出引脚输出
        例子    1.SER写入1,时钟上升沿,SER移位一次,SERCLK清零
            2.SER清零(等于写入0),时钟上升沿,SER移位,SERCLK清零
            3.如此反复,写入8个数据
            4.RCLK高电平,SER数据全部通过QA~QH输出

重新定义RCLK为P3的第五位    sbit RCK = P3^5;    改变RCLK的变量名为RCK规避重定义,P3^5为P3口的第六个引脚
    同理创建变量SRCLK和SER

创建函数74HC595_WriteByte,控制写入数据
    程序开始时,重置RCLK和SRCLK
    Byte&0x80(1000 0000),取出Byte最高位,若是1,则为1,若是0,则为0
    结果给SER,SER只能保存1位数据,遵循规则非0即1来保存
    利用循环每次移位i个,第一次移位0个,第二次移位1个
    当取出8位数后,RCLK置1,传送8个数据,然后复位

创建函数MatrixLED,控制LED点阵屏

每次完成一次显示后,应该清零

用#define 定义MATRIX_LED_PORT代替P0变量

=================================================

LED点阵屏显示动画

利用for循环,循环改变当前的列显示的数据,将要显示的卷轴动画纵向分割,每一列单独取数据
显示的数据用数组保存,并用偏移量调整,偏移量不断增加

偏移量调整为数组-8个(32),LED点阵屏8x8横向滚动显示,数组长度为40,偏移量从0开始,到32时,已偏移33次,此时第1列显示第33个值,第8显示第40个值
    大于32时,重置偏移量,否则因为数组溢出而显示乱码

=================================================

DS1302实时时钟

RTC 实时时钟 Real Time Clock
因为开发板VCC1没有接备用电池,所以不可掉电继续运行

引脚名    作用
VCC2    主电源
VCC1    备用电池
GND    电源接地
X1,X2    32.768KHz晶振
CE    芯片使能Chip Enable,复位引脚,读写时要置高电平,低电平复位
IO    数据输入/输出
SCLK    串行时钟

WP 写保护 Write Protect    写入无效,可以读

命令字 8位
    最高位7    固定为1
    6位     逻辑1操作RAM,逻辑0操作时钟CK
    5~1位    地址
    0位    读写,逻辑1读,逻辑0写

时序图
    单字节读写中,CE始终高电平,完成前后低电平
    SCLK提供固定时序,在上升沿时,I/O口数据写入
        时钟下降沿,DS1302将数据输出
        既读写一次后要置高再置低(默认情况下开始运行函数时已经置低)
        根据供电有最小最大时间间隔,80C51的供电规格可以不添加延迟
    单字节写
        1.CE置1,高电平
        2.命令字最低位,即R/W置为写入数据
        3.时钟上升沿,R/W写入,时钟复位
        4.写入A0,时钟高电平,复位,写入A1,时钟高电平,复位,直到写入命令字最高位
        5.写入实际数据,D0~D7,每次写入一个数据,都进行一次时钟电平操作

寄存器
    命令字不占用地址,一个地址8个字节根据地址不同保存的数据意义和范围也不同
    在写函数和读函数中,对应的控制字节8个位写入后,后八个位就是寄存器中的数据

BCD码
    Binary Coded Decimal,用4位二进制数表示1位十进制数
    BCD码 -> 十进制    DEC = BCD / 16 * 10 + BCD % 16
    十进制 -> BCD码    BCD = DEC / 10 * 16 + DEC % 10
    两种计算方式只可以转换两位的BCD码    

=================================================

DS1302时钟

创建DS1302的模块文件和头文件

在单字节写函数中
    先将CE置1,使能芯片
    一个时序中,先读取低位,让命令字 与 0x01 想与,读取出低位
        每一位都相同步骤,利用for循环与位左移实现
    再按相同方式写入数据
    最后复位CE
在单字节读函数中
    每一次上升沿写入命令字,每一次下降沿读取数据字节,同时,一次上升和下降会让数据为进一步
    类似单字节写入函数,使能CE和写入控制位字节
    但因为在时序图中,写完命令字最后一位后的一次脉冲中,上升沿写入,下降沿就开始读取过程,两个操作在一个脉冲中实现
        调整SCLK的高低电平顺序,让每次循环结束时是高电平,可是现在最后一次循环结束时,SCLK的电平为高电平
        同时不会对命令字写入有影响
    给下降沿,对应时序图中结束后一个脉冲之中同时又上升沿和下降沿的下降沿
    给上升沿,准备在之后的下降沿中读取字节
    用还在IO变量内保存的命令字最后一位是不是1来决定是否运行if函数,同时单字节读的命令字最后一位默认是1
        只有在当前位,既第i位是1时会执行将当前位写为1的命令
        可以实现用这种方式将8个数据字节复制到读函数内的保存数据的变量内,既我定义的dsReadData内
        dsReadData本身就是八个0    0000 0000,而外部传入的数据除了0就是1总共八个,只需要将dsReadData对应位是1的改为1就可以
    将IO口置0
    最后传出数据

测试写入秒寄存器
    用写入函数写入秒寄存器,参考手册中寄存器地址定义,秒寄存器写入的地址是80,既0x80,第二位是数据为,可以暂时随便赋值
    关闭写保护,写入保护可以在不被关闭状态下禁止外部写入,对应的地址是8E
    用变量保存读函数的返回值,并用LCD显示,放在死循环内,DS1302自带寄存器可以实现精确的秒计时
    在用LCD显示时,ShowNum是十进制,而DS1302默认是BCD码,需要转换为十进制
    在第二次测试时,在读函数中,提前为dsReadData变量赋0可以让函数输出格式变为十进制,原因不明

之后按照相同方式读取分钟,读地址是83h

创建数组,保存时间信息

用预定义,保存全部时间格式(时分秒等)的写的地址
因为地址全是偶数位,则在读函数中,command和0x01想与
让命令字最低位改为1,可实现对应时间格式的模式为读

创建函数设置时间和读取时间
    设置时间
        反复调用写入函数,将寄存器中对应的每个时间格式(年月日等)分别设置
    读取时间
        同上,反复调用读取函数

=================================================

DS1302可调时钟

显示主菜单函数,运行后显示主菜单标题和功能显示,显示提示切换功能的按键和箭头
    在默认情况下和按下矩阵键盘的s1时,现实的功能时TIME,意思时查看时间
        TIME时功能组第一个,向左会到功能组最后一个,向右依次是年月日时分秒
    S1是回到初始状态,在时间页面,其他功能和调整时间页面都会回到TIME选项上
    S2是向左移动,S3是向右移动,S5和S6是确认和返回

已实现对年份的切换,在年份功能修改后,查看时间会显示修改的时间,同时再次返回可以看到上次修改的时间,双向同步
其他的日期都一样,看情况做不做

=================================================

  • 8
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值