yuyy1989 发表于 2023-5-23 08:52:07

本帖最后由 yuyy1989 于 2023-5-23 11:28 编辑

第23集,看门狗
系统复位,复位的主要作用是把单片机内部的特殊功能寄存器置于初始状态,使单片机硬件、软件从一个确定的、唯一的起点开始工作。
复位方式包括

看门狗,看门狗是一个计数器,它的基本功能是在软件问题和程序跑偏后重启系统。看门狗正常工作时会自动计数,程序进程会定时将其归零。如果系统在某个地方卡住了或者跑了,定时器就会溢出,是系统强制复位。
软件的可靠性一直是一个关键问题。任何使用软件的人都可能遇到电脑死机或程序失控的问题,这种问题在嵌入式系统中也存在。由于单片机抗干扰能力有限,在工业现场仪器仪表中,经常因电压不稳和电弧干扰而死机。在水表、电表无人值守的情况下,系统因干扰无法重启。为了保证系统在受到干扰后能自动恢复正常,看门狗定时器的使用是非常有价值的。
看门狗实现原理,在系统运行以后也就启动了看门狗的计数器,看门狗就开始自动计数,如果到了一定的时间还不去清理看门狗(也叫喂狗),那么看门狗计数器就会溢出从而引起看门狗中断,造成系统复位。所以,在使用有看门狗的芯片时要注意清理看门狗。
看门狗实验,初始状态P2上的LED全亮,按下P34后开启看门狗,P2上的LED流水灯,按住P35按键1秒后看门狗复位P2上的LED全亮
attach://10611.mp4

代码实现

#define MAIN_Fosc       24000000L   //定义主时钟
void delay_ms(uint16_t ms)
{
    uint16_t i;
    do{
      i = MAIN_Fosc / 6000;
      while(--i);   //6T per loop
    }while(--ms);
}
/******************** 主函数 **************************/
void main(void)
{
    uint8_t ledindex = 0;
    WTST = 0;//设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
    EAXFR = 1; //扩展寄存器(XFR)访问使能
    CKCON = 0; //提高访问XRAM速度

    RSTFLAG |= 0x04;   //设置硬件复位后需要检测P3.2的状态选择运行区域,否则硬件复位后进入USB下载模式

    P0M1 = 0x00;   P0M0 = 0x00;   //设置为准双向口
    P1M1 = 0x00;   P1M0 = 0x00;   //设置为准双向口
    P2M1 = 0x00;   P2M0 = 0x00;   //设置为准双向口
    P3M1 = 0x00;   P3M0 = 0x00;   //设置为准双向口
    P4M1 = 0x00;   P4M0 = 0x00;   //设置为准双向口
    P5M1 = 0x00;   P5M0 = 0x00;   //设置为准双向口
    P6M1 = 0x00;   P6M0 = 0x00;   //设置为准双向口
    P7M1 = 0x00;   P7M0 = 0x00;   //设置为准双向口

    //USB调试及复位所需代码-----
    P3M0 &= ~0x03;
    P3M1 |= 0x03;
    IRC48MCR = 0x80;
    while (!(IRC48MCR & 0x01));
    //如果使用USB-CDC需要下面的两行代码
    // USBCLK = 0x00;
    // USBCON = 0x90;
    //如果使用USB-HID注释掉上面两行代码
    usb_init();
    //-------------------------
   
    EUSB = 1;   //IE2相关的中断位操作使能后,需要重新设置EUSB
    EA = 1;   //打开总中断
    P2 = 0x00; //复位后P2上的LED全部亮起
    while (P34 != 0);
    WDT_CONTR = 0x25; //24M主频下约1.05秒
    while(1)
    {
      if(P35 != 0) //如果P35按键没有按下
      {
            CLR_WDT = 1; //清零看门狗
      }
      delay_ms(100);
      P2 = ~(1<<ledindex);
      ledindex++;
      if(ledindex > 7)
            ledindex = 0;
    }
}


yuyy1989 发表于 2023-5-23 16:07:15

第24集,比较器


核心作用就是通过比较两个电压的大小,来及时的响应某些动作



