找回密码
 立即注册
楼主: Rain_Personal

跟冲哥学习STC32G128K芯片打卡

[复制链接]
  • 打卡等级:以坛为家I
  • 打卡总天数:210
  • 最近打卡:2025-05-05 17:50:21

1

主题

63

回帖

369

积分

中级会员

积分
369
发表于 2024-4-26 20:28:13 | 显示全部楼层
本帖最后由 Rain_Personal 于 2024-4-26 20:37 编辑

第九课 数码管的静态使用

1. 什么时数码管
截图202404262008418579.jpg

数码管就是LED灯,根据发光二极管的正负极可以分为共阳和共阴数码管,LED灯负极接在一起的就是共阴,LED数码管正极接在一起的就是共阳
截图202404262012332051.jpg


截图202404262035296094.jpg

每个灯表示一个段,每8个灯表示一个位,根据课后作业推算出来的各个字母的描述其中N的描述应该时11.。没有想到其他方法,只能用dp区分了。


截图202404262017467903.jpg

根据每个灯的控制逻辑可以将每个数字所需要亮的灯用16进制描述。
首先需要控制共阳/阴极开启一位显示,再根据16进制控制这一位的每个灯开关逻辑
P70 = 0;                        //开启一个数码管

就是开启一个数码管。
截图202404262027507646.jpg

关键代码分析

截图202404262018357014.jpg
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:210
  • 最近打卡:2025-05-05 17:50:21

1

主题

63

回帖

369

积分

中级会员

积分
369
发表于 2024-4-26 21:00:30 | 显示全部楼层
本帖最后由 Rain_Personal 于 2024-4-27 08:32 编辑

第十课  动态显示数码管

1. 显示原理
截图202404262048374130.jpg

其中需要注意每个延时不能太短,我们这边程序就以1ms为准,且需要保证总共一个循环结束的时间不能大于20ms,因为人眼的视觉不容易分辨出50HZ以上的动态刷新。

截图202404262047064288.jpg

通过延时的长短可以控制每个灯的显示时间,超过人眼闪烁的分辨率就可以看起开像都显示了。
全部显示不同数字时,可以减少延时时间,看起来像是每位都在显示,其实是每位分别显示,只是频率快,人眼分辨不出来。
逻辑上有点绕,感觉比较复杂。
2. 10秒按键挑战代码分析


void SEG_Fre( void )   //  应该是属于  刷新数码管
{
        //位码选择第一位,段码选择0  
        P7 = COM_Tab[num];                        //位码的选择
        P6 = SEG_Tab[Show_Tab[num]];//需要显示的数字的内码 赋给 P6   NUM =0 -> Show_Tab[num]] = 1 -> p6 = oxF9
        delay_ms(SEG_Delay);

        num++;
        if( num >7 )
                num = 0;        
}


                Show_Tab[0]  = 1;                //选择 1
                Show_Tab[1]  = 10;                //选择 0.  // 为什么从10开始,   带小数点
                Show_Tab[2]  = 0;                //选择 0
                Show_Tab[3]  = 0;                //选择 0                        

                if( RUN_State==1 )
                {
                        TimCount++;
                        Show_Tab[4] = TimCount/10000%10;  //  TimCount/10000,表示有多少个10000,计算万位以上数字 %10 对10取余 表示万位上的数字
                        Show_Tab[5] = TimCount/1000%10+10;        // 加10 带小数点
                        Show_Tab[6] = TimCount/100%10;               
                  Show_Tab[7] = TimCount/10%10;                //取10位
                }
               
                SEG_Fre();  // 刷新数码管

                if( KEY1 ==0 )
                {
                        delay_ms(10);
                        if( KEY1 ==0 )
                        {
                                BEEP = 0;
                                delay_ms(10);
                                BEEP = 1;
                                while( KEY1 ==0 )
                                {
                                        SEG_Fre();
                                }
                                if( RUN_State==0 )
                                        TimCount = 0;
                                
                                RUN_State = !RUN_State;
                        }
                }

这逻辑秒呀!!!


回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:210
  • 最近打卡:2025-05-05 17:50:21

1

主题

63

回帖

369

积分

中级会员

积分
369
发表于 2024-4-26 21:05:15 | 显示全部楼层
本帖最后由 Rain_Personal 于 2024-4-27 08:35 编辑

第十一课 定时器的应用

while(Key==0)会不断循环,函数不会向下运行。
1. 定时器作用

截图202404262103496175.jpg

定时器主要是可以自动自增,定时时间,达到固定时间就可以执行想要的不在主程序中的程序段

void Timer0_Init(void)                //1毫秒@24.000MHz
{
        AUXR &= 0x7F;                        //定时器时钟12T模式   AUXR为寄存器0x8e 那么后面的都是寄存器的描述,直接赋值寄存器,就是初始化
        TMOD &= 0xF0;                        //设置定时器模式
        TL0 = 0x30;                                //设置定时初始值
        TH0 = 0xF8;                                //设置定时初始值
        TF0 = 0;                                //清除TF0标志
        TR0 = 1;                                //定时器0开始计时
        ET0 = 1;                                //使能定时器0中断
}


void Timer0_Isr(void) interrupt 1 // interrupt 关键字
{
        SEG_Fre();                //数码管刷新的
        
        if( RUN_State==1 )                //如果开始运行
        {        
                TimCount++;                        //每隔1ms+1
                Show_Tab[4] = TimCount/10000%10;
                Show_Tab[5] = TimCount/1000%10+10;        
                Show_Tab[6] = TimCount/100%10;               
                Show_Tab[7] = TimCount/10%10;                //取10位
        }
        
}
截图202404270826499665.jpg

