查看: 814|回复: 6

[天问STC8]单片机学习笔记(20210714&0715)

[复制链接]

6

主题

40

帖子

112

积分

注册会员

Rank: 2

积分
112
发表于 2021-7-15 16:47:30 | 显示全部楼层 |阅读模式
这两天分别学习了字符式编程以及定时器的相关知识,两天的笔记和在一起,作为一个帖子发。


目录
1、字符式编程(C语言)
2、定时器的基础知识
3、定时器的应用,8*led,数码管和点阵

回复

使用道具 举报

6

主题

40

帖子

112

积分

注册会员

Rank: 2

积分
112
 楼主| 发表于 2021-7-15 17:11:25 | 显示全部楼层
字符式编程(C语言)

    如果有c语言的基础,结合图形化编程的直观表示,单片机的字符式编程就很容易上手。


1、通过天问Block,小灯是如何点亮的。
    当你编一个C语言程序,写下来的代码将会通过编译器转化为汇编语言,汇编语言再转化为机器语言。机器语言就是可供cpu直接阅读的语言,cpu阅读机器语言后,完成一系列的指令。


    C语言==>汇编语言==>机器语言

而天问Block中的图形化编程,则是在C语言之前加了一环图形编程,简略了C语言编程的一些繁杂输入。


    图形化编程==>C语言==>汇编语言==>机器语言

2、程序烧写过程。
    BIN或HEX==>烧写软件==>烧写工具==>芯片内ROM


3、C语言的其他基本内容。


    (1)变量。  按照定义的位置可分为局部变量和全局变量;按照存储方式可以分为静态变量和动态变量。
           按照存储的内容来分,还分为整型、浮点型等等。
    (2)头文件。形式如:xxxx.h,头文件里封装了函数,在编程时声明头文件后就可使用这个函数。
    (3)运算符。A、关系运算(==,!=,>等等),结果为真或假。
                         B、逻辑运算(||,&&,!)
                         C、位运算(<<左移,>>右移,~按位取反,|或,&与)
    (4)函数。
    (5)循环和条件。 编程中的基本算法。


回复

使用道具 举报

6

主题

40

帖子

112

积分

注册会员

Rank: 2

积分
112
 楼主| 发表于 2021-7-15 17:33:37 | 显示全部楼层
定时器的基本知识

