找回密码
 立即注册

杰哥的32G12K128学习记录【已送试验箱】

[复制链接]
  • 打卡等级:常住居民III
  • 打卡总天数:130
  • 最近打卡:2025-05-07 18:17:53

13

主题

164

回帖

375

积分

中级会员

积分
375
发表于 2024-8-26 10:07:45 | 显示全部楼层
本帖最后由 阿杰爱学单片机 于 2024-8-26 10:10 编辑

第五集 上(求助贴2)

  在这次的学习中,我们跟着冲哥学习使用C语言中的printf打印输出字符串到串口‘’ 但在这之中我又遇到了问题。

第一个问题,printf不是C语言中的函数吗,怎么就直接运用到单片机上了
第二个问题,按道理来说串口应该做一些处理才能输出数据吧,而视频里,直接就使用printf就能输出字符了这让我非常不解
第三个问题,随后我又去看了下布丁橘子长的代码,发现他写的和冲哥的代码完全是两种,他的代码不仅应用了<stdio.h>的头文件,还重构了pintf的底层代码,还用了定时器,看起来很复杂,冲哥却只加几行代码就实现了,搞不懂
第四个问题,冲哥的视频中,都没有应用<stdio.h>的头文件为啥就可以用pintf了?

QQ图111114444.jpg


回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:135
  • 最近打卡:2024-12-25 10:15:05

47

主题

1350

回帖

8060

积分

荣誉版主

冲哥视频教程和各种开源资料QQ交流群884047237,可群

积分
8060
QQ
发表于 2024-8-26 10:32:56 | 显示全部楼层
第一个问题,printf不是C语言中的函数吗,怎么就直接运用到单片机上了
------这个单片机就是C语言开发的呀,printf是C标准库里的功能,单片机当然也可以调用

第二个问题,按道理来说串口应该做一些处理才能输出数据吧,而视频里,直接就使用printf就能输出字符了这让我非常不解
------视频里调用的是现成的库,在库里面设置好了底层的串口(USB-CDC串口),所以只要初始化之后就可以直接使用了

第三个问题,随后我又去看了下布丁橘子长的代码,发现他写的和冲哥的代码完全是两种,他的代码不仅应用了<stdio.h>的头文件,还重构了pintf的底层代码,还用了定时器,看起来很复杂,冲哥却只加几行代码就实现了,搞不懂
------视频里调用的是现成的库,在库里面设置好了底层的串口(USB-CDC串口),这一节只是最简单的调用,到了后面讲CDC串口的时候会重点讲这个的,这一章只要求学会怎么printf打印数据,不然后面几个章节的内容看不了数据,不好验证

第四个问题,冲哥的视频中,都没有应用<stdio.h>的头文件为啥就可以用pintf了?
------你可以打开底层的.H文件去看看,在别的文件里调用了<stdio.h>的
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:130
  • 最近打卡:2025-05-07 18:17:53

13

主题

164

回帖

375

积分

中级会员

积分
375
发表于 2024-8-26 10:48:50 | 显示全部楼层
我又改了这回更离谱了,我把冲哥的代码和文件(COMM)复制到我的工程,然后发现还是不行,但我试了一下他的工程是没问题的,
但我复制过来就有问题,是不是那里没设置好
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:130
  • 最近打卡:2025-05-07 18:17:53

13

主题

164

回帖

375

积分

中级会员

积分
375
发表于 2024-8-26 10:52:00 | 显示全部楼层
电子DI*** 发表于 2024-8-26 10:32
第一个问题,printf不是C语言中的函数吗,怎么就直接运用到单片机上了
------这个单片机就是C语言开发的呀 ...

我用的是<STC32G.h>我还以为<STC32G.h>和"STC.h"是一样的,回头看了一下确实包含了
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:130
  • 最近打卡:2025-05-07 18:17:53

13

主题

164

回帖

375

积分

中级会员

积分
375
发表于 2024-8-26 10:57:03 | 显示全部楼层
电子DI*** 发表于 2024-8-26 10:32
第一个问题,printf不是C语言中的函数吗,怎么就直接运用到单片机上了
------这个单片机就是C语言开发的呀 ...