可以通过STCAI-ISP下载器中的所带的功能设置定时器
不使能定时器

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

使能定时器  ET0的寄存器使能定时器

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


回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:210
  • 最近打卡:2025-05-05 17:50:21

1

主题

63

回帖

369

积分

中级会员

积分
369
发表于 2024-4-27 08:58:32 | 显示全部楼层
第十二课  计数器的应用

截图202404270847584232.jpg

使用SYSclk时,是计时器,SYSclk为固定频率,所以可以计数,理论仍是计数。
使用T1 Pin为计数器,可以对电机转速什么的进行计数

回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:210
  • 最近打卡:2025-05-05 17:50:21

1

主题

63

回帖

369

积分

中级会员

积分
369
发表于 2024-4-27 10:05:20 | 显示全部楼层
本帖最后由 Rain_Personal 于 2024-4-27 11:48 编辑

第十三课  简易多任务处理
1. 模块化编程
打开工程后。需要打开一个c文件才可以显示模块化编程中的模块
截图202404270902347095.jpg
截图202404270902188966.jpg





打开c文件之后

截图202404270907469822.jpg


引脚定义可以用

sbit 名称 = P10;        
#define 名称 P10
作业:LED0给他200ms取反一次,LED1给他400ms取反一次,LED2给他800ms取反一次
截图202404271141453195.jpg

关键代码
P40 = 0;
// 可采用中断控制LED0  LED1 LED2
// LED0  200ms

截图202404271146475605.jpg

不能生成200ms的程序...



回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:210
  • 最近打卡:2025-05-05 17:50:21

1

主题

63

回帖

369

积分

中级会员

积分
369
发表于 2024-4-27 11:56:15 | 显示全部楼层
第十四课  矩阵键盘


截图202404271152435856.jpg

SW33按下为什么是0,而不是P01是5V???
GND遇到5V会把引脚拉低到0V,而不是5V会把GND拉底到5V!
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:210
  • 最近打卡:2025-05-05 17:50:21

1

主题

63

回帖

369

积分

中级会员

积分
369
发表于 2024-4-27 14:35:31 | 显示全部楼层
第十五课 外部中断

1. 中断系统
多个中断源
2. 外部中断
截图202404271427149230.jpg


外部引脚可以触发中断,INT标注的引脚为中断引脚
代码描述
需要首先定义中断 以中断0为例
        EA = 1;                                        //CPU开放中断,打开总中断。
        IT0 = 1;                                                //1:下降沿中断   0:上升下降沿中断
        EX0 = 1;                                                //允许中断
        IE0 = 0;                                                //清除中断标志位

void INT0_Isr(void) interrupt 0  // 中断触发后执行的函数  
{
        SEG0 += 1;                                        //数码管0的数值+1
}


回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:210
  • 最近打卡:2025-05-05 17:50:21

1

主题

63

回帖

369

积分

中级会员

积分
369
发表于 2024-4-27 15:15:33 | 显示全部楼层
第十六课  IO中断

IO中断于Pin的中断区别,中断里面不能添加延时函数。
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:210
  • 最近打卡:2025-05-05 17:50:21

1

主题

63

回帖

369

积分

中级会员

积分
369
发表于 2024-4-27 17:24:00 | 显示全部楼层

谢谢,非科班出身,只能死磕,共同进步
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:210
  • 最近打卡:2025-05-05 17:50:21

1

主题

63

回帖

369

积分

中级会员

积分
369
发表于 2024-4-27 18:02:20 | 显示全部楼层
本帖最后由 Rain_Personal 于 2024-4-28 18:17 编辑

第十七课  模数转换器ADC

1. ADC原理
截图202404271728136208.jpg

个人理解有点像递归调用,
截图202404271729251811.jpg


使用ADC功能时,Vref引脚的单片机不能悬空,必须接外部参考电压源或者VCC!!! 是不是表明如果不接Vref就会烧毁单片机?


截图202404271736259821.jpg


实验箱的采用的是2.5V基准电压

ADC接口需要设置为高阻输入  相当于初始化ADC

P1M0 = 0x00;                                         //设置P10为高阻输入
P1M1 = 0x01;


ADCTIM = 0X3F;                                        //ADC内部时序
ADCCFG = 0X2F;                                        //数据右对齐,时钟选择位SYSCLK/2/16最慢
ADC_POWER = 1;                                        //打开adc电源



        u16  ADC_Read( u8 no )  // no 表示通道
        {
                u16 adcval;                                                                //adc数值保存变量
                ADC_CONTR &= 0xf0;                                                //清空通道
                ADC_CONTR |= no;                                                //选择通道
                ADC_START = 1;                                                        //开启ADC转化
                _nop_();                                                                //空操作指令    intrins.h
                _nop_();                        
                while(!ADC_FLAG);                                                //等待ADC转换结束
                ADC_FLAG = 0;               
                adcval = (ADC_RES << 8)  + ADC_RESL;        //计算adc的数值  高8位 低8位用两个16进制描述12位的ADC值
                adc_val = adcval;
                return adcval;
        }

通道的选择 其中ADC_CHS表示通道,函数调用需要输入对应参数 0000~0111即0~7
截图202404271753134805.jpg

实验箱中可以通过按键生成ADC值
截图202404271759161300.jpg

SW1~SW16

获取真实电压值的计算方式为

u16 ADC_CAL_Voltage(u16 num)
{
        return num*2.5*1000 /4096; // num取值为0-4096    返回值为0-2500
}



回复 支持 反对

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2025-5-8 02:18 , Processed in 0.147877 second(s), 100 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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