tyun1990 发表于 2023-10-21 09:38:57

本帖最后由 tyun1990 于 2023-10-21 13:29 编辑

学习记录(第13课)第一部分课堂笔记:应用模块化编程,每一个模块对应一个 “.C”“.H”的文件。每个函数都要添加函数说明、版本号
//======================================================// 函数名称:// 函数功能: // 入口参数: // 函数返回: // 当前版本: VER1.0// 修改日期: 2023 - 1-1// 当前作者:// 其他备注://======================================================
修饰符extern 用在变量或者函数的声明前,用来说明此变量函数在别处定义的,要在此处引用例如:Temp.c文件需要应用Temp2.C文件变量int i,就可以在Temp2.H中声明 extern int i,之后才能在Temp.c文件中引用v这个变量

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

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


tyun1990 发表于 2023-10-21 20:00:37

学习记录(第13课)第二部分

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

u8LastState = 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>0 )                                //按键是按下的各种状态返回
        {
                if( Count<3 )                        //按下<30ms 返回消抖状态
                {
                        return KEY_FILCKER;
                }
                else if( Count==3 )                //按下正好30ms 返回单击
                {
                        return KEY_PRESS;
                }
                else if( Count<300 )                //按下不到3000ms 返回单击结束
                {
                        return KEY_PRESSOVER;
                }               
                else if( Count==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




tyun1990 发表于 2023-10-21 20:13:16

本帖最后由 tyun1990 于 2023-10-21 20:17 编辑

新买的书今天到货了,努力学习中!真羡慕他们大学生,有《STC32位 8051单片机原理与应用》教材 和“配套的实验箱”送呢。而我只能买

之前有一个核心板被我干废了,我也是个人才!估计整个论坛只有我会把核心板和OLED屏幕一起干废的了。无奈新买了一块。还有一块是STC8H8K64U核心板
还没来得及焊接排针先拿出来秀一秀






tyun1990 发表于 2023-10-22 10:27:25

本帖最后由 tyun1990 于 2023-10-22 18:26 编辑

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



#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               
}


tyun1990 发表于 2023-10-22 18:25:34

学习记录(第15课)

课堂笔记




要启动外部中断就必须打开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
{


}       

tyun1990 发表于 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的程序。需要安装补丁↓


补丁软件下载链接:https://www.stcai.com/filedownload/609391


















tyun1990 发表于 2023-10-23 19:38:06

学习记录(第16课)
外部中断
外部中断0初始化:

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







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

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

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



中断服务子程序:

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

                }
        }
}

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









tyun1990 发表于 2023-10-23 21:15:10

本帖最后由 tyun1990 于 2023-10-24 09:52 编辑

学习记录(第17课)

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




ADC初始化:

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










读取转换后的程序

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=0000,选择P1.0 的I/O口。
例如temp=ADC_Read(0); //读取P1.0口端口的ADC值



例如:








tyun1990 发表于 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_CHECK0                         //查询
#define ADC_Isr    1                         //中断
#defineADC_FuncADC_Isr                //最终选择

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


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

u16ADC_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 )   的初始化程序时,就可以用到预编译

tyun1990 发表于 2023-10-25 09:25:46

本帖最后由 tyun1990 于 2023-10-25 15:10 编辑

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


用到的模块:


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);                              //更新数码管显示 AddrDisPlay(第几位,显示几);      
                if(TEMP)
                {
                        AddrDisPlay(1,TubeTab);//数码管刷新
                }
      }
}

工程目录树:




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;
}




页: 1 [2] 3
查看完整版本: 实验箱已收到!看冲哥《STC32位8051单片机视频教程》学习记录