找回密码
 立即注册
楼主: tyun1990

实验箱已收到!看冲哥《STC32位8051单片机视频教程》学习记录

[复制链接]

2

主题

21

回帖

108

积分

注册会员

积分
108
发表于 2023-10-21 09:38:57 | 显示全部楼层
本帖最后由 tyun1990 于 2023-10-21 13:29 编辑

学习记录(第13课)第一部分
课堂笔记:应用模块化编程,每一个模块对应一个 “.C”  “.H”的文件。
每个函数都要添加函数说明、版本号
截图202310210937367435.jpg
//======================================================
// 函数名称:  
// 函数功能:
// 入口参数:
// 函数返回:
// 当前版本: VER1.0
// 修改日期: 2023 - 1-1
// 当前作者:
// 其他备注:
//======================================================

修饰符extern 用在变量或者函数的声明前,用来说明此变量函数在别处定义的,要在此处引用
例如:Temp.c文件需要应用Temp2.C文件变量int i,就可以在Temp2.H中声明 extern int i,之后才能在Temp.c文件中引用v这个变量


bdata 位寻址变量
a.c                                                           a.h
u8 bdata LED=0x00;              extern u8 bdata LED;  
sbit LED0=LED^0;               extern bitLED0;  
sbit LED1=LED^1;               extern bitLED1;  
以下是.C文件标准模板
截图202310210937582239.jpg
以下是.H标准模板
截图202310210947284604.jpg

按键检测注意点
按键应该10ms(毫秒)检测一次
软件防抖要<30ms       单击按下检测  =30mS,   长按检测3秒开始检测,一直按>3000ms(3   秒)表示在一直按着按键


回复 支持 反对

使用道具 举报 送花

2

主题

21

回帖

108

积分

注册会员

积分
108
发表于 2023-10-21 20:00:37 | 显示全部楼层
学习记录(第13课)第二部分

新学到的知识:按键的用法
以前我们学到的按键用法跟老师的这个区别很大,感谢老师教的新方法。我要消化一下,第13-4的视频要多看一次才能慢慢明白
老师讲的方法是利用宏定义返回状态来读取按键;我们以前学的方法是直接扫描按键值
#include "key.h"
u16 Count[8] = {0,0,0,0,0,0,0,0};

u8  LastState = 0;                        //8位变量         b0=1,代表k0上一次按下过
//========================================================================

// 函数名称: KEY_Deal
// 函数功能: 按键状态读取
// 入口参数: 无
// 函数返回: 无
// 当前版本: VER1.0
// 修改日期: 2023 - 1-1
// 当前作者:
// 其他备注:循环读取八个端口的状态,并将按下的时间赋值给 Count 数组,按下的状态赋值给LastState
//========================================================================
void KEY_Deal(void)                        //检查所有的按键状态 10ms执行一次
{
        u8 i = 0;
        for(i=0;i<8;i++)                //循环8次 i的取值范围是0-7  代表了P30-P37的状态查询
        {
                if( ~KEY & ( 1<<i ) )                        //持续按下,变量+1  
                {
                        if( Count<60000 )
                                Count ++;                //按键按下,这个计数变量+1
                }
                else                                        //按键松开了,变量清0
                {
                        if( Count>0 )                //如果这个变量是按下过的
                        {
                                LastState |= (1<<i);        //这个变量相应的标志位置位
                        }
                        else
                        {
                                LastState &= ~(1<<i);        //这个变量相应的标志位清0
                        }
                        Count = 0;                        //按键按下,这个计数变量清0
                }
        }
}


//========================================================================
// 函数名称: KEY_ReadState
// 函数功能: 读取指定的按钮的状态
// 入口参数: @keynum : 按钮的端口号 例如P32端口,端口号就是2
// 函数返回: 看其他备注
// 当前版本: VER1.0
// 修改日期: 2023 - 1- 1
// 当前作者:
// 其他备注: 函数返回值如下
//        #define        KEY_NOPRESS                0                //按键未按下
//        #define        KEY_FILCKER                1                //消抖
//        #define        KEY_PRESS                2                //单击
//        #define        KEY_PRESSOVER        3                        //单击结束
//        #define        KEY_LONGPRESS        4                        //长按3秒
//        #define        KEY_LONGOVER        5                        //长按结束
//        #define        KEY_RELAX                6                //按键松开
//========================================================================


