找回密码
 立即注册
查看: 2762|回复: 39

冲哥32位8051视频学习日记-已看到27集-实验箱到了

[复制链接]
  • TA的每日心情
    无聊
    前天 22:23
  • 签到天数: 132 天

    [LV.7]常住居民III

    3

    主题

    65

    回帖

    1157

    积分

    金牌会员

    积分
    1157
    发表于 2023-5-5 11:00:06 | 显示全部楼层 |阅读模式
    本帖最后由 yuyy1989 于 2023-6-1 21:48 编辑

    实验箱到了感谢STC的支持,之后会把没能验证的代码在实验箱上验证一下
    微信图片_20230526183658.jpg


    自学单片机,但从来没有系统的学习过,正好看视频好好了解一下

    实际上手过程中越来越觉得STC-ISP这个工具的强大,不光是一个烧录工具
    冲哥32位8051视频学习日记-1.png

    有这些功能初始化的程序写起来太方便了
    冲哥32位8051视频学习日记-2.png

    即使没有相关设备也能用这里的虚拟设备来调试功能逻辑,只不过没法验证底层驱动逻辑,例如数码管的实现
    回复 送花

    使用道具 举报

  • TA的每日心情
    无聊
    前天 22:23
  • 签到天数: 132 天

    [LV.7]常住居民III

    3

    主题

    65

    回帖

    1157

    积分

    金牌会员

    积分
    1157
     楼主| 发表于 2023-5-5 11:04:54 | 显示全部楼层
    第1集,主要介绍了什么是单片机,单片机的应用场景以及如何入门
    个人觉得用51单片机入门更有助于对单片机原理的理解,有C语言的基础入门应该也会很快
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    无聊
    前天 22:23
  • 签到天数: 132 天

    [LV.7]常住居民III

    3

    主题

    65

    回帖

    1157

    积分

    金牌会员

    积分
    1157
     楼主| 发表于 2023-5-5 11:17:06 | 显示全部楼层
    本帖最后由 yuyy1989 于 2023-5-5 11:18 编辑

    第2集,试验箱介绍,外设的工作原理,有开发经验的可以跳过这集
    课后作业:结合实验箱上的外设做个时钟和温度表还是比较简单的
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    无聊
    前天 22:23
  • 签到天数: 132 天

    [LV.7]常住居民III

    3

    主题

    65

    回帖

    1157

    积分

    金牌会员

    积分
    1157
     楼主| 发表于 2023-5-5 11:27:42 | 显示全部楼层
    第3集,开发环境的搭建和程序烧录,真手把手地教,连怎么打开和查看PDF都教了
    不过WIN10不用特地去下PDF阅读器,EDGE感觉就不错
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    无聊
    前天 22:23
  • 签到天数: 132 天

    [LV.7]常住居民III

    3

    主题

    65

    回帖

    1157

    积分

    金牌会员

    积分
    1157
     楼主| 发表于 2023-5-5 14:06:15 | 显示全部楼层
    第4集,点亮第一颗LED上,介绍了如何控制GPIO来点亮一颗LED,参考数据手册配置寄存器
    这里用到了端口模式配置寄存器PxM0和PxM1,其中x为IO口的端口号,寄存器的bit0-bit7分别对应该端口的0-7号IO口,通过配置对应位为0或1配置IO口的模式
    微信截图_20230505140401.png

    关于视频最后那个问题,从数据手册能看到除P3.0和P3.1外其余所有IO口上电后均为高阻输入状态(电流既不能流入也不能流出),如果注释掉配置IO口模式的代码是不能操作IO口点亮LED的,因此在使用IO口前必须配置IO口模式


    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    无聊
    前天 22:23
  • 签到天数: 132 天

    [LV.7]常住居民III

    3

    主题

    65

    回帖

    1157

    积分

    金牌会员

    积分
    1157
     楼主| 发表于 2023-5-5 15:15:25 | 显示全部楼层
    本帖最后由 yuyy1989 于 2023-5-7 13:11 编辑

    第4集,点亮第一颗LED下,USB-CDC/虚拟串口,不停电下载
    STC的单片机支持USB直接下载而不用额外再用一个烧录器,这就很方便了,实现不停电下载后调试代码更方便了
    isp软件设置,我的版本是6.91N和手册上的界面不大一样
    微信截图_20230505151342.png

    实现方式也很简单,在工程里添加stc_usb_hid_32g.LIB(USB-HID模式)或stc_usb_cdc_32g.LIB(USB-CDC/串口模式),然后添加如下代码

    1. //包含头文件
    2. #include "../comm/usb.h" //USB调试及复位所需头文件
    3. //main函数外的全局变量
    4. //USB调试及复位所需定义
    5. char *USER_DEVICEDESC = NULL;
    6. char *USER_PRODUCTDESC = NULL;
    7. char *USER_STCISPCMD = "@STCISP#";//设置自动复位到ISP区的用户接口命令
    8. //main函数内while(1)前
    9. WTST = 0;  //设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
    10. EAXFR = 1; //扩展寄存器(XFR)访问使能
    11. CKCON = 0; //提高访问XRAM速度
    12. //USB调试及复位所需代码-----
    13. P3M0 &= ~0x03;
    14. P3M1 |= 0x03;
    15. IRC48MCR = 0x80;
    16. while (!(IRC48MCR & 0x01));
    17. //如果使用USB-CDC需要下面的两行代码
    18. USBCLK = 0x00;
    19. USBCON = 0x90;
    20. //如果使用USB-HID注释掉上面两行代码
    21. usb_init();
    22. //-------------------------
    复制代码

    支持USB不停电下载的固件编译好之后需要用传统方式下载一次这个固件,之后就可以不停电下载了


    课后练习:使用端口寄存器可以方便的一次性把该端口下的IO口全部拉高或拉低,例如P2.0-P2.7每个引脚都连接1颗LED,LED共阳极,代码中P2=0x00就可以点亮全部LED,P2=0xF0可以点亮P2.0-P2.3关掉P2.4-P2.7







    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    无聊
    前天 22:23
  • 签到天数: 132 天

    [LV.7]常住居民III

    3

    主题

    65

    回帖

    1157

    积分

    金牌会员

    积分
    1157
     楼主| 发表于 2023-5-5 21:17:55 | 显示全部楼层
    第5集,C语言运算符和进制数入门,介绍了一些C语言的基础知识,有C语言基础的可以跳过这一集
    刚接触单片机需要注意的是sbit P23=P2^3,这里的的^并不是进行异或运算,而是取寄存器的第3位
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    无聊
    前天 22:23
  • 签到天数: 132 天

    [LV.7]常住居民III

    3

    主题

    65

    回帖

    1157

    积分

    金牌会员

    积分
    1157
     楼主| 发表于 2023-5-6 13:19:29 | 显示全部楼层
    本帖最后由 yuyy1989 于 2023-5-7 13:13 编辑

    第6集,LED闪烁和花式点灯,介绍了自适应时钟的Delay函数的实现,while循环的使用,#define的使用,函数的使用
    1. #define MAIN_Fosc       24000000L   //定义主时钟
    2. void delay_ms(uint16_t ms)
    3. {
    4.     uint16_t i;
    5.     do{
    6.         i = MAIN_Fosc / 6000;
    7.         while(--i);   //6T per loop
    8.     }while(--ms);
    9. }
    10. //在main函数的while(1)中添加
    11. P20 = 0;
    12. delay_ms(500);
    13. P20 = 1;
    14. delay_ms(500);
    15. //实现P2.0IO控制的灯500ms亮500ms灭的循环闪烁
    复制代码

    如果只是使用固定时间的延时可以用STC-ISP软件生成延时代码
    微信截图_20230506094109.png

    关于--a和a--:--a会返回减1后的a值,a--会返回减1前的a值,++a和a++同理

    课后练习:
    1. //写一个闪烁的函数
    2. void blinkLed(uint16_t onms,uint16_t offms,uint8_t count)
    3. {
    4.     while(count > 0)
    5.     {
    6.         P20 = 0;
    7.         delay_ms(onms);
    8.         P20 = 1;
    9.         delay_ms(offms);
    10.         count--;
    11.     }
    12. }
    13. //在main函数的while(1)中添加
    14. blinkLed(100,100,2);
    15. blinkLed(100,500,1);
    16. blinkLed(500,500,3);
    17. blinkLed(100,100,3);
    18. delay_ms(2000);
    复制代码



    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    无聊
    前天 22:23
  • 签到天数: 132 天

    [LV.7]常住居民III

    3

    主题

    65

    回帖

    1157

    积分

    金牌会员

    积分
    1157
     楼主| 发表于 2023-5-6 20:23:02 | 显示全部楼层
    本帖最后由 yuyy1989 于 2023-5-7 13:15 编辑

    第7集,按键点灯
    1. //定义按键和LED
    2. #define KEY0 P32
    3. #define KEY1 P33
    4. #define KEY2 P34
    5. #define KEY3 P35
    6. #define LED0 P20
    7. #define LED1 P21
    8. #define LED2 P22
    9. #define LED3 P23
    10. #define LED4 P24
    11. #define LED5 P25
    12. #define LED6 P26
    13. #define LED7 P27
    14. uint8_t keydown = 0x00;//使用bit0-bit3记录key0-key3的状态
    15. uint8_t ledindex = 0;//0-4
    16. uint8_t leddatas[5] = {0xF7,0xEF,0xDF,0xBF,0x7F};
    17. //按下KEY0 LED0亮,松开熄灭
    18. void key0down_led0on()
    19. {
    20.     if(KEY0 == 0)
    21.     {
    22.         delay_ms(10);//去抖
    23.         if(KEY0 == 0)
    24.         {
    25.             LED0 = 0;
    26.         }
    27.     }
    28.     else
    29.     {
    30.         LED0 = 1;
    31.     }
    32. }
    33. //按下KEY1 LED1熄灭,松开点亮
    34. void key1down_led1off()
    35. {
    36.     if(KEY1 == 0)
    37.     {
    38.         delay_ms(10);//去抖
    39.         if(KEY1 == 0)
    40.         {
    41.             LED1 = 1;
    42.         }
    43.     }
    44.     else
    45.     {
    46.         LED1 = 0;
    47.     }
    48. }
    49. //按下一次KEY2,LED2状态改变一次
    50. void key2down_led2onoff()
    51. {
    52.     if(KEY2 == 0)
    53.     {
    54.         delay_ms(10);//去抖
    55.         if(KEY2 == 0)
    56.         {
    57.             if((keydown&0x04) == 0)
    58.             {
    59.                 keydown |= 0x04;
    60.                 LED2 = !LED2;
    61.             }
    62.         }
    63.     }
    64.     else
    65.     {
    66.         keydown &= 0xFB;
    67.     }
    68. }
    69. //按下一次KEY3,LED3-LED7依次亮起一个
    70. void key3down_led37on()
    71. {
    72.     if(KEY3 == 0)
    73.     {
    74.         delay_ms(10);//去抖
    75.         if(KEY3 == 0)
    76.         {
    77.             if((keydown&0x08) == 0)
    78.             {
    79.                 keydown |= 0x08;
    80.                 //if else 判断实现,此方法不要求LED全在同一个端口上
    81.                 /*
    82.                 if(LED3 == 0)
    83.                 {
    84.                     LED3 = 1;
    85.                     LED4 = 0;
    86.                 }
    87.                 else if(LED4 == 0)
    88.                 {
    89.                     LED4 = 1;
    90.                     LED5 = 0;
    91.                 }
    92.                 else if(LED5 == 0)
    93.                 {
    94.                     LED5 = 1;
    95.                     LED6 = 0;
    96.                 }
    97.                 else if(LED6 == 0)
    98.                 {
    99.                     LED6 = 1;
    100.                     LED7 = 0;
    101.                 }
    102.                 else
    103.                 {
    104.                     LED7 = 1;
    105.                     LED3 = 0;
    106.                 }
    107.                 */
    108.                 //移位方法
    109.                 //P2 = (P2 & 0x07)|(~(1<<(ledindex+3)));
    110.                 //数组方法
    111.                 P2 = leddatas[ledindex];
    112.                 ledindex++;
    113.                 if(ledindex>4)
    114.                 {
    115.                     ledindex = 0;
    116.                 }
    117.             }
    118.         }
    119.     }
    120.     else
    121.     {
    122.         keydown &= 0xF7;
    123.     }
    124. }
    125. //在main函数的while(1)循环体前初始化LED状态
    126. P2 = 0xFF;
    127. //在main函数的while(1)循环体中放入
    128. key0down_led0on();
    129. key1down_led1off();
    130. key2down_led2onoff();
    131. key3down_led37on();
    复制代码




    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    无聊
    前天 22:23
  • 签到天数: 132 天

    [LV.7]常住居民III

    3

    主题

    65

    回帖

    1157

    积分

    金牌会员

    积分
    1157
     楼主| 发表于 2023-5-6 22:13:19 | 显示全部楼层
    本帖最后由 yuyy1989 于 2023-5-7 13:16 编辑

    第8集,蜂鸣器的应用
    蜂鸣器分为有源蜂鸣器和无源蜂鸣器2种,有源蜂鸣器内部带有振荡源通电就会响,无源蜂鸣器内部无振荡源直接通直流信号不会响
    1. #define KEY0 P32
    2. #define KEY1 P33
    3. #define KEY2 P34
    4. #define KEY3 P35
    5. #define LEDPORT P2
    6. #define BEEP P54
    7. uint8_t keydown = 0x00;//使用bit0-bit3记录key0-key3的状态
    8. uint8_t funcindex = 0;//0-8功能档位
    9. bit powerup = 0;//开关机状态
    10. bit working = 0;//启动状态
    11. uint8_t workingcount = 0;
    12. //按下一次KEY0,蜂鸣器状态改变一次
    13. void key0down_beeponoff()
    14. {
    15.     if(KEY0 == 0)
    16.     {
    17.         delay_ms(10);//去抖
    18.         if(KEY0 == 0)
    19.         {
    20.             if((keydown&0x01) == 0)
    21.             {
    22.                 keydown |= 0x01;
    23.                 BEEP = !BEEP;
    24.             }
    25.         }
    26.     }
    27.     else
    28.     {
    29.         keydown &= 0xFE;
    30.     }
    31. }
    32. //按键1开关机
    33. void key1_power()
    34. {
    35.     if(KEY1 == 0)
    36.     {
    37.         delay_ms(10);//去抖
    38.         if(KEY1 == 0)
    39.         {
    40.             if((keydown&0x02) == 0)
    41.             {
    42.                 keydown |= 0x02;
    43.                 if(powerup == 0) //当前关机,执行开机动作
    44.                 {
    45.                     BEEP = 0;
    46.                     delay_ms(10);
    47.                     BEEP = 1;
    48.                     LEDPORT = 0x00;
    49.                     delay_ms(200);
    50.                     LEDPORT = 0xFF;
    51.                     powerup = 1;
    52.                     funcindex = 0;
    53.                     working = 0;
    54.                 }
    55.                 else//当前开机,执行关机动作
    56.                 {
    57.                     BEEP = 0;
    58.                     delay_ms(10);
    59.                     BEEP = 1;
    60.                     LEDPORT = 0xFF;
    61.                     powerup = 0;
    62.                 }
    63.             }
    64.         }
    65.     }
    66.     else
    67.     {
    68.         keydown &= 0xFD;
    69.     }
    70. }
    71. //按键2切换功能
    72. void key2_func()
    73. {
    74.     if(powerup == 1 && working == 0)//已经开机且未启动
    75.     {
    76.         if(KEY2 == 0)
    77.         {
    78.             delay_ms(10);//去抖
    79.             if(KEY2 == 0)
    80.             {
    81.                 if((keydown&0x04) == 0)
    82.                 {
    83.                     keydown |= 0x04;
    84.                     funcindex += 1;
    85.                     if(funcindex > 8)
    86.                     {
    87.                         funcindex = 1;
    88.                     }
    89.                     BEEP = 0;
    90.                     delay_ms(10);
    91.                     BEEP = 1;
    92.                     LEDPORT = ~(1<<(funcindex-1));
    93.                 }
    94.             }
    95.         }
    96.         else
    97.         {
    98.             keydown &= 0xFB;
    99.         }
    100.     }
    101. }
    102. //按键3启动或停止
    103. void key3_work()
    104. {
    105.     if(powerup == 1 && funcindex > 0)//检查是否已开机并选择了功能
    106.     {
    107.         if(KEY3 == 0)
    108.         {
    109.             delay_ms(10);//去抖
    110.             if(KEY3 == 0)
    111.             {
    112.                 if((keydown&0x08) == 0)
    113.                 {
    114.                     keydown |= 0x08;
    115.                     BEEP = 0;
    116.                     delay_ms(10);
    117.                     BEEP = 1;
    118.                     working = !working;
    119.                     if(working == 0)
    120.                     {
    121.                         LEDPORT = ~(1<<(funcindex-1));
    122.                     }
    123.                 }
    124.             }
    125.         }
    126.         else
    127.         {
    128.             keydown &= 0xF7;
    129.         }
    130.         if(working == 1)
    131.         {
    132.             delay_ms(10); //延时太长影响按键按下的判断
    133.             workingcount++;
    134.             if(workingcount > 99)
    135.             {
    136.                 workingcount = 0;
    137.             }
    138.             if(workingcount < 50)
    139.             {
    140.                 LEDPORT = 0xFF;
    141.             }
    142.             else
    143.             {
    144.                 LEDPORT = ~(1<<(funcindex-1));
    145.             }
    146.         }
    147.     }
    148. }
    149. //在main函数的while(1)循环体中放入
    150. key0down_beeponoff();
    151. key1_power();
    152. key2_func();
    153. key3_work();
    复制代码
    回复 支持 反对 送花

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

    GMT+8, 2024-5-11 14:36 , Processed in 0.075306 second(s), 67 queries .

    Powered by Discuz! X3.5

    © 2001-2024 Discuz! Team.

    快速回复 返回顶部 返回列表