C语言位移、不同长度赋值操作

移位问题

向下函数传入0x00800000和0x00400000分别返回什么?

这还用想,当然返回原值了。然而实际却是返回了0xff800000和0x00400000

为什么0x00800000会返回0xff800000,而0x00400000返回了原值?

先看程序运行过程,首先temp先左移了八位,变成0x80000000,这是没有问题的,再右移八位后却变成了0xff800000。这是因为c语言对无符号类型数据的移位均为空位补零,但是对于有符号类型的右移却根据最高位决定,最高位为1则补1,反之则补零,所以0x00800000变换为0xff800000,而0x00400000返回原数值,但将数据类型改为无符号时则无此规律。

不同类型赋值问题

已知cannle为u32,p_Temp为s32 分析下列赋值过程

首先u32和s32长度等长,区别在于最高位是否有符号位,这种赋值二进制数值不变,但是在打印时候按不同类型解析。

其次,将长值赋值给短值,截取低位,然后再赋给短值(即丢弃长值中高于短值最高位的所有值)

其实上述过程只是将int 32类型拆分开存储。发送给上位机后,上位机可将其视为一个int32数据。

赋值类型补充

整数与整数之间
短值赋给长值 短整数直接高位补0
两个无符号数据 短整数符号拓展
两个有符号类型
一个有符号,一个无符号 短整数先进行位数拓展,过程保持数为不变,然后按长整数的数据类型解析数据

整数与浮点数之间

浮点数转整型

截取整数部分

整型转浮点型

小数部分为零,整数部分不变

double & float

double->float

丢失数据精度

float->double

不丢失精度

IKBC C104加灯

之前买的机械键盘没带背光,无奈盲打不熟练,晚上码字经常出错,果断决定加灯

拆开键盘发现C104的PCB上预留了灯位,就是没焊,也没有限流电阻。特么右上角还有四个空轴位,特么不就是F108的阉割版么?接上示波器发现特么居然还有PWM信号输出,买包LED直接焊上就是了

预留灯位

PWM驱动信号