u8 KEY_ReadState(u8 keynum)        //读取指定的按键的状态 10ms执行一次
{
        if( Count[keynum]>0 )                                //按键是按下的各种状态返回
        {
                if( Count[keynum]<3 )                        //按下<30ms 返回消抖状态
                {
                        return KEY_FILCKER;
                }
                else if( Count[keynum]==3 )                //按下正好30ms 返回单击
                {
                        return KEY_PRESS;
                }
                else if( Count[keynum]<300 )                //按下不到3000ms 返回单击结束
                {
                        return KEY_PRESSOVER;
                }               
                else if( Count[keynum]==300 )                //按下正好3000ms 返回长按状态
                {
                        return KEY_LONGPRESS;
                }
                else                                        //长按结束
                {
                        return KEY_LONGOVER;
                }                       
               
        }
        else                                                //按键已经松开了,返回各种状态
        {
                if( LastState &( 1<<keynum ) )                //按键之前按下过
                {
                        return KEY_RELAX;               
                }
                else                                        //按键之前没有按下
                {
                        return KEY_NOPRESS;
                }
        }
}


#ifndef __KEY_H
#define __KEY_H
#include "COMM/stc.h"                //调用头文件

#include "COMM/usb.h"
//------------------------------引脚定义------------------------------

#define KEY         P3                                //P32-P35
#define KEY1        2                                //按键1

#define KEY2        3                                //按键2
#define KEY3        4                                //按键3
#define KEY4        5                                //按键4
//------------------------------变量声明------------------------------

#define        KEY_NOPRESS                0                //按键未按下
#define        KEY_FILCKER                1                //消抖
#define        KEY_PRESS                2                //单击
#define        KEY_PRESSOVER        3                        //单击结束
#define        KEY_LONGPRESS        4                        //长按3秒
#define        KEY_LONGOVER        5                        //长按结束
#define        KEY_RELAX                6                //按键松开
//------------------------------函数声明------------------------------

void KEY_Deal(void);                        //检查所有的按键状态
u8 KEY_ReadState(u8 keynum);                //读取指定的按键的状态
#endif




回复 支持 反对

使用道具 举报 送花

2

主题

21

回帖

108

积分

注册会员

积分
108
发表于 2023-10-21 20:13:16 | 显示全部楼层
本帖最后由 tyun1990 于 2023-10-21 20:17 编辑

新买的书今天到货了,努力学习中!真羡慕他们大学生,有《STC32位 8051单片机原理与应用》教材 和“配套的实验箱”送呢。而我只能买
截图202310212004514234.jpg 截图202310212013077411.jpg
之前有一个核心板被我干废了,我也是个人才!估计整个论坛只有我会把核心板和OLED屏幕一起干废的了。无奈新买了一块。还有一块是STC8H8K64U核心板
还没来得及焊接排针先拿出来秀一秀
截图202310212007104603.jpg 截图202310212005389363.jpg





回复 支持 反对

使用道具 举报 送花

2

主题

21

回帖

108

积分

注册会员

积分
108
发表于 2023-10-22 10:27:25 | 显示全部楼层
本帖最后由 tyun1990 于 2023-10-22 18:26 编辑

学习记录(第14课)
课堂笔记,矩阵键盘扫描程序
截图202310221026296923.jpg


#define MateixKEY         P1           //定义矩阵按键的引脚

u8 MateixKEY_Read(void)            //矩阵按键读取当前是哪一个按钮按下

