bwwjsbzd 发表于 2023-7-17 18:10:41

STC32G课程观后感

本帖最后由 bwwjsbzd 于 2023-7-17 20:36 编辑

大一就在学STC8A8k64D4的开发。


第一课:认识单片机
   这节课内容相对简单。

1.介绍了一下单片机的定义
2.简单介绍了stc的功能和用途。
            功能:读取电压,输出电平,计时,计数,等。
            用途:基本啥都能干,功能很多。
总的来说挺简单的。



第二课:认识硬件
       这节课介绍了开发板上的硬件外设。
比STC8a8k64d4外设丰富很多,功能也多上不少。
也看到了很多从来没有接触到的外设。




第三课:开发环境搭建和程序下载这是学习嵌入式单片机的基础,也是非常简单的。
还是在复习一下
接下来就来介绍一下。
         1.stc-isp下载
             https://stcai.com/gjrj 网址下载。
         2.手册下载
             stc-isp工具顶部菜单 资料下载 -手册下载 - 找到stc32系列。
             也可以在官网下载。
         3.4.pdf阅读器
            这个没啥说的,我自己用的苏门答腊pdf 。
            记得擅用书签,搜索等功能。
         5.c251环境搭建
            根据手册上的链接下载c351xxx.exe,一路next就行。
         6.程序包下载
            stc-isp顶部菜单 资料下载-软件库函数-stc32G库函数
         7.编译
            stc-isp中添加型号和头文件到keil中
            打开下载好的stc32g库函数中的工程文件(.uvproj),这里以跑马灯为例。
            点击keil左上的编译 链接 按钮 完成编译,如果编译成功,下方会出现0 errors。
          8.下载
             装好驱动。
             选好芯片和端口
             通过usb接口下载。
             按住p3^2按钮,再按电源按钮,最后再松开p3^2按钮。
             点击下载,完成下载。

这样。hex文件就被烧录进单片机可以看看实际运行结果了。

第四课 :建立工程点亮第一颗LED
1.点亮led原理
            GPIO 可以通过软件读取其输入电平或控制他输出高低电平。
            GPIO----发光二极管 -----限流电阻 ----- 5v (注意二极管方向)
            此时GPIO 输出低电平,发光二级管就会被点亮。
            类似的还有发光二极管负端接地,GPIO 输出高电平。
          2.新建Keil项目
                打开keil
                点击顶部菜单project- new uvision project,在弹出的对话框输入你的工程名字 0.1DEMO
                选择STC MCU 数据库,选择stc32g 单片机
                点击file-new 新建 文件
                点击file-save 保存文件 文件名 Demo.c
          3.写代码 点灯仪式

sfr P0          =   0x80;
sfr P1               =       0x90;

sbit LED1 = P0 ^ 7;                /*!< LED1 引脚定义 */
sbit LED2 = P0 ^ 6;

sbit LED4 = P0 ^ 4;                /*!< LED1 引脚定义 */
/*!< LED1 引脚定义 */

/*
   传统的 8051 单片机上电后即为准双向口模式并输出高电平,
       STC8A8K64D4系列单片机的 I/O 上电后为高阻输入模式。在向
       外输出信号前,要先使用 PxM0 和 PxM1 两个寄存器对 I/O
       的工作模式进行设置。
*/
sfr P0M0        =   0x94;   //0000,0000 端口0模式寄存器0
sfr P0M1        =   0x93;   //0000,0000 端口0模式寄存器1
sfr P1M0        =        0x92;
sfr P1M1        =        0x91;

int main()
{
        P0M0 = 0;
        P0M1 = 0;
        P1M0 = 0;
        P1M1 = 0;
       
    while(1)
    {
      LED1 = 0;
                LED2 = 0;
                LED4 = 0;
                       
    }
}



第五课C语言运算符和进制数入门

C语言的运算符和进制都是学习嵌入式的基础。

打印函数中可以添加格式字符,常见的格式字符有%d 整形 %f 浮点 %lf 双浮点 %o 8进制 %x 16进制 %c字符 %s字符串也可添加标志 n.m   -空格 #


常见的转义字符 \r\nwindows中的换行符 。


例 printf("温度:%.2f \r\n",15,8);
stc-isp中得到的输出就是 《温度:15.80》。


