ygyfy 发表于 2024-6-20 21:55:51

第五集 上 主要介绍c语言printf函数,二进制、十进制、十六进制的互相转换

continue 系统级关键字 在keil5中会蓝色显示

在主函数添加程序(while(1)后面):
if(DeviceState != DEVSTATE_CONFIGURED)
    continue;
if (bUsbOutReady)
{
    usb_OUT_done();    //接收应答(固定格式)   
}


printf(" "),引号里面输入字符可以直接输出,比如Hello World!,printf("Hello World!")在本例中可以在收到信息后可以输出Hello World!(选择文本模式)
%.2f中小数点后的2表示保留小数点后两位数
\r\n相当于windows中的回车换行符,如不输入,显示的内容不会换行
学习转义字符
printf(“当前温度:%.2f 当前湿度:%.2f”,11.2,55.2);
进制转换部分看得比较迷糊,可以在科学计算器里面换成程序员模式,hex表示16进制,在里面输入数字可以转换成十进制(点dec那行)和二进制
学会下ASCII字符查找,先将16进制转换成10进制然后再ASCII表中找到对应字符
80h中最后的h表示这是个16进制,0x开头表示他是16进制,0x不参与运算。


ygyfy 发表于 2024-6-22 01:14:43

本帖最后由 ygyfy 于 2024-6-22 01:24 编辑

第五集 下
接上集,继续二进制和16进制的换算,讲的这个表格挺好的,比较容易理解。介绍了加减乘除,取余;与&运算,或|运算,取反~,这几个都是位运算,按照二进制的每一位来进行运算的。
变量:能变化的量。
bit,一位变量,取值范围0和1
unsigned char 无符号字符型变量,8位,取值范围0~255
unsigned int 无符号整型变量,16位系统中,取值范围0~65535
严格说,上面两个取值范围和位数是有操作系统决定的,暂时按照视频中写,下同。
char 取值范围-128~127
int 取值范围-32768~32767
位运算中暂时讲了左移<<

格式字符,在本集学习了:
n.m n表示整数占几行,m表示小数占几行(即保留几位小数);
%d 以十进制整数形式输出;
%f 以单精度浮点型输出;
%u 以十进制无符号整型输出;

转义字符:
\n 换行符;
\r 回车
不是很熟悉,以后应用中可以回来查找冲哥的ppt文件

soma 发表于 2024-6-22 19:20:00

ygyfy 发表于 2024-6-22 01:14
第五集 下
接上集,继续二进制和16进制的换算,讲的这个表格挺好的,比较容易理解。介绍了加减乘除,取余; ...

凌晨还在学习真勤奋

ygyfy 发表于 2024-6-23 01:44:01

第六集 上
主要是delay,do while,while的运用,简单介绍a--和--a的区别


#define MAIN_Fosc 24000000UL//24M 定义一个irc时钟 烧写时应与之相同
主程序之前添加

void delay_ms(u16 ms)
{
        u16 i;
        do
        {
                i=MAIN_Fosc/6000;
                while(--i);
        }while(--ms);
}主程序最后面添加
delay_ms(500);
在程序中输入正确的关键词,关键词会自动用蓝色显示,如不变色,可能有误。
编译保证0错误,有警告也没太大问题
while语句                do while语句
while(条件)         {
{                           功能B
功能A                     }while(条件)
}
while语句先判断条件是否为真,为真则执行下面{}中的语句;do while语句先执行一次{}中的语句,然后才判断条件是否为真,为真则继续执行{}中的语句。
条件中的值非0,结果为真。值为0,则为假



主函数之前定义的变量或者说在主函数外面定义的变量是全局变量,主函数之内定义的变量是局部变量

--在前面个在后面的区别
--a   a先减1,然后再输出运算结果先运算后输出
a--   先输出a的值,然后a再减1       先输出后运算



ygyfy 发表于 2024-6-25 19:25:19

第六集 下
#define 名称 需要定义的内容
名称用英文名或者数字,不要以数字开头,避开关键词,不要与其他函数重名

函数的使用
1函数定义:
返回值 函数名称(入口参数)
{
函数要执行的功能
}
如void   delay_ms(u16 ms)括号内u16为类型,ms是名称
函数的定义可放在前面,也可以放在后面,放在后面的话,要把函数声明放在前面,否侧引用时会出现未定义;多个参数,以逗号分开。

2.函数声明
返回值 函数名称 (入口参数)

3.函数调用
函数名称(入口参数)调用的时候只需要入口参数,不需要类型,只有在函数定义和函数声明的时候才要把int等类型加上
如本例中声明时写int add(int parm1,parm2)
引用时写add(1,2)

建议一个.c文件对应一个.h文件


