雾里看花 发表于 2023-7-17 16:47:52

第十二集
定时器要设置为计数功能,需要配置TMOD的C/T为1
计数器根据脉冲来计数,在模式1下,计数最大值为65536,超过65535就会产生中断,设置预装载值TH0/TL0,当计数溢出时,重载为预装载值。

小龙哥 发表于 2023-7-17 21:36:26

多任务处理学习起来有点难,看了两遍了,还是有点晕,等拿到试验箱,多练习练习吧!

工控单片机 发表于 2023-7-17 22:42:38

                        printf("计算结果:%d\r\n",TL1);
//            memcpy(UsbInBuffer, UsbOutBuffer, OutNumber);//将接收数据(UsbOutBuffer),复制到发送缓冲区(UsbInBuffer)
//            usb_IN(OutNumber);      //原路返回, 用于测试
      }
    }
}
//void Tim1_Isr() interrupt 3//计数器1中断函数,中断号3,固定格式计数器0中断号必须是1,计数器1中断号是3,
//{
//        P60 = !P60;
//}
void Timer0_Isr(void) interrupt 1//定时器1ms中断服务函数
{
       
        Tim_Count++;
        if(Tim_Count>=2000)//计时到达2000MS,也就是2S,
        {
        Tim_Count = 0;//计时值清零,
        Count_t1 = (TH1*256)+TL1;//读计数寄存器高八位TH1和低八位TL1的值
        TH1 = 0;//计数值清零,
        TL1 = 0;//计数值清零,
        Show_tab=Count_t1/1000%10;
        Show_tab=Count_t1/100%10;
        Show_tab=Count_t1/10%10;
        Show_tab=Count_t1/1%10;          //取1位
        }
        Seg_Fre();
}

我在while(1)里面打印TL1的值,TL1不会被清零,求解。

void Timer0_Init(void)                //1毫秒@24.000MHz1ms定时器初始化
{
        AUXR &= 0x7F;                        //定时器时钟12T模式
        TMOD &= 0xF0;                        //设置定时器模式
        TL0 = 0x30;                                //设置定时初始值
        TH0 = 0xF8;                                //设置定时初始值
        TF0 = 0;                                //清除TF0标志
        TR0 = 1;                                //定时器0开始计时
        ET0 = 1;                                //使能定时器0中断
}

void Timer1_Init(void)                //1毫秒@24.000MHz计数器初始化函数,检测到到一次脉冲执行一次中断服务函数
{
        TMOD = 0x40;                        //设置计数器模式
        TL1 = 0x00;                                //设置计数器初始值========计数两次脉冲进入中断
        TH1 = 0x00;                                //设置计数器初始值
        TF1 = 0;                                //清除TF0标志
        TR1 = 1;                                //计数器1开始计时
        ET1 = 1;                                //使能计数器1中断
}


这是计数和中断初始化

雾里看花 发表于 2023-7-18 08:57:23

第十三集
学习使用模块化编程,每个外设单独一个.c/.h文件。在写函数时,为函数添加一些注释性内容,方便他人阅读。
使用extern 修饰符用来说明变量和函数在别的地方已经定义,需要在此处引用。extern修饰变量不能赋初值。
学习使用bdata位寻址变量。

雾里看花 发表于 2023-7-18 10:37:21

第十四集
了解矩阵按键,使用矩阵按键可以减少IO口占用。按键数量x*y,IO口数量需要x+y
控制列IO口输出低电平,行IO口输出高电平,当按键按下,可以知道哪一行按键按下;
控制列IO口输出高电平,行IO口输出低电平,当按键按下,可以知道哪一列按键按下;
行列一组合就能知道哪个按键被按下。

雾里看花 发表于 2023-7-18 11:30:50

第十五集
在主程序运行过程中,有中断请求时,需要进行响应去执行中断处理程序,执行完后再返回主程序继续执行。
CPU总是先响应优先级最高的中断请求,然后按照优先级高低顺序来依次执行中断服务程序。
外部中断是捕获单片机上引脚电平变化,单片机上只有一些固定引脚才能被用作外部中断的IO口。