{
     static u8 keystate_last;                //表示当前的按钮的上一次的状态值
     u8 keystate;                                       //表示当前的按钮的状态值
     u8 key_val = 0;                                //表示当前按键的键码
     MateixKEY = 0XC0;        //1100 0000
     MateixKEY_delay();
     keystate = (MateixKEY ^ 0XC0);                //0100 0000 ^ 1100 0000 =  1000 0000
        
     MateixKEY = 0X0f;        //0000 1111

     MateixKEY_delay();
     keystate |= (MateixKEY ^ 0X0f);                //0000 1110 ^ 0000 1111 =  0000 0001 | 1000 0000 = 0x81
        
     if( keystate_last != keystate )                //如果说本次获取到的按键状态值和之前的不一样

    {
      keystate_last = keystate;                //把本次的按键状态值写入进去
               
      switch ( keystate )                                //返回对应的键码
      {
            case 0x41:        key_val = 1;break;
            case 0x42:        key_val = 2;break;
            case 0x44:        key_val = 3;break;
            case 0x48:        key_val = 4;break;        
            case 0x81:        key_val = 5;break;
            case 0x82:        key_val = 6;break;
            case 0x84:        key_val = 7;break;
            case 0x88:        key_val = 8;break;                        
            default:        key_val = 0;break;
        }
    }

        
   return key_val;                                                //返回最终的键码,没有按下时返回0               
}


回复 支持 反对

使用道具 举报 送花

2

主题

21

回帖

108

积分

注册会员

积分
108
发表于 2023-10-22 18:25:34 | 显示全部楼层
学习记录(第15课)

课堂笔记
截图202310221821371963.jpg

截图202310221825171444.jpg

要启动外部中断就必须打开IT0=1或者IT1=1,允许外部中断EX0=1、EX1=1,EA总开关打开。为了防止上电误判可以对IE0、IE1清零。


IT0服务子函数

void EX0_isr(void) interrupt 0
{


}


IT1服务子函数

void EX1_isr(void) interrupt 2
{


}       

截图202310221037587650.jpg
截图202310221707004134.jpg
截图202310221707251973.jpg
回复 支持 反对

使用道具 举报 送花

2

主题

21

回帖

108

积分

注册会员

积分
108
发表于 2023-10-22 20:41:22 | 显示全部楼层
学习记录(第15课)课堂笔记

I/O口 中断初始化程序:

        P3IM0=0X00;

        P3IM1=0XFF;                        //低电平中断
        P2INTE=0X20;                //p35中断 0010 0000


I/O口 中断 中断服务程序:

void P3EXIT_Isr(void) interrupt 40
{
        u8 intf;
        intf=P3INTF;                //读取中断标志
        if(intf & 0x20)                //P35按下? 0x20由来:芯片手册338页
        {
                P3INTF=0;                //读取完后清除中断标志
                if(intf&0x04)        //P35按下
                {
                        SEG0++;
                        if(SEG0>9)
                                SEG0=0;
                }
        }
}


特别注意,因位Keil软件的原因不能编译中断号>31的程序。需要安装补丁↓
截图202310222037381998.jpg

补丁软件下载链接:https://www.stcai.com/filedownload/609391  
截图202310222038546336.jpg 截图202310222039207872.jpg 截图202310222039352937.jpg



截图202310222034429340.jpg
截图202310222034517938.jpg


截图202310222035003748.jpg
截图202310222040338910.jpg

截图202310222035105898.jpg

截图202310222035185264.jpg




回复 支持 反对

使用道具 举报 送花

2

主题

21

回帖

108

积分

注册会员

积分
108
发表于 2023-10-23 19:38:06 | 显示全部楼层
学习记录(第16课)
外部中断
外部中断0初始化:

        IT0 = 1;
        EX0 = 1;
        IE0 = 0;



截图202310231930337102.jpg 截图202310231929587235.jpg 截图202310231930599490.jpg



P3口初始化:
        P3IM0=0X00;
        P3IM1=0XFF;          //低电平中断
        P2INTE=0X20;        //p35中断  0010 0000

主程序需要调用程序
        INT0_Init();                        //外部中断0初始化
        P3Exit_Init();

        EA = 1;        //总中断开关打开

截图202310231926351877.jpg

中断服务子程序:

void P3Exit_Isr(void) interrupt 40
{
        u8 intf;
        intf = P3INTF;                        //读取中断标志
        if( intf )
        {
                P3INTF = 0;                //清空中断标志位,必须软件清空
                if( intf & 0x20 )                //p35按下 0010 0000
                {

                }
        }
}