1、定时器的原理
(参考:定时器工作原理-电子发烧友网 (elecfans.com)
    看起来很复杂,实际上就是由一个晶振发出脉冲信号,然后由计数器计数。晶振单次振动的时间可能很小,是纳秒级别的时间,但是用计数器套计数器套娃之后,就可以定1ms,1us等等等等。


2、什么是定时器。
    在工业检测、实时控制系统中,经常要用到定时或计数功能,用于产生精确的定时时间,对外部脉冲进行计数等。基于STC8H8K64U芯片的天问51单片机中有5个可编程定时器。其它型号芯片,请查看芯片手册确认可用定时器。


3、定时长度。
    定时器的最大定时长度=65536×0.5=32768微秒,也就是说,在定时器初始化定时长度(微秒)这一栏中,不能填超过32768的数字。
   
我们来做个小小实验:


点击运行,可以看见cmp灯在频率很快的闪烁。这是由于定时长度为30000us,相当于0.03秒,每0.06秒完成一次闪烁,肉眼勉强可以看得清在闪。
如果我们把定时长度定为1000000,相当于1s,点击运行,发现cmp灯反而不闪烁了。这是因为定时长度超过了限额。
2.PNG
1.PNG
回复

使用道具 举报

6

主题

40

帖子

112

积分

注册会员

Rank: 2

积分
112
 楼主| 发表于 2021-7-16 10:36:33 | 显示全部楼层
中断系统



定义:CPU在处理某一事件A时,发生了另一事件B请求CPU迅速去处理(中断发生); CPU暂时中断当前的工作,转去处理事件B(中断响应和中断服务); 待CPU将事件B处理完毕后,再回到原来事件A被中断的地方继续处理事件A(中断返回),这一过程称为中断 。

目的:
————51单片机主要用于实时测控,要求单片机能及时响应和处理单片机内部或外部事件。由于很多事件都是随机发生的,如果采用定时查询方式来处理这些事件请求,有可能得不到实时处理,且单片机的工作效率也会变得很低。因此,单片机要实时处理这些事件,就必须采用中断技术来实现,这就要用到一个重要的功能部件--中断系统。(来自PPT)
    中断系统的功能如上图,要理解中断系统的优越性,就得比较中断和定时查询两种总线仲裁方式。这两种方式的区别主要在于检测方式:
        查询法,编程,循环检测 TF==1,去执行指定程序。
        中断法,硬件,自动检测 TF==1,去执行指定程序。
    用中断法,效率高,且延时的时间精确。
   
回复

使用道具 举报

6

主题

40

帖子

112

积分

注册会员

Rank: 2

积分
112
 楼主| 发表于 2021-7-16 11:13:34 | 显示全部楼层
定时器的应用——前置学习:数码管和点阵的探究

    定时器常应用于外部设备的接入使用,在51单片机里,这个设备主要是数码管、点阵等。所以在进入定时器的应用前,先了解数码管、点阵的使用知识。
结合图形化模块,先看点阵的功能:


然后是数码管的功能


无论是定时器还是数码管,本质上的原理都差不多,就是指令定位到相关的寄存器,点亮某个led。多个led点亮了,就组成了图案,或是点阵中的图形,或是数码管显示的数字。

举个例子:
以时钟显示模块为例,


我们找到它的C语言代码:



跳转到函数的定义:
    这里我们可以发现函数是通过对一个叫‘“_nix_display_buff”的变量完成时钟的显示的


    在头文件中找到这个变量的定义,



    有没有发现,和图形化编程中的“更新显示缓存mylist”功能很像,无论是数码管还是点阵,都是通过数组来确定led发光的地址的,而图形化编程的其他功能,都是在这个的基础上加以发挥。

4.4.PNG
4.3.PNG
4.2.PNG
4.1.PNG
3.1.PNG
3.PNG
回复

使用道具 举报

6

主题

40

帖子

112

积分

注册会员

Rank: 2

积分
112
 楼主| 发表于 2021-7-16 11:37:07 | 显示全部楼层
定时器的应用——实践
    在对点阵和数码管进行了解后,我进入定时器应用的实践。


1、简易时钟。
    第一个程序我利用数码管来编写一个时钟。
   

    程序的结果是从12:30:00开始读秒计时。这个程序是在中断系统中判断是否读秒的。在编写程序的时候,我还发现简易时钟可以有另一种编写方式:




这里我只用一个delay()函数,就可以达到上面的效果。前几张中断系统和定时查询的比较,让我怀疑其实这个delay()函数实际上是定时查询的函数,然后我查询函数定义:



可知delay()函数是对计算机每一次频率的周期进行计数,再进行一系列的逻辑判断。本质上,delay()函数是一个定时查询。
5.3.PNG
5.2.PNG
5.1.PNG
回复

使用道具 举报

6

主题

40

帖子

112

积分

注册会员

Rank: 2

积分
112
 楼主| 发表于 2021-7-16 11:53:01 | 显示全部楼层
定时器的应用——实践


2、点阵轮流亮轮流灭程序——在图形化编程基础上编写C语言程序
    要是让我全都用C语言编写程序,很多的头文件、函数的名称我还不是很熟悉,于是我在通过图形化编程对函数、变量、头文件等进行定义和声明后,用C语言加以更改,实现我想要的效果。


我想要的效果是,点阵从第一个led灯开始,从左往右从上到下亮起,再从右往左从下到上灭掉。


以下是程序源代码:


#define MATRIX_PORT P6
#define MATRIX_PORT_MODE {P6M1=0x006M0=0xff;}//推挽输出

#include <STC8HX.h>
uint32 sys_clk = 24000000;//设置PWM、定时器、串口、EEPROM频率参数
#include "lib/twen_board.h"
#include "lib/led8.h"
#include "lib/matrix.h"

uint8 mylist[8]={0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
void Timer0Init(void)        //1000微秒@24.000MHz
{
  AUXR &= 0x7f;                //定时器时钟12T模式
  TMOD &= 0xf0;                //设置定时器模式
  TL0 = 0x30;                        //设定定时初值
  TH0 = 0xf8;                        //设定定时初值
}

void T_IRQ0(void) interrupt 1 using 1{
  matrix_scan_callback();//点阵扫描回调函数
}

void setup()
{
  twen_board_init();//天问51初始化
  led8_disable();//关闭8个LED流水灯电源
  matrix_init();//点阵初始化
  Timer0Init();
  TR0 = 1;// 定时器0开始计时
  EA = 1; // 控制总中断
  ET0 = 1; // 控制定时器中断
}

void loop()
{
  int i,j;
  uint8 step_list[8];
  uint8 kkk=0x80;
  for(i=0;i<8;i++)
  {  
    step_list=mylist;
  }
  for(i=0;i<8;i++)
  {
    step_list--;
    matrix_update_buf(step_list);//点阵更新显示缓存
    delay(i*10);
  }
  for(j=0;j<7;j++)
    for(i=0;i<8;i++)
    {
      step_list=step_list*2;
      matrix_update_buf(step_list);//点阵更新显示缓存
      delay(i*10);
    }   
//  for(i=0;i<8;i++)
//  {
//    step_list=step_list+0x80;
//    matrix_update_buf(step_list);//点阵更新显示缓存
//    delay(100);
//  }
  for(j=0;j<8;j++)
  {
    for(i=0;i<8;i++)
    {
      step_list=step_list+kkk;
      matrix_update_buf(step_list);//点阵更新显示缓存
      delay(i*10);
    }  
    kkk=kkk/2;
  }
}

void main(void)
{
  setup();
  while(1){
    loop();
  }
}

运行测试,符合目标。
OVER

回复

使用道具 举报

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

本版积分规则

QQ|Archiver|手机版|小黑屋|好好搭搭在线 ( © 好好搭搭在线 浙ICP备19030393号-1 )

GMT+8, 2024-4-19 05:04 , Processed in 0.332403 second(s), 25 queries .

Powered by Discuz!

© 2001-2024 Comsenz Inc.

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