雾里看花 发表于 2023-7-18 12:12:10

开始学习
第一集
了解什么是单片机,如何学习单片机。

第二集
了解实验箱上所有元器件以及其功能。

第三集
开发环境搭建完成,坐等开发板。

第四集   点亮LED
LED一端连接电阻接P6口,另一端接三极管外接高,当P6,P4口输出低电平,三极管导通,LED相当于一端接高一端接地,此时LED点亮。编写代码用的是寄存器,习惯了使用库函数对于寄存器的使用不太习惯。特殊功能寄存器sfr,sbit定义特殊功能寄存器的位变量。使用端口数据寄存器P4、P6,模式配置寄存器P4M0、P4M1、P6M0、P6M1都设置为0(准双向口),将定义好位变量P40、P60附值为0点亮LED,然后学习如何实现不断电下载程序的功能,在<stc32g.h>包含寄存器定义,无需自己定义。

第五集
C语言基础知识基本都学过
要实现printf需要添加如下代码
if( DeviceState != DEVSTATE_CONFIGURED)
    continue;
if(bUsbOutReady){
    usb_OUT_done();
    printf();
}
每次打印信息都要加上这些代码,还需要使用串口发送数据才能接收数据,有没有别的方法实现printf。

第六集
控制LED灯闪烁,需P60先给低电平,延时后再给高电平。延时用到了delay_ms函数,函数里用到了while和do.....while循环,代码能够看懂,但是为什么这么写能够实现ms延时不清楚。在学习如何实现LED闪烁中间穿插了C语言知识,比如#define用法,a--和--a区别,while和do.....while区别,函数使用,模块化编程,这样方式让我对C语言理解更加透彻。

第七集
因为开关是机械开关,所以按下松开时需要进行按键消抖。
正常LED不亮,按下按键,LED从左往右流水
#define KEY1 P32
u8 LED_State = {0XFE,0XFD,0XFB,0XF7,0XEF,0XDF,0XBF,0X7F};
void main()
{
    u8 num = 0;
    P6 = 0xFF;
    if(KEY1 == 0)
    {
            delay_ms(10);
            if(KEY1 == 0)
            {
                  P6 = LED_State;
                delay_ms(500);
                num++;
                if(num > 7) num = 0;
      }
    }
}

第八集
P54给低电平,蜂鸣器工作。使用一个电磁炉实际应用将之前所学LED,按键和蜂鸣器进行整合,巩固所学知识,知道所学是如何应用于实际生活中的。

第九集
数码管由多个发光二极管组成,点亮数码管和点亮LED一样。由发光二极管组成不同形状,点亮不同二极管就可以显示不同图案,比如显示数字0~9。
练习显示
H:0x89      J:0xf1         L:0xc7       n:0xab       o:0xa3         
P:0x8c         U:0xe3         t:0x87       r:0xaf

KEY1控制数码管显示0~9循环,KEY2根据数字控制蜂鸣器鸣叫
u8 SEG = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
P6 = SEG;
if(KEY1 == 0)
{
    delay_ms(10);
    if(KEY1 == 0)
    {
      while(KEY1 == 0);
      if(num < 9)num++;
      if(num == 9)num = 0;
    }
}
if(KEY2 == 0)
{
    delay_ms(10);
    if(KEY2 == 0)
    {
      while(KEY2 == 0);
       while(num--)
       {
         BEEP = 0;
         delay_ms(50);
         BEEP = 1;
       }
    }
}