手册里例程的上升沿下降沿的注释标反了


上升沿时0变1,触发中断后CMPRES为1,下降沿是1变0,触发中断后CMPRES为0

代码示例

#include "stc32g.h"
#include "intrins.h"
void main(void)
{
    WTST = 0;//设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
    EAXFR = 1; //扩展寄存器(XFR)访问使能
    CKCON = 0; //提高访问XRAM速度

    RSTFLAG |= 0x04;   //设置硬件复位后需要检测P3.2的状态选择运行区域,否则硬件复位后进入USB下载模式

    P0M1 = 0x00;   P0M0 = 0x00;   //设置为准双向口
    P1M1 = 0x00;   P1M0 = 0x00;   //设置为准双向口
    P2M1 = 0x00;   P2M0 = 0x00;   //设置为准双向口
    P3M1 = 0x00;   P3M0 = 0x00;   //设置为准双向口
    P4M1 = 0x00;   P4M0 = 0x00;   //设置为准双向口
    P5M1 = 0x00;   P5M0 = 0x00;   //设置为准双向口
    P6M1 = 0x00;   P6M0 = 0x00;   //设置为准双向口
    P7M1 = 0x00;   P7M0 = 0x00;   //设置为准双向口

    //USB调试及复位所需代码-----
    P3M0 &= ~0x03;
    P3M1 |= 0x03;
    IRC48MCR = 0x80;
    while (!(IRC48MCR & 0x01));
    //如果使用USB-CDC需要下面的两行代码
    // USBCLK = 0x00;
    // USBCON = 0x90;
    //如果使用USB-HID注释掉上面两行代码
    usb_init();
    //-------------------------
    CMPEXCFG |= 0x40; //比较器 DC 迟滞10mv P3.6负极 P3.7正极
    CMPCR1 = 0xB0; //开启比较功能,使能上升沿和下降沿中断
    CMPCR2= 0x00; //使能0.1us模拟滤波
   
    EUSB = 1;   //IE2相关的中断位操作使能后,需要重新设置EUSB
    EA = 1;   //打开总中断
    while(1)
    {
    }
}

void CMP_Isr() interrupt 21
{
    CMPIF = 0; //清中断标志
    if (CMPRES)
    {
      P20 = !P20; //上升沿(0变1)中断测试端口
    }
    else
    {
      P21 = !P21; //下降沿(1变0)中断测试端口
    }
}


单片机学徒 发表于 2023-5-24 10:37:12

{:4_200:}

清风予我 发表于 2023-5-24 11:50:18

【免费+包邮】 送/申样热线:0513-55012928、0513-55012929、0513-55012966
工作时间:8:30-12:0013:00-17:30(周一 到 周五, 法定节假日除外),也可加如下 QQ 或 微信 申请
加STC华南区客服刘经理QQ: 3398500488 ;微信:18106296592要求 【免费+包邮】 送, 还免费教你仿真
加STC华南区客服曹经理QQ:1933892258 ;微信:18106296595 要求 【免费+包邮】 送, 还免费教你仿真
加STC华东区客服聂经理QQ:2593903262;微信:18106296598要求 【免费+包邮】 送, 还免费教你仿真
加STC西北区客服孙经理QQ: 1347154513 ;微信:18106296593要求 【免费+包邮】 送, 还免费教你仿真
加STC华北区客服石经理QQ: 1638975601 ;微信:19952583876要求 【免费+包邮】 送, 还免费教你仿真
加STC华中区客服唐经理QQ:2571301708 ;微信:18106296589 要求 【免费+包邮】 送, 还免费教你仿真
加STC东北区客服张经理QQ:3141888640 ;微信:19952583265   要求 【免费+包邮】 送, 还免费教你仿真
加STC西南区客服张经理QQ:3141888640 ;微信:19952583265   要求 【免费+包邮】 送, 还免费教你仿真

或者加我QQ:2269694595,我帮您联系对应业务员

yuyy1989 发表于 2023-5-26 15:12:07

第25集,FLASH模拟EEPROM