打印函数在单片机中实际上是以ascii码进行传输的,课程中也给出了ascii码表,在stc-isp中可以查看接收到的ascii (hex)数据。



算数运算符:主要是加减乘除 ,取余,自增自减就是基本的常用的数学运算。
                   位运算符:移位 按位与/或 取反
                   放到二进制中就很好理解了,左移,右移,就是将每一位进行移动,空的补0.
                   例:1101 0011 << 2 = 11 0100 1100;
                   按位与/或 就是将对应的位相与/或;
                   例:1000 0001 & 1000 0000 = 1000 0000;
                         1000 0001 & 1000 0000 = 1000 0001;

                  取反就是将所有位取反;
                        !1000 0000 = 0111 1111;




第六课LED闪烁和花式点灯


1s=1000ms = 1000 000 us


定义时钟频率为24M define 是c的宏定义
#define MAIN_Fosc 24000000UL


STC-ISP也有延时函数的生成。
列如:

void Delay1ms()                //@24.000MHz
{
        unsigned long edata i;

        _nop_();
        _nop_();
        _nop_();
        i = 5998UL;
        while (i) i--;
}


在主函数循环中调用延时函数

            点灯 延时 关灯 延时

            P40 = 0;
            Delay1ms();
            P40 = 1;

这个delay 使用方便 但弊端是占用单片机的内存。单片机不能做别的事情。

             3.新建文件使用模块化编程
                  新建xxx.c 和xxx.h
      
                  xxx.h中:
                         #ifndef __XXX_H_
                         #define __XXX_H_
                         调用头文件
                        函数声明
                        #endif

                  xxx.c中:
                            #include “xxx.h”
                            函数定义
                  例:
                         math.h


                         #ifndef __MATH_H_
                         #define __MATH_H_

                        
                         int add(int int);
                         #endif


                         math.c
                        
                         #include "math.h"


                         int add (int parm1, int parm2)
                         {
                                 return parm1+parm2;
                        }




第七课 按键点灯
         
          1.按键的原理

         常见用法:               
                      sys-vcc
                           |
             io - 电阻 - -按键 - gnd
             按键有抖动5-10ms


          2.按键的代码
            if(key == 0)
            {
                  delay_ms(10);
                  if(key == 0)
                   {
                        P60 = !P60;                   //点灯取反
                        while(key == 0);                     
                  }
               }

   
            按键按下执行的动作

               可以使用<< 移位来实现
         

          3.按键的应用

                   点击点灯,松开灭灯;
                   点击灭灯,松开点灯;      这两个直接赋值就行
                   按下一次, 改变一次;      这个取反
                  按下一次,左走一个;      这个移位

          4.数组      
               定义类型[长度] = {值}
                使用名称[索引] = 值;   

               例: int a= {0, 1, 2}
                  
                         a = 8;



第八课 蜂鸣器的应用
       1.认识蜂鸣器
            分有源和无源的,有缘的略贵,因为有震荡源,有黑胶,通电就叫。

P54 高关闭 P54 低开启
            自己的尝试:            
            #define buzzer P54

               if(key == 0)
            {
                  delay_ms(10);
                  if(key == 0)
                   {
                        buzzer = !buzzer//点击按键蜂鸣器开,再点关。                  
                        while(key == 0);                     
                  }

               }



作业 :
                #define key3 P36
                u8 working = 0;

                if(key3 == 0)
                {
                     delay_ms(10);
                     if(key3 == 0)
                  {
                        working = !working;                  
                        while(key3 == 0);                     
                     }

                }   

               if(working)
               {
                     led = 0;
                     delay_ms(200);

                     led = 1;
                     delay_ms(200);

               }