.h文件中ifndef中if是如果,n是no缩写,def是define缩写,连起来if no define大致意思是,如果没有定义。
endif与ifndef对应。
添加文件路径:
点击魔术棒,选c251,然后选include paths点击该行末尾的...找到对应路径添加进去


添加到工程文件:
双击Source Group,找到文件,双击文件或者点右下角add添加进去
用#include调用头文件

.c文件个人理解为如同前几集中的函数定义,然后在.h文件里面声明,然后再主文件里面调用头文件。

ygyfy 发表于 2024-6-25 21:53:36

作业

#include <stc32g.h>
#define MAIN_Fosc 24000000UL
#defineu16 unsigned int
      
void delay_ms(u16 ms)                //延时函数
{
      u16 i;
      do
      {
                i = MAIN_Fosc/6000;
                while(--i);
      }while(--ms);
}


void main()
{
      WTST = 0;      //设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
      P2M1 = 0x00;   P2M0 = 0x00;                //设置为准双向口
      P20 = 0;                        //亮
      delay_ms(200);
      P20 = 1;                        //灭
      delay_ms(200);
      P20 = 0;                        //亮
      delay_ms(200);
      P20 = 1;                        //灭
      delay_ms(200);
      P20 = 0;                        //亮
      delay_ms(200);
      P20 = 1;                        //灭
      delay_ms(200);

      P20 = 0;                        //亮
      delay_ms(500);
      P20 = 1;                        //灭
      delay_ms(500);
      P20 = 0;                        //亮
      delay_ms(500);
      P20 = 1;                        //灭
      delay_ms(500);
      P20 = 0;                        //亮
      delay_ms(500);
      P20 = 1;                        //灭
      delay_ms(500);
      
      P20 = 0;                        //亮
      delay_ms(200);
      P20 = 1;                        //灭
      delay_ms(200);
      P20 = 0;                        //亮
      delay_ms(200);
      P20 = 1;                        //灭
      delay_ms(200);
      P20 = 0;                        //亮
      delay_ms(200);
      P20 = 1;                        //灭
      delay_ms(200);      
      
      delay_ms(3000);      
      
}      
发现
1.WTST = 0; //设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
不写这行闪烁速度很慢。
2.P2M1 = 0x00; P2M0 = 0x00; //设置为准双向口
不写这行LED直接不亮。

ygyfy 发表于 2024-6-26 22:56:11

第七集 按键点灯 上



本集是前面几集的延伸学习,主要是延时(按键消抖),取反(每次按下按键改变led状态),if……else语句应用

简单介绍按键的作用和外形,以及按键的外围电路构成


此电路中,按键按下时,io口检测到的是低电平,松开是高电平,通过检测其电平变化来判断按键是否按下。



按键按下和松开的瞬间,电压是不稳定的,有一连串的抖动,因此,需要进行按键消抖,也就是做个延时10ms左右。

头文件的引用,多引用不会报错,少引用会报错。

按键消抖及按下点亮led

if(key==0)//判断按键是否按下(图中按下按键电平为0)
{
delay_ms(10);//延时10ms,按键消抖
if(key==0)
{
P40=0;//执行功能,点亮led
}
else//上面条件(key==0)不成立则执行下面语句
{
P40=1;//按键没按下(或松开),熄灭led
}
}

按一次改变一次led的状态依靠取反实现

while(key==0)//按键一直按下则一执行
{
P40=!P40;//取反,每按下一次按键改变一次led灯状态

}

视频末尾简单介绍按键的长按,短按等

ygyfy 发表于 2024-6-28 02:03:11

本帖最后由 ygyfy 于 2024-6-28 15:56 编辑

第七集 按键点灯 下

主要涉及移位,数组
数组:
类型 数组名[元素个数]={值,值……值};

u8 LED_DataTab = { 0XFE,0XFD, 0XFB,0XF7,0XEF,0XDF,0XBF,0X7F};

其中u8,8位无符号整型变量;LED_Data是数组的名字,中括号中的8表示这个数组有八个元素(值),大括号中是数组8个元素的每个值。
数组的引用,数组名称[下标],如LED_Data,LED_Data,LED_Data……LED_Data,注意下标是从0开始而不是1开始,最大下标为数组元素个数减去1,如本例,最大数组下标为7而不是8.

数组的使用:先定义数组,然后引用,如同之前函数先定义,在引用一样

通过改变数组的值或者引用顺序,可以改变led的点亮顺序和方向以及每次点亮led的个数


本集中P6=0XFE会点亮P6.0的灯,依次引用数组元素会依次点亮P6.0到P6.7

因本人暂时没有试验箱,只能用屠龙刀板做实验,编写程序会依次点亮P2.0到P2.7。
屠龙刀也没反正,就简单写个程序,依次点亮P2.7开始往P2.0跑,每次点亮四个,然后再从2.7开始循环吧