实验箱还没到,先继续看

FLASH和EEPROM是什么
EEPROM的全称是“电可擦除可编程只读存储器” ,即 Electrically Erasable Programmable Read-Only Memory:是相对于紫外擦除的rom来讲的。但是今天已经存在多种 EEPROM 的变种,变成了一类存储器的统称。
狭义的EEPROM:
这种rom的特点是可以随机访问和修改任何一个字节。这是最传统的一种EEPROM,掉电后数据不丢失,可以保存 100年,可以擦写100w次。具有较高的可靠性,但是电路复杂/成本也高。因此目前的 EEPROM 都是几十千字节到几百千字节的,绝少有超过 512K 的。
Flash:
Flash属于广义的EEPROM,因为它也是电擦除的ROM。但是为了区别于一般的按字节为单位的擦写的EEPROM,我们都叫它Flash。FLASH如果数据不为OXFF,需要擦除之后才能写入

实验:点击P32切换LED亮起,点击P35保存LED状态,重新通电恢复保存的LED状态

运行效果
attach://10912.mp4

代码实现
#include "stc32g.h"
#include "intrins.h"
#define MAIN_Fosc       24000000L   //定义主时钟
void delay_ms(uint16_t ms)
{
    uint16_t i;
    do{
      i = MAIN_Fosc / 6000;
      while(--i);   //6T per loop
    }while(--ms);
}

void IapIdle(void)
{
    IAP_CONTR = 0; //关闭 IAP 功能
    IAP_CMD = 0; //清除命令寄存器
    IAP_TRIG = 0; //清除触发寄存器
    IAP_ADDRE = 0x00;
    IAP_ADDRH = 0x00;
    IAP_ADDRL = 0x00;
}

uint8_t IapRead(uint32_t addr)
{
    char dat;
    IAP_CONTR = 0x80; //使能 IAP
    IAP_TPS = 12; //设置等待参数 12MHz
    IAP_CMD = 1; //设置 IAP 读命令
    IAP_ADDRL = addr; //设置 IAP 低地址
    IAP_ADDRH = addr >> 8; //设置 IAP 高地址
    IAP_ADDRE = addr >> 16; //设置 IAP 最高地址
    IAP_TRIG = 0x5a; //写触发命令(0x5a)
    IAP_TRIG = 0xa5; //写触发命令(0xa5)
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    dat = IAP_DATA; //读 IAP 数据
    IapIdle(); //关闭 IAP 功能
    return dat;
}

void IapProgram(uint32_t addr, uint8_t dat)
{
    IAP_CONTR = 0x80; //使能 IAP
    IAP_TPS = 12; //设置等待参数 12MHz
    IAP_CMD = 2; //设置 IAP 写命令
    IAP_ADDRL = addr; //设置 IAP 低地址
    IAP_ADDRH = addr >> 8; //设置 IAP 高地址
    IAP_ADDRE = addr >> 16; //设置 IAP 最高地址
    IAP_DATA = dat; //写 IAP 数据
    IAP_TRIG = 0x5a; //写触发命令(0x5a)
    IAP_TRIG = 0xa5; //写触发命令(0xa5)
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    IapIdle(); //关闭 IAP 功能
}

void IapErase(uint32_t addr)
{
    IAP_CONTR = 0x80; //使能 IAP
    IAP_TPS = 12; //设置等待参数 12MHz
    IAP_CMD = 3; //设置 IAP 擦除命令
    IAP_ADDRL = addr; //设置 IAP 低地址
    IAP_ADDRH = addr >> 8; //设置 IAP 高地址
    IAP_ADDRE = addr >> 16; //设置 IAP 最高地址
    IAP_TRIG = 0x5a; //写触发命令(0x5a)
    IAP_TRIG = 0xa5; //写触发命令(0xa5)
    _nop_();
    _nop_();
    _nop_();
    _nop_(); //
    IapIdle(); //关闭 IAP 功能
}