第九课 数码管的静态使用


       1.认识数码管
             开发板上有2个4位数码管
             长啥样的都有,内部有led
             本质还是点灯,和点亮led相同
            
             8字的里面有8个灯abcdefg dp,分共阳极 和共阴极
             共阳的给低电平 共阴的给高电平
             4位的abcdefg dp 是连在一起的

       2.控制原理    共阳极
               C0 F9 A4 B0 99 92 82 F8 80 90
         对应01   2   34   5   6   7   89
               
       3.数码管实现0-9的显示
                先定义个数组SEG_Tab,把10个数字对应的16进制值存储进去               

               P70 = 0;                     //P70 对应最后那个数码管
               P6 = SEG_Tab      //显示0

                  按按键便利数组SEG_Tab并给P6赋值,可以得到0-9 的显示

                   if(key2 == 0)
                {
                     delay_ms(10);
                     if(key2 == 0)
                  {
                        if(num<9)
                        {
                                 num++;                              
                           }            
                        while(key2 == 0);                     
                     }
                }   


                if(key == 0)
                {
                     delay_ms(10);
                     if(key == 0)
                  {
                        if(num<9)
                        {
                                 num--;                              
                           }            
                        while(key == 0);                     
                     }
                }

                P6 = SEG_Tab      //显示

               也可以加上蜂鸣器 ,每次按按键就会滴滴响,并切换数码数值。


第十课 数码管的动态显示
          1.数码管动态刷新原理
               依次打开每个位的公共阳极端,关闭其他的,
               同时 输入对应位的段码,就行了。


          2. 8位数码管点亮
                   增加位码 数组 COM_Tab
                   增加显示 数组 Show_Tab
                   定义 intnum 变量
                  
                   P7 = COM_Tab;
                   P6 = SEG_Tab];
                  delay_ms(1);
                   num++;
                   if(num >7)
                         num = 0;
                  
                  即可实现8位数码管点亮。




第十一课 定时器的使用
      1.定时器的意义和作用
            while循环中的每隔1ms加1 受while影响

            定时器 每隔固定时间完成操作可以脉冲计数 或替代delay


   2.定时器应用
                         手册上有个很清晰的定时器0 16位计数器的流程图
                        
                         TMOD = 0x00;       //模式 0
                         TL0 = 0x30;         //24M 1ms
                         TH0 = 0xF8;
                        TR0 = 1;               //启动定时器
                        ET0 = 1;                     //使能定时器中断
                        EA = 1;
                        
                        void tim0_isr() interupt 1
                        {
                                    //在这写中断函数的代码
                            }

                           stc-isp 定时器计算器很好用



                   课后练习:
                         void Timer0Init(void)                //10毫秒@24.000MHz

                         {
                                 AUXR &= 0x7F;                //定时器时钟12T模式
                              TMOD &= 0xF0;                //设置定时器模式
                              TL0 = 0xE0;                //设置定时初始值
                              TH0 = 0xB1;                //设置定时初始值
                              TF0 = 0;                //清除TF0标志
                                       TR0 = 1;                //定时器0开始计时
                         }

                        
                        void tim0_isr() interupt 1
                        {
                                    if(num>100)
                                    {
                                              clock++;          //时间变量(s)
                                              num = 0;
                                       }
                            }

                            sec = clock % 7200;
                            min = clock /60 %60;
                            hour = clock /7200;



第十二课 计数器
      1.计数器的用途
               马达 编码器
      2.计数器配置
                  T1_C/T 置1为计数器
                  T0_GATE控制开关
                  TH1 TL1 计数用的
         3.计数器应用
                   TMOD = 0x40;          //计数模式
                   TL1 = 0xff;
                   TH1 = 0xff;
                   TF1 = 1;            
                   TR1 = 1;
                   ET0 = 1;
                   EA = 1;
               
               void Timer0_Isr(void) interrupt 3
                  {
                        P60 = !P60;
                   }

            M法测速
                     n=M0/CT0


            还是没太学清楚。



第十三课 简易多任务处理


1.回顾   
                     GPIO 应用 和 TIM
                  重点清理程序的逻辑电路

               2.模块化编程 .c .h
                      LED&数码管               led_seg.c (.h)
                      按键                        key.c(.h)
                      蜂鸣器                     beep.c(.h)
                      定时器                     tim.c(.h)

                      函数添加注释
                      添加软件头

                     .h 中添加引脚定义
                           sbit name = P10;
                           #define name P10
                     函数
                           定义
                           声明
                           调用
                      extern
                              a.c 中 引用 b.c的变量要加
                      bdata
                              可以寻址每个位
                               u8 bdata LED = 0x00;
                               sbit LED0 = LED^0;
                               sbit LED1 = LED^1;

                   3.工程文件编写
                        这里将之前的代码都整理了一遍
                        拆分成了4个模块,
                        在key模块中引入了状态机的概念,
                        实现了短按,长按等功能,
                        
                        记住一个模块一个.c.h
                        声明放到.h 中