#include "COMM/stc.h"                //调用头文件
#include "COMM/usb.h"
#define MAIN_Fosc 24000000UL      //定义主时钟

char *USER_DEVICEDESC = NULL;
char *USER_PRODUCTDESC = NULL;
char *USER_STCISPCMD = "@STCISP#";

void sys_init();      //函数声明
void delay_ms(u16 ms);

void main()                                        //程序开始运行的入口
{
      u8 Led_Data=0xFE;
      int num=4;
      u8 Led_datatab={0XF0,0XE1,0XC3,0X87,0X0F};

      
      sys_init();                              //USB功能+IO口初始化
      usb_init();                              //usb库初始化
      EA = 1;                                        //CPU开放中断,打开总中断。
      
      while(1)                //循环执行
      {
                if( DeviceState != DEVSTATE_CONFIGURED )
                        continue;
                if( bUsbOutReady )                                                               
                {
                        usb_OUT_done();

                }

                        P2=Led_datatab;
                        delay_ms(500);
                        num--;
                        if(num<0)
                        num=4;
      }
}

void sys_init()                //函数定义
{
    WTST = 0;//设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
    EAXFR = 1; //扩展寄存器(XFR)访问使能
    CKCON = 0; //提高访问XRAM速度

      P0M1 = 0x00;   P0M0 = 0x00;   //设置为准双向口
    P1M1 = 0x00;   P1M0 = 0x00;   //设置为准双向口
    P2M1 = 0x00;   P2M0 = 0x00;   //设置为准双向口
    P3M1 = 0x00;   P3M0 = 0x00;   //设置为准双向口
    P4M1 = 0x00;   P4M0 = 0x00;   //设置为准双向口
    P5M1 = 0x00;   P5M0 = 0x00;   //设置为准双向口
    P6M1 = 0x00;   P6M0 = 0x00;   //设置为准双向口
    P7M1 = 0x00;   P7M0 = 0x00;   //设置为准双向口
      

   
    P3M0 &= ~0x03;
    P3M1 |= 0x03;

    //设置USB使用的时钟源
    IRC48MCR = 0x80;    //使能内部48M高速IRC
    while (!(IRC48MCR & 0x01));//等待时钟稳定

    USBCLK = 0x00;      //使用CDC
    USBCON = 0x90;
}

void delay_ms(u16 ms)      //
{
      u16 i;
      do
      {
                i = MAIN_Fosc/6000;
                while(--i);
      }while(--ms);
}



ygyfy 发表于 2024-6-30 03:11:43


第八集 蜂鸣器
蜂鸣器分为有源蜂鸣器和无源蜂鸣器,有源蜂鸣器内部有振荡源,加上合适的电压就响,控制方便,价格较贵,外形特征是后部是背胶。无源蜂鸣器没有振荡源,直接通电不会响,价格便宜,可用于播放音乐,背部可以看到电路板。
本集涉及原来学过的的知识:.c和.h文件的创建,在keil5中添加文件,添加文件路径;函数使用(定义返回值,定义函数名称,入口参数);取反和移位。
涉及新的知识:函数中使用了bit作为变量,其取值范围是0和1.

硬件原理:通过io口电平控制三极管的通断来让蜂鸣器响

P6<<1+1 之前讲的,P6左移一位,然后+1
                       
                       
P6 = ~(1<< (Run_Mode-1)); 本集,MODE先-1,然后左移1位,然后取反

大致逻辑

按按键1开机

自检(蜂鸣一下,所有灯一起闪一下)

按按键2选择功能

蜂鸣一下,灯跟着移动到对应功能点亮

按按键3使对应功能运行

蜂鸣一下,判断是否已运行,运行则锁定不让再选择其他功能,运行的功能持续闪烁

按按键1关机

蜂鸣一下,将所有灯熄灭,清除功能选择和运行状态使其归零,否则下次将可能导致功能紊乱

ygyfy 发表于 2024-6-30 04:11:47

第九集 数码管的静态使用

数码管的本质,是一些LED(发光二极管),按照一定的要求组合在一起,实现显示时间或者字母、图标等功能。正极连在一起的数码管是共阳,负极连在一起的数码管是共阴。


码表写的时候低位在后高位在前。

以8位2进制数,需要点亮的部分其对应io口电平置低电平。

在excel里面将10进制转化成16进制挺好用,输入=dec选择DEX2HEX然后选择要转换的10进制所在的表格然后回车。

根据笔画,选择需要点亮的对应的二进制转化成10进制使其通过对应端口输出对应需要的电平即可。

本集算是之前学过的按键点灯和蜂鸣器章节的拓展,只要理解数码管的本质即可实现本章学习

页: 1 2 [3] 4 5 6
查看完整版本: 冲哥视频 《STC32位8051单片机原理及应用》学习打卡【已送实验箱】