void main(void)
{
    uint8_t ledindex = 0;
    WTST = 0;//设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
    EAXFR = 1; //扩展寄存器(XFR)访问使能
    CKCON = 0; //提高访问XRAM速度

    RSTFLAG |= 0x04;   //设置硬件复位后需要检测P3.2的状态选择运行区域,否则硬件复位后进入USB下载模式

    P0M1 = 0x00;   P0M0 = 0x00;   //设置为准双向口
    P1M1 = 0x00;   P1M0 = 0x00;   //设置为准双向口
    P2M1 = 0x00;   P2M0 = 0x00;   //设置为准双向口
    P3M1 = 0x00;   P3M0 = 0x00;   //设置为准双向口
    P4M1 = 0x00;   P4M0 = 0x00;   //设置为准双向口
    P5M1 = 0x00;   P5M0 = 0x00;   //设置为准双向口
    P6M1 = 0x00;   P6M0 = 0x00;   //设置为准双向口
    P7M1 = 0x00;   P7M0 = 0x00;   //设置为准双向口

    //USB调试及复位所需代码-----
    P3M0 &= ~0x03;
    P3M1 |= 0x03;
    IRC48MCR = 0x80;
    while (!(IRC48MCR & 0x01));
    //如果使用USB-CDC需要下面的两行代码
    // USBCLK = 0x00;
    // USBCON = 0x90;
    //如果使用USB-HID注释掉上面两行代码
    usb_init();
    //-------------------------
    ledindex = IapRead(0x0000);
    if(ledindex > 7)
      ledindex = 0;
    P2 = ~(1<<ledindex);
   
    EUSB = 1;   //IE2相关的中断位操作使能后,需要重新设置EUSB
    EA = 1;   //打开总中断
    while(1)
    {
      if(P32 == 0)
      {
            delay_ms(30);
            if(P32 == 0)
            {
                while(P32 == 0);
                  ledindex += 1;
                if(ledindex > 7)
                ledindex = 0;
                P2 = ~(1<<ledindex);
            }
      }
      if(P35 == 0)
      {
            delay_ms(30);
            if(P35 == 0)
            {
                while(P35 == 0);
                IapErase(0x0000);
                IapProgram(0x0000,ledindex);
            }
      }
    }
}

yuyy1989 发表于 2023-5-27 21:54:54

用实验箱验证了一下之前写的数码管驱动程序,看来可以正常运行



attach://11036.mp4

yuyy1989 发表于 2023-5-29 21:04:45

验证了一下之前普通按键、矩阵按键、ADC按键都放到一个文件里的程序,功能正常

数码管第1位数是按键类型0普通按键 1矩阵按键 2ADC按键,第2位是按键编号,第3位是按键动作1按键按下 2松开
attach://11153.mp4

清风予我 发表于 2023-5-30 09:17:25

yuyy1989 发表于 2023-5-29 21:04
验证了一下之前普通按键、矩阵按键、ADC按键都放到一个文件里的程序,功能正常

数码管第1位数是按键类型0 ...

楼主学习精神值得称赞,希望能配合STC32G12K128实验箱9.6版,分享更多学习经验哦{:4_196:}

yuyy1989 发表于 2023-5-30 21:33:42

第26集,DS18B20温度传感器
DS18B20是常用的数字温度传感器,其输出的是数字信号,仅需要一根数据线就能通讯


演示代码
#define DP P33

uint8_t yuyy_ds18b20_reset(void)
{
    uint8_t flag;
    DP = 0;
    yuyy_delay_us(480);
    DP = 1;
    yuyy_delay_us(60);
    flag = DP;
    yuyy_delay_us(420);
    return flag;
}

void yuyy_ds18b20_write0(void)
{
    DP = 0;
    yuyy_delay_us(60);
    DP = 1;
    yuyy_delay_us(2);
}

void yuyy_ds18b20_write1(void)
{
    DP = 0;
    yuyy_delay_us(2);
    DP = 1;
    yuyy_delay_us(60);
}

void yuyy_ds18b20_writebyte(uint8_t dat)
{
    uint8_t i = 0;
    while (i<8)
    {
      if(dat & 0x01)
            yuyy_ds18b20_write1();
      else
            yuyy_ds18b20_write0();
      dat >>= 1;
      i++;
    }
   
}