准备材料如下:LED一包(注意正向压降、导通电流),电池(测试LED)、焊锡、吸锡器、螺丝刀、拔键器、焊锡膏、松香、镊子、斜口钳、烙铁。(其实一半都没用上

工具全家福

注意烙铁选功率较大的或者焊台,敷铜板导热快容易让烙铁温度不够。

拆开,加灯,卡口设计,用卡片撬开。注意焊的时候LED正负极以及引脚短路问题,建议焊一排试一排。

焊完时

焊好装回去就是

装好后效果

背光控制快捷键
|Fn+1|全 亮|
|—|:—-:|
|Fn+2|贪 吃 蛇|
|Fn+3|按 下 按 键 点 亮|
|Fn+4| 涟 漪 |
|Fn+5|两 侧 律 动|
|Fn+6|全 键 盘 呼 吸 灯|
|Fn+7|高亮Esc Q W E R ↑↓←→|
|Fn+8|高 亮 部 分 键|
|Fn+↑|亮 度 +|
|Fn+↓|亮 度 -|
|Fn+←|速 度 +|
|Fn+→|速 度 -|

MLX90614 红外测温模块使用(待续

非接触式红外测温模块,贵的一批屌照

管脚定义

MLX90614管脚定义

就电源线和IIC一共四根线,接线简单。

RAM和EEPROM

32*16bitEEPROM,部分可写入,所有均可读取。0x04可设置物体发射率

即物理发射率取值四舍五入后最接近物体的值,默认为1(即0xFFFF).写入时需要先清零再写入

32*16bitRAM 部分可读,Ta为环境温度,Tobj1为目标温度,Tobj2在部分型号中不支持,值和Ta一致

温度干扰与补偿

只有当传感器在热平衡且恒温状态下测得的温度才是准确的,需要注意旁边是否有热源(电路发热、被测物体过近),而我这里使用的MLX90614DCI可以设置内部测量热梯度并补偿测量的温度,降低干扰。(老老实实远离热源

测温的准确性依赖于VDD,VDD对环境温度和物体温度的典型依赖性为0.6°C / V。

Ta对VDD的依赖性(实际To和Ta一致)

由于出厂时校准时VDD=3V,则为了补偿该误差,我们测量电源电压,并通过应用以下公式补偿结果:

测量角度影响测量温度

几种规格的对应视野角度

MLX90614DCI对应视野的角度值与灵敏度

休眠

可通过设置高低温实现模块的睡眠以节省功耗,计算公式如下

分析空调遥控器编码

上一步中获取了遥控器的红外数据,接下来就需要解析了

观察这126组数据,显然72组数据后的数据电平时钟不变,时间也是满的(9637us)。说明该遥控器数据位共72位。

开机位

接下来用控制变量法获取数据解析,首先是开关机位。分别获得 制冷 25度 自动风 摆风 下的开关机码。建议将打印出来的数据导入excel分析比较方便。将前后电平时间相减,差值小于100的认为是系统误差,大于的认为是数据差。很明显第9位和65位数据差值大于1000 。二者应该只有一个位控制开关机,剩下一个数据区别应该为检验和区别,正常人都会把校验和放在最后,所以大胆预测第九位控制开关机 ,65位及附近数据为检验位。

数据格式

上面推算出来了开机位,注意数据格式 大胆猜测 起始信号为4100us的高电平和450us左右的低电平组成 数据信号的第二个电平为0 且时间为450us左右 ,而第一个电平为高电平时间为420us或1550us,对应的应该为数据0 和1 (关于这里的推测,联系上面的开机位,正常人都会把开机设为1,关机设为0),这样大致的数据格式推测出来了,可能有错误,继续用控制变量法获取数据分析,有错再改。

温度控制位

分别采集 开机 制冷 自动风 摆风 前提下 25度和26度的数据,发现有15 16两位 30 31位 以及65位前后不一样,首先可以肯定的是上面的开关机位推断正确,但是仍然看不出来温度变化规律。

25和26对比

大胆一点,干脆把温度调到最低看,特么的,怎么还是那三处不一样。没办法,只能带进去假设演算了。18度和25度第一个区别就是13 15 16 不一样,将数据按上一步推测的换成0或1,可得18度时为0010,25度为1001. 加减一下可以发现:25-18==7==1001-0010 ;这样规律很可能是 temperature - 18 = n - 0010 将26度的数据带入演算,推断成立。该遥控器支持最大温度为32度,哎,四位数最多到31,需要5bit。大胆再猜下12-16 5bit都是控制温度的,32度时为10000. 控制变量将温度设置为32度,发现上述推断成立。

注意28-32位数据和温度有关,但是没看出来具体关联,可能是某类校验,先跳过

18和25度对比

模式控制位

直接将上述模式切换为送风模式,发现只有2-16bit 上数据为00001有不同,特么怎么又跑到温控位了?但是18度时为00010,下面确实有一位没用,可能送风模式比较特殊,直接用温控位代替了。

继续分析其他模式,将模式切换为制热模式,发现这次变的地方太多了,等下再继续分析模式

风速控制位

分别获取 自动模式 24 不扫风下的强中低三种风速

发现55 56两位区别,弱风为01 中为10 强风为11 该遥控器还有一个自动风,应该为00,将00带入之前开机位测试的码型中,结论成立。

摆风控制

同理可得41位控制摆风

风向控制

45位为方向控制位,该位使能后摆风失能,导风板切换方向一次

起始码和地址码

经过上述分析过程,堆积样本码数量足够多了,仔细观察前九位,数据完全一样。第一位格式较特殊,起始码推断应该没问题。再往后八位:01010101,数据完全一样,推断大概率可能为地址码

数显控制位

46-48为数显控制位,000保持当前 111切换状态

超静控制位

62位为超静控制位,1:使能超静模式

定时控制位

多次采集对比发现 11 36-40 57 58都和时间有关联

11位较为明显,控制定时功能是否开启,为1时开启

36-40位控制定时时间,此部分较为特殊,当t<=5h时,该部分值为2t。当t>5 h时,数据为1010+(t-5h)。

57 58两位控制定时状态 ,具体不清楚

该功能用不上,定时时间选择太小,还不如用单片机定时器直接定时方便(逃

模式控制位

前面已经分析一半多的码了,继续分析模式,依次切换模式尝试(自动、送风模式下温度无法控制,分析时排出温度位和温度相关位(12-16,28-32))

50-52位控制模式,自动(000)->制冷(001)->除湿(010)->送风(011)->制热(100).

值得注意的是,此时送风模式下得到的温度值是24(01000),这和之前温度分析不一样???然后我去翻了之前保留的数据,发现温度值是24,而不是之前写的00001???

睡眠控制位

19位为睡眠控制位,为1使能睡眠功能

先睡觉,起来再写,狗命要紧

ESP32配置RMT接收功能

懒癌晚期,一个月没更了(逃

一 什么是RMT?能干啥?

RMT(Remote Control)即红外遥控,通过红外传输数据。学单片机的时候,不管是51还是stm32,肯定有个红外遥控。而且做得都是接收数据解析,想要控制空调之类的家电要干的事居多

二 首先是怎么通过红外传输数据

数字信号->模拟信号->红外光线->模拟信号->数字信号

主要的工作就是把数字信号调制成红外信号再将红外信号解调成数字信号。最简单的当然是直接把灯亮灭当0/1,但是如何排除干扰项呢?显然这是不行的。一般而言,红外传输是先把数据转化为NEC格式的编码或者PPM编码,之后再将数据加载到载波信号(一般为38KHz)上完成调制过程。

调制过程

三 具体的API调用

信号调制过程可以使用定时器+PWM信号完成,本憨批一开始就是这么做的…后来发现乐鑫的ESP32提供了RMT功能的API:官方API参考

初始化

通过初始化结构体 rmt_config_t ,再调用函数_rmt_config(_)和_rmt_driver_install()_完成配置,需要注意的是esp32默认的内存块只能存下63bit的数据,空调这些绝对不是什么省油的灯,需要将mem_block_num设置为2。126应该够大多数场景用了。

红外接收初始化函数

接下来是数据的解析,读取缓存区并将数据打印出来。缓存的数据是保存在rmt_item32_t结构体中 ,该结构体主要成员为level0,duration0,level1,duration1.即两组电平、时间。

打印出来的数据

看到打印出来的数据后需要自行解析了

树莓派部署Wordpress博客

首先安装Apache

1
sudo apt install apache2 -y

安装完成可以在localhost打开,如果是无桌面版的,同一局域网的设备直接访问树莓派ip地址。安装成功则可以在浏览器内看到下列内容

接下来是安装数据库,第一个坑来了,很多老教程是装MySQL,不好意思,新树莓派系统木得,需要换成MriaDB

1
sudo apt-get install mariadb-server 

中间问你装不装,填个y,回车。完成后通过下个命令连接mriaDB

1
sudo mysql 

出现下图即为成功连接到MariaDB

接着需要给root用户修改密码(自行替换password)

1
2
3
4
5
use mysql; 
UPDATE user SET password=password('password') WHERE user='root';
UPDATE user SET plugin='mysql_native_password' WHERE user = 'root';
flush privileges;
exit

然后重启服务

1
sudo systemctl restart mariadb 

之后再新建wordpress的数据库,首先命令行运行

1
sudo mysql -uroot -p

接着输入之前设置的数据库密码(password),进入后创建新数据库,注意后面的分号,数据库名也可自行设置

1
create database wordpress;

接着把数据库权限交给root用户,password为数据库密码

1
GRANT ALL PRIVILEGES ON wordpress.* TO 'root'@'localhost' IDENTIFIED BY 'password';

还需要刷新数据库权限

1
FLUSH PRIVILEGES;

安装php和mysql的插件

1
sudo apt-get install php php-mysql -y

之后进入 /var/www/html目录,删掉index.html文件,再新建一个index.php

1
2
3
cd /var/www/html
sudo rm index.html
sudo nano index.php

在index.php文件中写入

1
<?php phpinfo(); ?>

按ctrl+O,再回车,再ctrl+x退出。完成后浏览器刷新页面,页面变成下面这样

这样拍黄片 php就装好了,下面部署wordpress。下载安装包然后解压到/var/www/html目录,由于你懂的原因,直接用树莓派下载太慢,建议用其它设备科学上网下载后再传到树莓派,这里用的是FileZilla,注意需要给文件夹权限否则传输失败,注意主机前的sftp://不可丢

添加权限命令:

1
sudo chomd 777 /var/www/html

完成后浏览器刷新页面,出现下图页面,点击现在开始

数据库名填入之前建立的数据库名,数据库用户名,数据库密码,后面两项不要动,然后提交

后面按照提示设置即可

这样基于wordpress的博客就建立好了,这个时候内网可以访问,如果需要外网访问的话自行搜索“内网穿透”

参考链接:如何在树莓派上搭建 WordPress

关于在树莓派上不能安装MySql

Proteus制作元件

首先,fuck c**n上的复读机

proteus仿真时,在找74ls183芯片时发现,芯片预览左上角提示没有模型,这样的芯片是没法仿真的,仿真直接报错

作业指名道姓要用proteus,换软件仿真是不可能的了,只能自己造轮,自己来画了。

首先把元件画出来,当然,库里有的但是没有仿真模型的可以跳过这一步。

首先是二维绘图模式画出元件形状,见1。之后在管脚模式添加管脚,和AD一样注意十字对外,引脚有普通引脚(DEFAULT)、低电平有效引脚(INVERT)、上升沿有效的时钟输入引脚(POSCLK)、下降沿有效的时钟输入引脚(NEGCLK)、短引脚(SHORT)、总线(BUS)等6种形式,放上引脚后注意设置

注意设置管脚属性,1:管脚名;2:管脚标号;3管脚是否隐藏,取消勾选隐藏,默认勾选;4选择引脚属性

接下来就是元件入库,大方框覆盖整个绘画的元件,右击选择制作元件,如果是库里面直接拖出来的直接右击元件->制作元件,后方步骤两者完全一样

设置元件名和标号前缀,然后下一步

选择封装,随便选吧,反正我也不画pcb

然后新建,选择MODEFILE,之后一路下一步,完成。

将上一步制作好的元件,右击编辑属性,勾选下方附加层次,然后确定即可。

这时候再右击元件就会有进入子图选项,右击进入,然后画出内部电路,注意输入输出的引脚为终端的input output,管脚标号必须与父图一样,如果元件有隐藏的电源脚需加上电源。

然后右击选中退出到父图

这时候可以仿真测试元件功能了

此时可以直接复制粘贴使用,忽略下方步骤

……………………..懒得写了,有空再补

参考:PROTEUS的元器件及模型制作

芯片内核由@༺雨月·听枫༻ ꧂绘制

DS18B20管脚该怎么看?

一说测温模块,首先想到的就是大名鼎鼎的DS18B20,只需两根电源线和一根信号线就行,芯片主要有三种封装:三条腿的TO-92、六腿的TSOC、八条腿的SOIC-8_150mil。

主要的三种封装

后面两种好说,问题在于TO-92,自己焊万用板或PCB库时就要区分引脚,DQ在中间不用说,but,到底哪个是VCC?哪个是GND?

这还不简单?看图说话,曲面对着自己,从左到右依次GND、DQ、VCC。于是我便烧了个18B20祭天了……….

难道datasheet里是错的?紧接着我瞅到了这么个单词

底部视角……

特么图就不能画成下面这样的吗?

图片来源:TO-92-Wikipedia

树莓派开箱配置

先点亮再说

首先需要给树莓派装系统,需要系统镜像和镜像烧录工具。官方镜像下载,官方提供了三个版本的镜像:无桌面版(Lite)、桌面版和全家桶版(逃 版本按需选择。镜像烧录工具我选Etcher,其它的也行

打开Etcher,选择好镜像和磁盘然后点Flash!烧写开始,注意中间弹出的格式化叉掉,否则导致镜像烧入失败

烧写

烧写完成

有屏幕的同学可以直接把tf卡插上树莓派开机了。当然,穷逼我没有屏幕, 只能用ssh代替了,打开tf卡,在boot目录新建文本文件,重命名为ssh(删除文件拓展名,无法修改文件拓展名的请在文件管理中设置显示拓展名)

然后把TF卡插入树莓派,用网线连接路由器,擦腚,楷机,轻松点亮。这时候可以在路由器的管理页面看到树莓派的内网地址了。接下来需要用到ssh连接的工具,我用的是putty,输入ip地址连接。

在弹出的弹窗选择是,输入账号密码登陆(LINUX环境下不显示密码,但是可以回车删除等操作)默认账号:pi 密码:raspberry

登陆成功

接下来就开始树莓派的配置了

首先换源,由于某些你懂的原因,国外源又慢又容易断,所以换成国内的镜像源。在换源之前一定要确认系统版本,镜像下载的时候会有说明,没注意也不要紧,键入下面的命令查看系统信息

1
lsb_release -a 

比如这里是buster,之前很多教程是stretch,导致换源失败,然后输入

1
sudo nano /etc/apt/sources.list

在第一行开头加一个#,把源拷贝到最后一行之后(这里用清华源,注意中间的系统版本),如图中的效果:

1
2
deb http://mirrors.tuna.tsinghua.edu.cn/raspbian/raspbian/ buster main contrib non-free rpi
deb-src http://mirrors.tuna.tsinghua.edu.cn/raspbian/raspbian/ buster main contrib non-free rpi

先按键盘上的ctrl+o,再按回车保存,再按ctrl+x退出nano编辑器回到命令行界面。再输入以下命令更新到清华大学镜像源最新的软件列表。

1
sudo apt-get update 

更新好后给pip换源

1
2
3
sudo mkdir ~/.pip
ls .pip
sudo nano pip.conf

在打开的文件中输入以下内容:

1
2
3
4
5
6
7
8
[global]
timeout = 10
index-url = http://mirrors.aliyun.com/pypi/simple/
extra-index-url= http://pypi.douban.com/simple/
[install]
trusted-host=
mirrors.aliyun.com
pypi.douban.com

先按键盘上的ctrl+o,再按回车保存,再按ctrl+x退出nano编辑器回到命令行界面。

接下来是树莓派内部设置

输入下列命令进入:

1
sudo raspi-config

第一行是修改密码,不解释 主要第四行修改地区,回车进入

Localisation Options

第一行:Change Locale 选择所在国家,让光标指在zh_CN.UTF-8 UTF-8前面(最下面),先按空格,再按回车,然后到如下界面,选zh_CN.UTF-8回车

再设置第二项:地区 时区选择亚洲 上海

最后设置wifi地区为CN_China

接着到第五大项 Interfacing Options

按需要打开,比如需要远程图形界面的打开vnc。回到主界面选择下方的finsh,如果问是否需要重启,不需要,还没设置完呢

安装中文字体和中文输入法fcitx及Google拼音输入法,注意中途会问你,直接输入y回车

1
2
sudo apt-get install fonts-wqy-zenhei
sudo apt-get install fcitx fcitx-googlepinyin fcitx-module-cloudpinyin fcitx-sunpinyin

完成后重启,这样就配置完成了

1
sudo reboot

参考:

清华源

一劳永逸配置树莓派

树莓派4B换清华源并更换系统源(Raspbian-buster系统)

使用PuTTY登录到树莓派

stm32连接到阿里云——MQTT协议移植

  首先勾选MQTTPacket以将包添加至工程 (没有安装的->MDK拓展包下载)
接下来需要封装四个函数 (我用ESP8266实现TCP连接,请酌情更改):

int transport_sendPacketBuffer(unsigned char``* buf, int buflen);

TCP协议发送数据

int transport_getdata(unsigned char``* buf, int count);

获取TCP接收到的数据(如果不用分析接收到的数据可以不管)

int transport_open(``void``);

打开网络接口(建立一个TCP连接)

int transport_close(``void``);

关闭网络接口

接下来就是这些函数调用了,库中调用的函数都在MQTTPacket.h文件中

构造连接报文发送函数

构造订阅函数

消息发布函数

接下来在你的主函数中调用这些函数:连接到服务器->发送连接报文->订阅->……

此时可以看看阿里云物联网控制台有没有显示产品在线,不在线请检查上述步骤

MCU和云连接已经完成了,接下来就是数据收发

首先需要在云端建立显示的数据模型

注意读写类型选择读写,选择只读的话后面没法让云端下发设置该数据

接下来就是单片机调用消息发布函数向属性上报topic发消息(如果没有说明产品建的就不对,重新建产品)

发送:{“method”:”thing.event.property.post”,”id”:”demo”,”params”:{“temperature”:36},”version”:”1.0.0”}

主要修改id和后面的标识符和标识符对应的数据。发完之后便可在云端看到数据状态(图后面补)

如果想修改发送内容可以使用cjson的方式创建json,当然也可以用sprintf()构造这个字符串。

接下来是数据下发,首先需要订阅属性设置topic,