7月6日
粗略复习51(问了学长后,我打算直接看小车视频,遇到不会的再回去看江科大)
51单片机 LED灯共阳 数码管共阴
7月7日
定时器时间计算
[参考(1条消息) 51单片机定时器使用与计算-----day3_单片机定时器定时时间计算_电子笔记的博客-CSDN博客](https://blog.csdn.net/weixin_45518253/article/details/109684096?ops_request_misc=&request_id=8789d3f1560144c1986351b6fe4ae5fb&biz_id=&utm_medium=distribute.pc_search_result.none-task-blog-2allkoosearch~default-2-109684096-null-null.142%5Ev88%5Einsert_down28v1,239%5Ev2%5Einsert_chatgpt&utm_term=51%E8%B6%85%E5%A3%B0%E6%B3%A2%E6%B5%8B%E8%B7%9D&spm=1018.2226.3001.4187)
使用_nop_()需包含intrins.h
超声波复习
距离计算单位问题
参考(1条消息) 51超声波测距简易代码_未寻得的旧梦的博客-CSDN博客
** 最终单位为cm/s**
7月8日
参考视频,购买小车零件(等待收货)
先看一遍小车视频
蓝牙模块 sfr AUXR=0x8e 用定时器2(改成超声波用定时器2,蓝牙用定时器1)程序在最后一个视频
暂时将避障模块放在超声波那里
复习串口通信模块
正反接入
7.9在家休息
7.10在家休息
7月11日
开始装小车
-
问题:操作按照基本正确,但无法烧录(经过林师兄的调试,无结果)
-
问题:小车上电后,动一下就没电
解决:刚开始以为某个地方烧了,但研究后发现是电源接线出接触不良。要拧一下。 -
L298N:使能引脚盖帽拔掉,用最外面的引脚即可
-
问题:其他都没有问题(接线,代码等)但是车轮不动
解决:稳压模块买错了,要5v的
买稳压模块等快递中
7月12日
-
markdown复习
-
51定时器复习(发现我之前写的程序有点问题)加深我对定时器的理解
-
51串口复习
串口是两台设备相互通信的基础。
对于寄存器来说,
我之前对于RI,TI,这两位理解不是很好。
程序都是相对于单片机而言的。要搞清楚主机和从机。
TI,即发送中断请求标志位,当串行发送第8位结束时,由其内部硬件自行置位,即TI=1;所以必须由软件进行复位(TI=0)。
RI,即接收中断请求标志位,当串行接收第8位结束时,自动置位RI=1,同样的必须要求软件复位,即(RI=0)。
所以单片机发送和接收都会触发中断,但发送是主动的,可以不需要中断。而接收是被动的,需要像定一个闹钟一样,这样,单片机接收后做一些操作,我们才能知道单片机已经接收了。
波特率计算
八位自动重装
TL1 = 0xFA; 250 256
TH1 = 0xFA;
每个6us溢出
转化为频率 1/6=0.1666666666666667Mhz
十六分频 0.1666666666666667Mhz/16=0.0104166666666667=10416.66667hz
原9600hz(多少还是有点误差,发送字节时记得加延时函数来防止传输错误)
复习i2c,onewire通信协议
7月13日
(5V稳压快递还没到,先学32)
-
命名规则
-
keil5安装
选择相同的路径即可,这样51和MDK就兼容了
安装插件
安装驱动
(下单买了江科大的STM32)
- 稳压快递到了
小车直行,循迹基本实现(多注意接线和线的固定,防止线松了)
舵机暂时还没动,不清楚啥原因(定时器配置错乱)
避障(红外+超声波+舵机)
蓝牙(没找到SPP那个软件,没进行测试)
蓝牙模块主要时用串口(默认定时器1),与之前的模块有冲突,然后用手机发送指令,串口中断执行指令。
- 小车各个模块基本搞定
7月14日
结构体学习
- 结构声明
struct student{ //类型char name[21]; //姓名int num; //学号float score; //成绩}; //(注意末尾有一个分号)
- 结构体变量
struct student stu1;
//定义结构体变量(类型+变量)-
char name[21];int num;float score;}stu1;
-
结构体访问
stu1.name
采用结构体变量名称.成员名称 -
结构体变量初始化
- 逐个赋值
struct student stu1; strcpy(stu1.name,"李"); stu1.num=18; stu1.score=100;
`` 注意不能直接给数组名赋值,因为数组名是个常量
- 整体赋值
struct student stu1={"李",18,100};
- 使用
void main ( void )
{struct student stu1;scanf("%s%d%d",stu1.name,&stu1.num,&stu1.score); //注意数组名称就可以表示地址printf("姓名: %s\n",stu1.name);printf("年龄: %d\n",stu1.num);printf("分数:%d\n",stu1.score);return 0;
}
结构体变量存储原理
-1)结构体数据成员对齐的意义
内存是以字节为单位编号的,某些硬件平台对特定类型的数据的内存要求从特定的地址开始,如果数据的存放不符合其平台的要求,就会影响到访问效率。所以在内存中各类型的数据按照一定的规则在内存中存放,就是对齐问题。而结构体所占用的内存空间就是每个成员对齐后存放时所占用的字节数之和。
计算机系统对基本数据类型的数据在内存中存放的限制是:这些数据的起始地址的值要求是某个数K的倍数,这就是内存对齐,而这个数 K 就是该数据类型的对齐模数(alignment modulus)。这样做的目的是为了简化处理器与内存之间传输系统的设计,并且能提升读取数据的速度。
结构体对齐不仅包括其各成员的内存对齐(即相对结构体的起始位置),还包括结构体的总长度。
2)结构体大小的计算方法和步骤
i. 将结构体内所有数据成员的长度值相加,记为 sum_a ;
ii. 将各数据成员为了内存对齐,按各自对齐模数而填充的字节数累加到sum_a上,记为sum_b。
对齐模数是 #pragma pack 指定的数值与该数据成员自身长度相比较得到的数值较小者。该数据相对起始位置应该是对齐模数的整数倍。
iii. 将和 sum_b 向结构体模数对齐。
该模数则是 #pragma pack 指定的数值与结构体内最大的基本数据类型成员长度相比较得到的数值较小者。结构体的长度应该是该模数的整数倍。
参考
https://blog.csdn.net/yanggangclcsdn/article/details/49718131
结构体数组
定义
struct student {char name[21];int num;float score;
}stu[5]; //定义一结构数组stu,共有5个元素
赋值
stu[0]=(struct student){"tom",18,100.0};
输出结构体
//结构体数组长度
int length = sizeof (stu)/sizeof (struct student)
//逐个输出结构数组元素
for(int i=0;i<length;i++)
{printf("姓名:%s 学号: %d 成绩: %f\n",stu[i].name,stu[i].num,stu[i].score);
}
结构体与指针
struct student *pstu;
数组名表示数组的首地址,可以直接给地址给指针。而结构变量名称不表示首地址,所以要用&给地址。
即 pstu=&stu1;
访问
(*pstu).name
pstu->name
结构体嵌套
struct birthday{int year;int month;int day;
};
struct student{char name[21];int num;float score;struct birthday birth; //生日
};
结构与函数
结构体的成员作为函数参数
struct student {char name[20];int num;float score;
};
void printnum (int num)
{
printf("num = %d \n",num);
}struct student student0={"tom,10,100"};printnum(student0.num);
结构变量名与可以作为函数参数传递
void printstu(struct student stu)
{stu.num=100; //修改学号printf("%s%d%p",student.name,student.num,&stu);struct student stu0={"tom",18,100};printstu(stu0);printf("%s%d%p",stu0.name.stu0.num,&stu0)
}
- 枚举
定义同类型的多个变量(本质上是int型)
enum DAY //类型名称就是 enum DAY
{MON=1, TUE, WED, THU, FRI, SAT, SUN
};
用typedef关键字将枚举类型定义成别名,并利用该别名进行变量声明
typedef enum workday;
枚举括号内逗号,而结构体括号内是分号;
宏定义#define与类型定义typedef的区别
- 宏定义范围更广(typedef只能给数据类型定义新名字)
- 宏定义新名字在前面;而typedef新名字在后面
- 宏定义最后不用加分号;而typedef需要
- #define u8 unsigned char
- typedef unsigned char u8
参考
https://blog.csdn.net/qq_28576837/article/details/125091771?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522168934073316800188583477%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=168934073316800188583477&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2alltop_positive~default-1-125091771-null-null.142v88insert_down28v1,239v2insert_chatgpt&utm_term=%E6%9E%9A%E4%B8%BE&spm=1018.2226.3001.4187
stm32快递到了,开始学
GPIO(general purpose input output)一般通用输入输出端口
推挽输出
开漏模式
高阻态
参考
https://blog.csdn.net/qq_37703067/article/details/129644535?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522168933997116800185874940%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=168933997116800185874940&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2alltop_positive~default-1-129644535-null-null.142v88insert_down28v1,239v2insert_chatgpt&utm_term=%E6%8E%A8%E6%8C%BD%E8%BE%93%E5%87%BA&spm=1018.2226.3001.4187