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进制使其通过对应端口输出对应需要的电平即可。
本集算是之前学过的按键点灯和蜂鸣器章节的拓展,只要理解数码管的本质即可实现本章学习