我把我的代码复制到他的工程里,屏蔽了它的代码,发现我的代码奇迹般的运行成功,我是不是Keill哪里又设置错了
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:130
  • 最近打卡:2025-05-07 18:17:53

13

主题

164

回帖

375

积分

中级会员

积分
375
发表于 2024-8-26 11:06:05 | 显示全部楼层
阿杰爱*** 发表于 2024-8-26 10:57
我把我的代码复制到他的工程里,屏蔽了它的代码,发现我的代码奇迹般的运行成功,我是不是Keill哪里又设 ...

OK已经解决了,KEIll里面那个memory model 弄错了弄成了XSmall data了,这个是储存方式吗
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:130
  • 最近打卡:2025-05-07 18:17:53

13

主题

164

回帖

375

积分

中级会员

积分
375
发表于 2024-8-26 16:32:33 | 显示全部楼层
本帖最后由 阿杰爱学单片机 于 2024-8-30 14:02 编辑

第五集 下

  本次跟着冲哥学习了c语言中的各种运算,包括+-*/%&|~,加减乘除按位与按位或,还有取反的用法,这么一说想起之前的一个问题,一直没有研究就是  !和~有啥区别 ,有时候用这两个都可以。
  还学习了进制的转换,这里给大家一个小技巧2进制转16进制的一个小技巧,就是8421码,具体可以去搜一下,二进制一般八位数表示16进制两位数,举个例子
1010 1011
8421 8421
从高位到低位一 一对应只要是零的地方就去掉对应的8421码
1010 1011
8 2   8  21
就比如这样,然后每组相加最后得到结果
1010 1011
    10    11
每四个二进制对应一个16进制数的一位
然后10对应16进制A,11对应16进制B    16进制数排序(123456789ABCDEF)
最后得出的结果就是16进制数的0xAB
具体方法可以去搜一下。

这次代码总体没问题,输出英文,数字没啥问题,但是输出中文就乱码了,又让人头疼了,有大佬指点下吗
问题已经解决,在串口助手,选择,串口设置,UTF8编码格式
QQ图片112112.jpg



  

回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:130
  • 最近打卡:2025-05-07 18:17:53

13

主题

164

回帖

375

积分

中级会员

积分
375
发表于 2024-8-26 19:18:16 | 显示全部楼层
本帖最后由 阿杰爱学单片机 于 2024-8-26 19:43 编辑

第6集 学习记录

  这集讲到了

  delay 函数的书写
以及如何使用delay函数实现LED闪烁,原理就是通过执行一些循环的操作,让程序卡在某个地点,达到延时的效果,缺点显而易见,影响程序的执行速度。


宏定义#define
可以理解为就是给一个变量或者寄存器取个新名字,名字写在左边,右边写变量或者.....比如
#define  aa   1234
优点就是当需要改变某个值的时候直接修改宏定义就好,使代码更加高效

  typdef的应用
以我的理解,就是给,变量类型名取新名字,他和宏定义的区别是他只能给变量类型取名字
而宏定义,就不管那么多了。
  假如一个变量类型的名字太长了,可以给他取一个新名字,便于书写,也便于自己理解。使用方法
  typdef  unsigned char u8;
  typdef  unsigned int u16;


  函数的书写和返回值和参数比如
void XX()空返回值类型
{}
int XX()int型返回值类型,有返回值的函数还需要写上return
{return;}
void XX(char XX)这里的char是形参
{}

  讲到了模块化编程,
  可以使代码更加精简,不容易出错,有利于团队合作,需要创建一个c文件还有一个h文件。

  c文件里写上函数和头文件
  .h文件里写上函数声明  如下

  #ifndef __XXX_H__
  #define __XXX_H__
  
  void XXX(char XXX);
  float XXX (int XXX);

  #endif

如果新建的文件是在文件夹里还要声明以下路径才可以应用
引用时只需调用对应的头文件即可