uint8_t yuyy_ds18b20_readbyte(void)
{
    uint8_t i = 0,dat = 0;
    while (i<8)
    {
      dat >>= 1;
      DP = 0;
      yuyy_delay_us(2);
      DP = 1;
      yuyy_delay_us(2);
      if(DP)
            dat |= 0x80;
      else
            dat &= 0x7F;
      yuyy_delay_us(60);
      i++;
    }
    return dat;
}

float yuyy_ds18b20_readtemp(void)
{
    float temp = -999;
    uint8_t err = 0,th,tl,retry = 0;
    err = yuyy_ds18b20_reset();         //复位
    while (err && retry < 5)
    {
      err = yuyy_ds18b20_reset();
      retry++;
    }
   
    if(err == 0)
    {
      yuyy_ds18b20_writebyte(0xCC);   //跳过ROM指令
      yuyy_ds18b20_writebyte(0x44);   //开始转化
      while (DP == 0);
      yuyy_ds18b20_reset();         //复位
      yuyy_ds18b20_writebyte(0xCC);   //跳过ROM指令
      yuyy_ds18b20_writebyte(0xBE);   //读取
      tl = yuyy_ds18b20_readbyte();
      th = yuyy_ds18b20_readbyte();
      temp = ((int16_t)((th<<8) | tl)) * 0.0625;
    }
    return temp;
}

void test_showsegled(void)
{
    yuyy_segled_show();
}

/******************** 主函数 **************************/
void main(void)
{
    uint16_t num1 = 200;
    float temp = 0;
    WTST = 0;//设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
    EAXFR = 1; //扩展寄存器(XFR)访问使能
    CKCON = 0; //提高访问XRAM速度

    RSTFLAG |= 0x04;   //设置硬件复位后需要检测P3.2的状态选择运行区域,否则硬件复位后进入USB下载模式

    P0M1 = 0x00;   P0M0 = 0x00;   //设置为准双向口
    P1M1 = 0x00;   P1M0 = 0x00;   //设置为准双向口
    P2M1 = 0x00;   P2M0 = 0x00;   //设置为准双向口
    P3M1 = 0x00;   P3M0 = 0x00;   //设置为准双向口
    P4M1 = 0x00;   P4M0 = 0x00;   //设置为准双向口
    P5M1 = 0x00;   P5M0 = 0x00;   //设置为准双向口
    P6M1 = 0x00;   P6M0 = 0x00;   //设置为准双向口
    P7M1 = 0x00;   P7M0 = 0x00;   //设置为准双向口

    //USB调试及复位所需代码-----
    P3M0 &= ~0x03;
    P3M1 |= 0x03;
    IRC48MCR = 0x80;
    while (!(IRC48MCR & 0x01));
    //如果使用USB-CDC需要下面的两行代码
    // USBCLK = 0x00;
    // USBCON = 0x90;
    //如果使用USB-HID注释掉上面两行代码
    usb_init();
    //-------------------------
    yuyy_timer0init(1000,test_showsegled);

    EUSB = 1;   //IE2相关的中断位操作使能后,需要重新设置EUSB
    EA = 1;   //打开总中断
   
    while(1)
    {
      delay_ms(1);
      if(num1 < 200)
      {
            num1++;
      }
      else
      {
            num1 = 0;
            temp = yuyy_ds18b20_readtemp();
            yuyy_segled_shwowfloatnums(temp,0xFF,2,0);
      }
    }
}

yuyy1989 发表于 2023-6-1 21:48:24

第27集,软件模拟SPI
SPI是串行外设接口(Serial Peripheral Interface)的缩写。SPI,是一种高速的,全双工,同步的通信总线。
一般使用4条线:串行时钟线(SCLK)、主机输入/从机输出数据线MISO、主机输出/从机输入数据线MOSI和低电平有效的从机选择线NSS。
模拟SPI读取flash的id
实验箱原理图上标的flash是pm25lv040