第十集
数码管动态刷新就是依次让每个数码管显示图案,虽然依次点亮数码管中间有延迟时间,但是由于人眼分辨率原因,多个数码管循环时间不超过20ms的情况下,在人眼看来数码管是一直显示的,这样就实现了多个数码管的动态显示。
练习
u8 hour = 0;
u8 minute = 0;
u8 second = 0;
u8 SEG = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf};
u8 COM = {0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};
u8 SHOW = {hour/10,hour%10,10,minute/10,minute%10,10,second/10,second%10};
void SEG_Fre(void)
{
      P7 = COM;
      P6 = SEG];
      delay_ms(1);
      num++;
      if(num > 7)num=0;
}
void main()
{
      num = 0;
      SEG_Fre();
      while(1)
      {
                P6 = SEG];
                delay_ms(1000);
                second++;
                if(second > 59){
                        minute++;
                        second = 0;
                }
                if(minute > 59){
                        hour++;
                        minute = 0;
                }
                if(hour > 23){
                        hour = 0;
                }
                if(hour == 0 && minute == 0 && second == 30)
                {
                        beep = 1;
            delay(3000);
            beep = 0;
                }
      }
}

第十一集
定时器具有计数和定时两种工作方式,定时本质就是对脉冲进行计数,不同定时器通过操作不同寄存器来设置定时还是计数功能,比如T0和T1操作TMOD寄存器。定时器模式下可以设置分频,此时定时器每12个时钟或者每1个时钟得到一个计数脉冲,计数值加一。定时器/计数器0有4种工作模式,可通过TMOD寄存器的T0_M1/T0_M0设置。IE中的EA是中断总开关,ET0为定时器0的中断允许位。使用定时器比延时更加高效和精确。计算定时时间手算比较慢,还容易出错,可以通过官方提供工具,选择好时钟,定时时间,模式,自动计算并生成代码,大大提高效率。

第十二集
定时器要设置为计数功能,需要配置TMOD的C/T为1
计数器根据脉冲来计数,在模式1下,计数最大值为65536,超过65535就会产生中断,设置预装载值TH0/TL0,当计数溢出时,重载为预装载值。

第十三集
学习使用模块化编程,每个外设单独一个.c/.h文件。在写函数时,为函数添加一些注释性内容,方便他人阅读。
使用extern 修饰符用来说明变量和函数在别的地方已经定义,需要在此处引用。extern修饰变量不能赋初值。
学习使用bdata位寻址变量。

第十四集
了解矩阵按键,使用矩阵按键可以减少IO口占用。按键数量x*y,IO口数量需要x+y
控制列IO口输出低电平,行IO口输出高电平,当按键按下,可以知道哪一行按键按下;
控制列IO口输出高电平,行IO口输出低电平,当按键按下,可以知道哪一列按键按下;
行列一组合就能知道哪个按键被按下。

第十五集
在主程序运行过程中,有中断请求时,需要进行响应去执行中断处理程序,执行完后再返回主程序继续执行。
CPU总是先响应优先级最高的中断请求,然后按照优先级高低顺序来依次执行中断服务程序。
外部中断是捕获单片机上引脚电平变化,单片机上只有一些固定引脚才能被用作外部中断的IO口。




小龙哥 发表于 2023-7-18 12:22:14

今天学习了矩阵按键,了解了矩阵按键的原理,主要是为了减少I/O口的占用,可是程序上会比独立按键的复杂一些,不超过五个按键的不适合用矩阵,

小龙哥 发表于 2023-7-18 14:33:45

十五集学了外部中断,了解了中断的优先级,做系统时这点比较重要,说白了就是根据事件的轻重缓急,来设定优先级,还有外部中断的原理框图,以及具体用法冲哥讲的也比较详细,感觉没啥难度{:4_245:}

chxelc 发表于 2023-7-19 14:13:29

公司电子工程师一枚,STC15 STC8用得很熟了,有个蓝牙项目需要用到32位MCU,比较了ARM内核和STC32G等32位MCU,本着够用原则,成本至上原则,果断选择STC32G12K128,目前资料较少,冲哥的视频教程是最系统和全面的。认真学习,争取拿下STC32G,拿下项目,加油!
页: 85 86 87 88 89 90 91 92 93 94 [95] 96 97 98 99 100 101 102 103 104
查看完整版本: 视频教学:《32位8051单片机原理及应用》,一等奖2万, 送实验箱; 冲哥版