最后冲哥布置了一个作业,我是这么写的没有问题
void main(void)      //主函数(程序从这里执行)
{
        SYS_Init();                                        // STC32初始化
        MyUSB_Init();                                //USB初始化
        GPIO_Init();                                //IO口初始化
        while(1)
        {
                if( DeviceState != DEVSTATE_CONFIGURED )         //
                        continue;
                if( bUsbOutReady )                                                               
                {
                        usb_OUT_done();
                }

                for(i=0;i<6;i++)
                {
                        if(i<3)
                        {
                                P20=0;
                                delay_ms(200);
                                P20=1;
                                delay_ms(200);
                        }
                        else
                        {
                                P20=0;
                                delay_ms(800);
                                P20=1;
                                delay_ms(800);
                        }
                }
        }
}

回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:327
  • 最近打卡:2025-05-08 13:27:17
已绑定手机

21

主题

487

回帖

1063

积分

金牌会员

积分
1063
发表于 2024-8-27 08:15:29 | 显示全部楼层
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:130
  • 最近打卡:2025-05-07 18:17:53

13

主题

164

回帖

375

积分

中级会员

积分
375
发表于 2024-8-27 09:56:21 | 显示全部楼层
本帖最后由 阿杰爱学单片机 于 2024-8-27 10:40 编辑

第七集 学习记录

  按键的应用,按键在生活中极为广泛是人与计算机进行交互的媒介,就比如电脑上的键盘
但在实际引用中,因为按键是机械元件,开关都会有抖动,如下图所示,此时我们就要滤除这些不必要的抖动,以免对程序效果产生影响。

按键的消抖分为软件消抖和硬件消抖
软件消抖的本质就是不读取抖动的电平,加延时耗过去。
而硬件消抖对硬件要求太高,会很麻烦,实际应用不多。
QQ图片7集1.jpg
在实验中我发现冲哥的代码有一些小瑕疵,冲哥的代码只对按键按下去除抖动,而按键松开没有进行延时去抖。
就导致了有时按键松开会执行两次按键按下的语句,造成一点小影响,虽然影响不大,到我觉得保险起见,按键松手时也加入延时代码,使按键检测更准确
就如下所示这样书写。

if(Key1 == 0)                                //如果按键1按下
{
        delay_ms(10);                        //延时消抖
        while(Key1 ==  0);//如果按键1按下死循环,等待松手
        delay_ms(10);                        //延时消抖
        LED1=!LED1;                        //LED1状态取反
        printf("按键1按下LED取反%\r\n");
}


串口打印小细节,不能显示中文的改一下串口设置,打开串口,点击更多设置,点击编码格式,选择UTF8就可以打印中文了
QQ图片7集.jpg

再提一点,按键控制LED左移其实有个更简单的方法
前面不是学过<<,>>,~,左移右移还有取反的运算符吗,把这些应用在一起如下
u8 i;
if(Key==0)
{
    delay_ms(10);
    while(Key==0);
    delay_ms(10);
    P2=~(0x01<<++i);

    if(i==9)i=1;
}

这句代码啥意思呢,意思就是,按键按下i++;0x80左移i位,简化一下就是按键按下几次0x01就移几位,
那0x01是啥呢,0x01换算成2进制就是0000 0001,又因为左移会把高位忽略,低位补0,所以效果就是
0000 0001
0000 0010
0000 0100
0000 1000
0001 0000.......

我们发现这个一是一只向左移的,那如果用这个一点亮LED那不就是流水灯的效果了吗。
但是我们知道开发板上的LED都是接低电平才会点亮也就是0,那用这个代码不全反了啊
这时候我们只用~这个符号,取反一下,0就变成1,1就变成0,程序就对了,最后再把这个值赋值给P2口就可以了

至于那个 if(i==9)i=1;是防止越界的,这个u8 i;是一个无符号char型数据,需要定义为全局变量,也就是写在void main上面。

这就是我这节课的感悟






4-2按键点亮LED.zip

110 KB, 下载次数: 59

回复 支持 反对

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2025-5-9 09:41 , Processed in 0.143038 second(s), 111 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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