特别注意:由于Keil的原因,端口号不支持>31!!需要安装补丁,补丁在stcai网站上下载
截图202310231936201796.jpg

截图202310231937065129.jpg

截图202310231937288422.jpg

截图202310231937423487.jpg


截图202310231929094174.jpg
回复 支持 反对

使用道具 举报 送花

2

主题

21

回帖

108

积分

注册会员

积分
108
发表于 2023-10-23 21:15:10 | 显示全部楼层
本帖最后由 tyun1990 于 2023-10-24 09:52 编辑

学习记录(第17课)

STC32G系列是集成了12位高速A/D转换器。ADC 的时钟频率范围SYSclk/2/1到SYSclk/2/16。
截图202310232059108730.jpg

截图202310232100017780.jpg

ADC初始化:

        P1M0 = 0x00;P1M1 = 0x01;//设置P10高阻输入
        ADCTIM=0X3F;
        ADCCFG=0X2F;        
        ADC_POWER=1;

截图202310232108355313.jpg

截图202310232109345798.jpg

截图202310232114252294.jpg

截图202310232114539697.jpg


读取转换后的程序

u16 ADC_Read(u8 no)
{
        u16 adcval;                //16位整型变量 adcval 用来读取转换后的值
        ADC_CONTR &=0xF0;        //
        ADC_CONTR |= no;        //不能改变原来的设置,或等于NO,入口参数决定是第几通道
        ADC_START=1;
        _nop_();_nop_();        //等待2个时钟
        while(ADC_FLAG);        //等待ADC转换结束,“ADC_CONTR.5 :ADC_FLAG”
        adcval=(ADC_RES<<8)+ADC_RESL;//读取ADC转换的值
        return adcval;
}

主程序只需要调用ADC_Read(0) 来读取转换后的值,括号中的0表示ADC_CHS[3:0]=0000,选择P1.0 的I/O口
例如temp=ADC_Read(0); //读取P1.0口端口的ADC值


截图202310240951522001.jpg
例如:

截图202310240951107229.jpg






回复 支持 反对

使用道具 举报 送花

2

主题

21

回帖

108

积分

注册会员

积分
108
发表于 2023-10-24 10:18:21 | 显示全部楼层
学习打卡 第17课 第2部分

ADC中断  初始化:
        P1M0 = 0x00;P1M1 = 0x01;//设置P10高阻输入
        ADCTIM=0X3F;
        ADCCFG=0X2F;        
        ADC_POWER=1;

        EADC=1; //多了一个EADC



void ADC_Isr() interrupt 5    //ADC的中断是 5
{
        ADC_FLAG = 0; //清中断标志
        Read_RES=(ADC_RES<<8)+ADC_RESL;//读取
        ADC_START=1;//一直转换读取ADC值
}




预编译(红字部分):

#ifndef __ADC_H
#define __ADC_H

#define ADC_CHECK  0                         //查询
#define ADC_Isr    1                         //中断
#define  ADC_Func  ADC_Isr                //最终选择

extern u16 adc_val;                                //中断获取到的的数值。extern u16表示在其他地方定义了某个变量,在这里调用


void ADC_Init( void );                                //ADC初始化

u16  ADC_Read( u8 no );                                //读取指定通道的adc电压
u16 ADC_CAL_Voltage(u16 num);
#endif


#include "adc.h"


#if ADC_Func == ADC_CHECK


        void ADC_Init( void )//adc查询的相关定义
        {
                 //ADC初始化其他程序
        }


#elif ADC_Func == ADC_Isr
       
        void ADC_Init( void )//adc中断的相关定义
        {
                 //ADC初始化其他程序

               
        }


#else
       
#endif


由以上程序可见,多个void ADC_Init( void )   的初始化程序时,就可以用到预编译

回复 支持 反对

使用道具 举报 送花

2

主题

21

回帖

108

积分

注册会员

积分
108
发表于 2023-10-25 09:25:46 | 显示全部楼层
本帖最后由 tyun1990 于 2023-10-25 15:10 编辑