但我这个实际上是gd25q40ctig,查看这个flash的spi协议,数据在第一个时钟边沿采样,第二个边沿修改


读取ID的命令,和对应的ID




程序读取结果


代码实现
typedef enum
{
    YUYY_SOFT_SPI_MSB = 0,
    YUYY_SOFT_SPI_LSB
} Yuyy_Soft_Spi_Data_Type;

typedef enum
{
    YUYY_SOFT_SPI_C1S2 = 0, //第一个边沿修改数据,第2个边沿采样
    YUYY_SOFT_SPI_C2S1
} Yuyy_Soft_Spi_Data_Sample_Type;

typedef enum
{
    YUYY_SOFT_SPI_SCK_IDLE_LOW = 0,
    YUYY_SOFT_SPI_SCK_IDLE_HIGH
} Yuyy_Soft_Spi_Sck_Idle_Type;

#define SOFT_SPI_CS P22
#define SOFT_SPI_SCK P25
#define SOFT_SPI_MOSI P23
#define SOFT_SPI_MISO P24

Yuyy_Soft_Spi_Data_Type spi_dt;
Yuyy_Soft_Spi_Data_Sample_Type spi_cpha;
Yuyy_Soft_Spi_Sck_Idle_Type spi_cpol;


void yuyy_soft_spi_delay()
{
    uint8_t i = 3;
    while(i--);
}

void yuyy_soft_spi_init(Yuyy_Soft_Spi_Data_Type dt,Yuyy_Soft_Spi_Data_Sample_Type cpha,Yuyy_Soft_Spi_Sck_Idle_Type cpol)
{
    SOFT_SPI_CS = 1;
    spi_dt = dt;
    spi_cpha = cpha;
    spi_cpol = cpol;
    if(spi_cpol == YUYY_SOFT_SPI_SCK_IDLE_HIGH)
      SOFT_SPI_SCK = 1;
    else
      SOFT_SPI_SCK = 0;
    SOFT_SPI_MISO = 1;
    SOFT_SPI_MOSI = 1;
}

void yuyy_soft_spi_cs(uint8_t lev)
{
    SOFT_SPI_CS = lev;
    yuyy_soft_spi_delay();
}

void yuyy_soft_spi_write_byte(uint8_t dat)
{
    uint8_t i = 0;
    while(i<8)
    {
      if(spi_cpha == YUYY_SOFT_SPI_C1S2)
      {
            SOFT_SPI_SCK = (spi_cpol == YUYY_SOFT_SPI_SCK_IDLE_HIGH ? 0 : 1);
      }
      if(spi_dt == YUYY_SOFT_SPI_MSB)
      {
            if(dat & 0x80)
                SOFT_SPI_MOSI = 1;
            else
                SOFT_SPI_MOSI = 0;
            dat <<= 1;
      }
      else
      {
            if(dat & 0x01)
                SOFT_SPI_MOSI = 1;
            else
                SOFT_SPI_MOSI = 0;
            dat >>= 1;
      }
      if(spi_cpha == YUYY_SOFT_SPI_C2S1)
      {
            SOFT_SPI_SCK = (spi_cpol == YUYY_SOFT_SPI_SCK_IDLE_HIGH ? 0 : 1);
      }
      yuyy_soft_spi_delay();
      SOFT_SPI_SCK = (spi_cpol == YUYY_SOFT_SPI_SCK_IDLE_HIGH ? 1 : 0);
      i++;
    }
}

uint8_t yuyy_soft_spi_read_byte()
{
    uint8_t i = 0,dat = 0;
    while(i<8)
    {
      if(spi_cpha == YUYY_SOFT_SPI_C2S1)
      {
            SOFT_SPI_SCK = (spi_cpol == YUYY_SOFT_SPI_SCK_IDLE_HIGH ? 0 : 1);
      }
      if(spi_dt == YUYY_SOFT_SPI_MSB)
      {
            dat <<= 1;
            if(SOFT_SPI_MISO)
                dat |= 0x01;
            else
                dat &= 0xFE;
      }
      else
      {
            dat >>= 1;
            if(SOFT_SPI_MISO)
                dat |= 0x80;
            else
                dat &= 0x7F;
      }
      if(spi_cpha == YUYY_SOFT_SPI_C1S2)
      {
            SOFT_SPI_SCK = (spi_cpol == YUYY_SOFT_SPI_SCK_IDLE_HIGH ? 0 : 1);
      }
      yuyy_soft_spi_delay();
      SOFT_SPI_SCK = (spi_cpol == YUYY_SOFT_SPI_SCK_IDLE_HIGH ? 1 : 0);
      i++;
    }
    return dat;
}