第十四课矩阵键盘


                先0-3 输出第电平 6-7 输出高电平
                     如果有按键按下,那一列io就变低电平 判断哪一列
                后0-3 输出高电平 6-7输出低电平
                     按下那一行的io就会变成低电平,判断出哪一列


         矩阵按键程序的编写
                  u8 MaterixKey_Read()
                  {
                         u8 keystate;                     //状态
                         u8 key_val = 0;
                         MaterixKey = 0xC0;
                         delay_ms(10);
                         keystate = MateixKey ^ 0xC0;
                         MaterixKey = 0x0f;

                         delay_ms(10);
                         keystate |= (MateixKey ^ 0x0f);
               
                        printf("0x%02x \r\n",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;
                           }                        

                        KEY_NUM = MaterixKey_Read();
                        SEG7 = KEY_NUM;
                        return keystate;
                   }
                           





第十五课 外部中断





      1.中断和中断系统
               cpu暂停,处理紧急事件,处理完继续原来的工作   
               相应优先级高的中断
               中断可以独立开关
               部分优先级可以设置
                  
       2.什么是外部中断
               外部电平变化产生的中断
               
                写着INT的引脚是外部中断口
                     
       3.外部中断的用法
                外部中断0
               IT0
               IE0
               EX0
               EA
                外部中断1
               IT1
               IE1
               EX1
               EA
               外部中断x
               INTxIF
               EXn
               EA
          4.外部中断用法
               
               IT0 = 1;               //使能 INT0 上升沿和下降沿中断
               EX0 = 1;            //使能 INT0 中断
               IE = 0;
               EA = 1;   
                        
               voidINT0_Init() interrupt 0
                  {
                        LED0 = !LED0;
                  }











总结:
学到了很多,也对一些东西进行了改写。


/* 函数体 -----------------------------------------------------------*/
/*
* 功能: GPIO    端口初始化
* 参数: gpio:   GPIO端口, GPIO_P0 - GPIO_P7
*       pin:    I/O引脚,GPIO_Pin_0 - GPIO_Pin_7 IO引脚 Px.0-7
*                         GPIO_Pin_LNIB IO引脚低 4 位
*                         GPIO_Pin_HNIB IO引脚高 4 位
*                         GPIO_Pin_AllIO所有引脚
*       mode:        工作模式
* 返回:SUCCESS 返回成功。
*                        ERROR   返回失败。
*/
//#define chr(x)        #@x
//ErrorStatus GPIO_Initl(uint8_t gpio_x, uint8_t pin, eGPIO_Mode mode)
//{
//                if(gpio_x > GPIO_P7)        return ERROR;
//                       
//                if(mode & BIT0)        Px_M0(gpio_x) |= (pin);
//                else        Px_M0(gpio_x) &= ~(pin);
//               
//                if(mode & BIT1)        Px_M1(gpio_x) |= (pin);
//                else        Px_M1(gpio_x) &= ~(pin);

//                return SUCCESS;
//}





typedef enum
{                /* IO 模式 */
    GPIO_MODE_WEAK_PULL         = 0x00,        /*< 上拉准双向口         */
    GPIO_MODE_OUT_PP                         = 0x01,        /*< 推挽输出        */
    GPIO_MODE_IN_FLOATING = 0x02,        /*< 浮空输入         */
    GPIO_MODE_OUT_OD                         = 0x03,        /*< 开漏输出         */
                /* IO 控制 */
    GPIO_CTRL_PULLUP                         = 0x10,        /*< 上拉电阻        */
    GPIO_CTRL_ST                                         = 0x20,        /*< 施密特触发器        */
    GPIO_CTRL_SPEED                   = 0x40,        /*< 电平翻转速度         */
    GPIO_CTRL_DRIVE                                = 0x80,        /*< 驱动电流         */       
} eGPIO_Mode;

/* GPIO Bit SET和Bit RESET枚举 */
typedef enum
{
    GPIO_PIN_RESET = 0,
    GPIO_PIN_SET = 1
} eGPIO_PinState;





页: [1]
查看完整版本: STC32G课程观后感