学习打卡,虽然已经学到第18课了,突发奇想想自己写一个矩阵键盘的实验,作业,作业为复习一下第14课老师教的
(↓4*4矩阵键盘,打错了↓)
12).gif

用到的模块:
截图202310250923105782.jpg 截图202310250923246112.jpg 截图202310250923383347.jpg

main.c:

#include <STC32G.H>
#include "TM1638.H"
//#include "intrins.h"
#include "DELAY.H"
#include "MateixKEY.H"
unsigned char TEMP,temp1;
//unsigned char KeyNum=0,SMG_WEI=2,Tube;        //KeyNum用来读取按键值,SMG_WEI用来在哪一个数码管位显示,Tube为数码管当前值
//unsigned char LED_Num=0,LED_SW;                //LED_Num用来操作哪一个LED灯,调节范围0-7。LED_SW用过来操作LED灯亮还是灭,0为灭1为亮
//unsigned char LianDu=0;                                //LianDu用来条件数码管和LED灯的亮度,调节范围0~5,上电默认最低亮度


void main()
{
        
        P0M0=0x00;P0M1=0x00;
        P2M0=0x00;P2M1=0x00;
        P3M0=0x00;P3M1=0x00;
        P4M0=0x00;P4M1=0x00;
    TM1638_Init(5);                                                //TM1638初始化
        AddrDisPlay(8,0x5b);                                //测试用,在第8为显示数字2






    while(1)
        {
                TEMP=MateixKEY_Read();
                temp1=TEMP;
//                AddrDisPlay(SMG_WEI,TubeTab[Tube]);                                //更新数码管显示 AddrDisPlay(第几位,显示几);        
                if(TEMP)
                {
                        AddrDisPlay(1,TubeTab[temp1]);//数码管刷新
                }
        }
}

工程目录树:
截图202310250920238649.jpg

截图202310250925124045.jpg

MATEIX_KEY.C:

#include <STC32G.H>
#include "MateixKEY.H"
#include "DELAY.H"


unsigned char MateixKEY_Read(void)                //矩阵按键读取当前是哪一个按钮按下
{
        unsigned char KeyNumber=0;
        
        P4=0xff;
        
        P43=0;
        if(P47==0){Delay(10);while(P47==0);Delay(10);KeyNumber=1;}
        if(P46==0){Delay(10);while(P46==0);Delay(10);KeyNumber=5;}
        if(P45==0){Delay(10);while(P45==0);Delay(10);KeyNumber=9;}
        if(P44==0){Delay(10);while(P44==0);Delay(10);KeyNumber=13;}
        
        P4=0xff;
        
        P42=0;
        if(P47==0){Delay(10);while(P47==0);Delay(10);KeyNumber=2;}
        if(P46==0){Delay(10);while(P46==0);Delay(10);KeyNumber=6;}
        if(P45==0){Delay(10);while(P45==0);Delay(10);KeyNumber=10;}
        if(P44==0){Delay(10);while(P44==0);Delay(10);KeyNumber=14;}
         
        P4=0xff;
        
        P41=0;
        if(P47==0){Delay(10);while(P47==0);Delay(10);KeyNumber=3;}
        if(P46==0){Delay(10);while(P46==0);Delay(10);KeyNumber=7;}
        if(P45==0){Delay(10);while(P45==0);Delay(10);KeyNumber=11;}
        if(P44==0){Delay(10);while(P44==0);Delay(10);KeyNumber=15;}
        
        P4=0xff;
        
        P40=0;
        if(P47==0){Delay(10);while(P47==0);Delay(10);KeyNumber=4;}
        if(P46==0){Delay(10);while(P46==0);Delay(10);KeyNumber=8;}
        if(P45==0){Delay(10);while(P45==0);Delay(10);KeyNumber=12;}
        if(P44==0){Delay(10);while(P44==0);Delay(10);KeyNumber=16;}
        return KeyNumber;
}




回复 支持 反对

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2025-5-6 16:35 , Processed in 0.172049 second(s), 99 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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