找回密码
 立即注册
查看: 1122|回复: 0

STC32G课程观后感

[复制链接]

2

主题

3

回帖

27

积分

新手上路

积分
27
发表于 2023-7-17 18:10:41 | 显示全部楼层 |阅读模式
本帖最后由 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\n  windows中的换行符 。


例 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[2]  = {0, 1, 2}
                  
                         a[1] = 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
         对应  0  1   2   3  4   5   6   7   8  9
               
       3.数码管实现0-9的显示
                先定义个数组SEG_Tab[10],把10个数字对应的16进制值存储进去                 

                 P70 = 0;                     //P70 对应最后那个数码管
                 P6 = SEG_Tab[0]        //显示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[num]        //显示

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


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


          2. 8位数码管点亮
                   增加位码 数组 COM_Tab
                   增加显示 数组 Show_Tab
                   定义 int  num 变量
                  
                   P7 = COM_Tab[num];
                   P6 = SEG_Tab[Show_Tab[num]];
                    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;   
                        
                 void  INT0_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_All  IO所有引脚
*       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;





回复

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2025-5-2 15:37 , Processed in 0.122720 second(s), 45 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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