void main(void)
{
    uint8_t id1,id2,id3;
    WTST = 0;//设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
    EAXFR = 1; //扩展寄存器(XFR)访问使能
    CKCON = 0; //提高访问XRAM速度

    RSTFLAG |= 0x04;   //设置硬件复位后需要检测P3.2的状态选择运行区域,否则硬件复位后进入USB下载模式

    P0M1 = 0x00;   P0M0 = 0x00;   //设置为准双向口
    P1M1 = 0x00;   P1M0 = 0x00;   //设置为准双向口
    P2M1 = 0x00;   P2M0 = 0x00;   //设置为准双向口
    P3M1 = 0x00;   P3M0 = 0x00;   //设置为准双向口
    P4M1 = 0x00;   P4M0 = 0x00;   //设置为准双向口
    P5M1 = 0x00;   P5M0 = 0x00;   //设置为准双向口
    P6M1 = 0x00;   P6M0 = 0x00;   //设置为准双向口
    P7M1 = 0x00;   P7M0 = 0x00;   //设置为准双向口

    //USB调试及复位所需代码-----
    P3M0 &= ~0x03;
    P3M1 |= 0x03;
    IRC48MCR = 0x80;
    while (!(IRC48MCR & 0x01));
    //如果使用USB-CDC需要下面的两行代码
    // USBCLK = 0x00;
    // USBCON = 0x90;
    //如果使用USB-HID注释掉上面两行代码
    usb_init();
    //-------------------------
    yuyy_soft_spi_init(YUYY_SOFT_SPI_MSB,YUYY_SOFT_SPI_C2S1,YUYY_SOFT_SPI_SCK_IDLE_HIGH);
    EUSB = 1;   //IE2相关的中断位操作使能后,需要重新设置EUSB
    EA = 1;   //打开总中断
    while (P32 != 0);
    yuyy_soft_spi_cs(0);
    yuyy_soft_spi_write_byte(0xAB);
    yuyy_soft_spi_write_byte(0x00);
    yuyy_soft_spi_write_byte(0x00);
    yuyy_soft_spi_write_byte(0x00);
    id1 = yuyy_soft_spi_read_byte();
    yuyy_soft_spi_cs(1);
    printf_hid("发送命令0xAB 读取到ID:0x%02X\r\n",id1);
    delay_ms(100);

    yuyy_soft_spi_cs(0);
    yuyy_soft_spi_write_byte(0x90);
    yuyy_soft_spi_write_byte(0x00);
    yuyy_soft_spi_write_byte(0x00);
    yuyy_soft_spi_write_byte(0x00);
    id1 = yuyy_soft_spi_read_byte();
    id2 = yuyy_soft_spi_read_byte();
    yuyy_soft_spi_cs(1);
    printf_hid("发送命令0x90 读取到ID:0x%02X 0x%02X\r\n",id1,id2);
    delay_ms(100);

    yuyy_soft_spi_cs(0);
    yuyy_soft_spi_write_byte(0x9F);
    id1 = yuyy_soft_spi_read_byte();
    id2 = yuyy_soft_spi_read_byte();
    id3 = yuyy_soft_spi_read_byte();
    yuyy_soft_spi_cs(1);
    printf_hid("发送命令0x9F 读取到ID:0x%02X 0x%02X 0x%02X\r\n",id1,id2,id3);
    delay_ms(100);
   
    while(1)
    {
    }
}

页: 1 2 3 [4]
查看完整版本: 冲哥32位8051视频学习日记-已看到27集-实验箱到了