粤嵌实训(笔记)

2023-11-02

目录

1. LCD换自己喜欢的颜色

 2. LCD换个图案

 3. LCD换张图片

4.网线登录

ifconfig eth0 192.168.5.9

5.触屏电子相册

6.网络编程(TCP通信)

 7.网络编程(UDP通信)

8.开发板串口通信MCU(32或Zigbee节点)

9.EDP接入onenet

10.MQTT协议接入onenet

 11.ZIGBEE发送数据,由6818开发板接收后发送到ONENET


说实话,对于这个粤嵌的实训,真的有很多想吐槽的地方,以下就是粤嵌给的一块板子,屏幕已经碎了,只有一根串口线(甚至是RS232,tm的)和一根DC电源(可能是为了省成本,要我就整个TYPEC供电了),它甚至一条MIRCOusb都不给(接OTG,后来我发现adb传输用不了,可能是这块板子OTG口需要特定的驱动,是的,我没资料),网线也没给,tftp,nfs都没法用,后面发现它竟然是用板载的一个rx工具(当时真是知识盲区),对比我用的一块全志的T113的板子,这块板子真的寄。

 吐槽完就进入正题吧,就是关于整个实训的各个实验:

1. LCD换自己喜欢的颜色

对于传输文件,我这里就统一用TFTP传输了

环境配置过程:

1.在windows环境下创建一个share文件,就用来存需要传到开发板的文件。

 2.关掉防火墙(记得把那些360之类的也关了,下面的是防火墙关闭工具)

链接:https://pan.baidu.com/s/1R5ycBw-_kbUw-jruMJyZmQ 
提取码:1234 

3.TFTP工具配置

链接:https://pan.baidu.com/s/18gele0YKJ_-J2cbJhg-QuQ 
提取码:1234 

 就改这两个,一个是share文件夹的路径,一个是本机的ip

4.把开发板IP改成与本机IP同一网段(因为我本机IP是192.168.5.10,开发板就改成192.168.5.9)

ifconfig eth0 192.168.5.9

 5.尝试ping通本机IP

6.TFTP传输

 我在share文件夹下放了一张BMP格式的图片

 tftp 192.168.5.10 -g -r func.bmp

参数的详情见这篇博客 Linux命令之tftp常用参数说明_小小小羊羊羊的博客-CSDN博客_tftp参数这玩意主要是快啊,比rx快太多了,如果你还是没配出来,那建议参考韦东山老师的配置双网卡的教程走一遍,其实我在玩粤嵌这块板子前是先去玩了T113的开发板,试着走驱动开发方向,但没办法,既然学校强制学习应用开发,那就来吧!(鸡汤)

 然后还是正题,就是显示个喜欢的颜色,很简单哈。

代码贴出来,扔到ubuntu拿交叉编译工具链跑就行

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

//ssize_t write(int fd, const void *buf, size_t count);
//int open(const char *pathname, int flags);

int main()
{
	//1.打开屏幕
	int fd=0; //接受open的返回值 
	fd=open("/dev/fb0", O_RDWR);
	if(fd==-1) //做错误判断
	{
		perror("open hello.c fail");
	}

	//2.写入颜色数据
	int w_ret=0;
	int i=0;
	int j=0;
	unsigned int color[480][800]={0};
	
	for(i=0;i<480;i++)
	{
		for(j=0;j<800;j++)
		{
			color[i][j]=0xff0000; //红色 
		}
		
	}

	w_ret=write(fd, color, 480*800*4);
	if(w_ret==-1)//做错误判断
	{
		perror("write fail");
	}
	
	//3.关闭文件
	close(fd);
}

arm-linux-gnueabi-gcc -o LCD LCD.c 

 因为用的是自己的编译环境就直接搞了,编译出来的程序文件已经框出来了。

TFTP传输进去开发板,然后添加运行权限运行。

tftp 192.168.5.10 -g -r LCD1
chmod 777 LCD1
./LCD1

 代码效果如下,实在有点简单,代码就不改了。

 2. LCD换个图案

代码贴出来,操作也是和上面那个实验类似。

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

//ssize_t write(int fd, const void *buf, size_t count);
//int open(const char *pathname, int flags);

int main()
{
	//1.打开屏幕
	int fd=0; //接受open的返回值 
	fd=open("/dev/fb0", O_RDWR);
	if(fd==-1) //做错误判断
	{
		perror("open hello.c fail");
	}

	//2.写入颜色数据
	int w_ret=0;
	int i=0;
	int j=0;
	unsigned int color[480][800]={0};
	
	for(i=0;i<480;i++)
	{
		for(j=0;j<800;j++)
		{
			if((j-400)*(j-400)+(i-240)*(i-240)<=200*200) //(x-x0)*(x-x0) + (y-y0)*(y-y0) =r*r
			{
				color[i][j]=0xff0000; //红色 
			}
			else
			{
				color[i][j]=0x000000; //黑色 
			}
		}
		
	}


	w_ret=write(fd, color, 480*800*4);
	if(w_ret==-1)//做错误判断
	{
		perror("write fail");
	}
	
	//3.关闭文件
	close(fd);
}

arm-linux-gnueabi-gcc -o LCD2 LCD.c

 tftp 192.168.5.10 -g -r LCD2
chmod 777 LCD2
./LCD2

 

效果如上,因为前面的三个LCD实验比较简单,过得快一点了,后面的网络编程才是重头戏 

 3. LCD换张图片

代码贴在这里,图片用的是我在实验一用TFTP传输过去的那张,像素为800*480,必须为BMP格式,且必须命名(func.bmp)图片不是我做的,虽然我会,但我不想自己整一张了,就沿用别人发的图片吧

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <unistd.h>
#include <sys/types.h>
#include <unistd.h>

//off_t lseek(int fd, off_t offset, int whence);
//ssize_t read(int fd, void *buf, size_t count);
//ssize_t write(int fd, const void *buf, size_t count);
//int open(const char *pathname, int flags);


int main()
{
	//1.打开屏幕
	int fd=0; //接受open的返回值 
	fd=open("/dev/fb0", O_RDWR);
	if(fd==-1) //做错误判断
	{
		perror("open fb0 fail");
	}
	//打开图片
	int bmp_fd=0; //接受open的返回值 
	bmp_fd=open("./func.bmp", O_RDWR);
	if(bmp_fd==-1) //做错误判断
	{
		perror("open func.bmp fail");
	}
	
	
	//2.偏移54字节
	lseek(bmp_fd,54,SEEK_SET);

	//3.读取像素数据 800*480
	unsigned char bmp[800*480*3]={0};
	
	read(bmp_fd,bmp,sizeof(bmp));
	//4.数据处理
/*
bmp[0]--B
bmp[1]--G
bmp[2]--R
bmp[3]--B
....
lcd[0]=bmp[0] | bmp[1]<<8 | bmp[2]<<16;
lcd[1]=bmp[3] | bmp[4]<<8 | bmp[5]<<16;
lcd[2]=bmp[6] | bmp[7]<<8 | bmp[8]<<16;
*/	
	unsigned int lcd[800*480]={0};
	int i=0;
	int j=0;
	for(i=0;i<800*480;i++)
	{
		lcd[i]=bmp[3*i] | bmp[3*i+1]<<8 | bmp[3*i+2]<<16;
	}

	//5.写入屏幕
	int w_ret=0;
	w_ret=write(fd, lcd, sizeof(lcd));
	if(w_ret==-1)//做错误判断
	{
		perror("write fail");
	}
	
	//6.关闭文件
	close(bmp_fd);
	close(fd);
}

arm-linux-gnueabi-gcc -o LCD3 LCD.c

tftp 192.168.5.10 -g -r LCD3
chmod 777 LCD3
./LCD3

 

效果如上,可以看到图片是颠倒的。下面贴个如何把图片正过来的代码。

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <unistd.h>
#include <sys/types.h>
#include <unistd.h>

//off_t lseek(int fd, off_t offset, int whence);
//ssize_t read(int fd, void *buf, size_t count);
//ssize_t write(int fd, const void *buf, size_t count);
//int open(const char *pathname, int flags);


int main()
{
	//1.打开屏幕
	int fd=0; //接受open的返回值 
	fd=open("/dev/fb0", O_RDWR);
	if(fd==-1) //做错误判断
	{
		perror("open fb0 fail");
	}
	//打开图片
	int bmp_fd=0; //接受open的返回值 
	bmp_fd=open("./func.bmp", O_RDWR);
	if(bmp_fd==-1) //做错误判断
	{
		perror("open func.bmp fail");
	}
	
	
	//2.偏移54字节
	lseek(bmp_fd,54,SEEK_SET);

	//3.读取像素数据 800*480
	unsigned char bmp[800*480*3]={0};
	
	read(bmp_fd,bmp,sizeof(bmp));
	//4.数据处理
/*
bmp[0]--B
bmp[1]--G
bmp[2]--R
bmp[3]--B
....
lcd[0]=bmp[0] | bmp[1]<<8 | bmp[2]<<16;
lcd[1]=bmp[3] | bmp[4]<<8 | bmp[5]<<16;
lcd[2]=bmp[6] | bmp[7]<<8 | bmp[8]<<16;
*/	
	unsigned int temp[800*480]={0};
	unsigned int lcd[800*480]={0};
	int i=0;
	int j=0;
	for(i=0;i<800*480;i++)
	{
		temp[i]=bmp[3*i] | bmp[3*i+1]<<8 | bmp[3*i+2]<<16;
	}
	
	for(i=0;i<480;i++)
	{
		for(j=0;j<800;j++)
		{
			lcd[(480-1-i)*800+j]=temp[i*800+j];
		}
		
	}
	//5.写入屏幕
	int w_ret=0;
	w_ret=write(fd, lcd, sizeof(lcd));
	if(w_ret==-1)//做错误判断
	{
		perror("write fail");
	}
	
	//6.关闭文件
	close(bmp_fd);
	close(fd);
}

 这里省去交叉编译的过程图

 效果图如上,其实就是把图反着写入。

在这里把执行的程序文件放上来,大伙自己烧板子自己试哈

链接:https://pan.baidu.com/s/1BuQ5Q2FEGbgdJ1yEr4o86w 
提取码:1234 

4.网线登录

啧...我觉得这个可能没太大必要,虽然好像可以省一个串口,但还不如串口换成个带5V的TYPEC,也是两条线,搞这个不如整个WiFi模块远程无线调试,我不做了,但里面有一个过程比较有价值,就是更改开机脚本的

vi /etc/profile

其实就是改ifconfig之后得到的开发板的网卡IP,我这里是改成了192.168.5.9,需要的话改,不需要就每次开机都输入一条

ifconfig eth0 192.168.5.9

5.触屏电子相册

我靠,晴天霹雳,完成这东西需要整多几张图,太难受了

 然后在图画另存为bmp格式就行,我做的是这三张。

 下面贴出代码:

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <unistd.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/mman.h>
#include <linux/input.h>


//void *mmap(void *addr, size_t length, int prot, int flags,int fd, off_t offset);

//off_t lseek(int fd, off_t offset, int whence);
//ssize_t read(int fd, void *buf, size_t count);
//ssize_t write(int fd, const void *buf, size_t count);
//int open(const char *pathname, int flags);
//函数声明
int show_bmp(const char *bmpname);
int show_anybmp(const char *bmpname);
int show_anywherebmp(int x0,int y0,const char *bmpname);
int get_xy(int *x,int *y);

int main()
{
	int x=-1;
	int y=-1;
    	int tmp=0;
	char photo[][30]={"./1.bmp","./2.bmp","./3.bmp"};
	//1.显示主界面
	show_anybmp("./func.bmp"); //规则界面
	while(1)
	{
		//2.获取坐标
		get_xy(&x,&y);

		if(x>=400) //下一张
		{
			tmp=(tmp+1)%3;
			show_bmp(photo[tmp]);
		}
		else if(x<400) //上一张
		{
			tmp=tmp-1;
			if(tmp==-1){
				tmp=2;
			}
			show_bmp(photo[tmp]);
		}
		
		//用完坐标得清零 坐标
		x=-1;
		y=-1;
	}
	
	
}

//函数实现
//显示800*480的图片
int show_bmp(const char *bmpname)
{
	//1.打开屏幕
	int fd=0; //接受open的返回值 
	fd=open("/dev/fb0", O_RDWR);
	if(fd==-1) //做错误判断
	{
		perror("open fb0 fail");
	}
	
	//建立屏幕映射
	unsigned int* lcd = mmap(NULL, 800*480*4,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
	
	
	//打开图片
	int bmp_fd=0; //接受open的返回值 
	bmp_fd=open(bmpname, O_RDWR);
	if(bmp_fd==-1) //做错误判断
	{
		perror("open func.bmp fail");
	}
	
	
	//2.偏移54字节
	lseek(bmp_fd,54,SEEK_SET);

	//3.读取像素数据 800*480
	unsigned char bmp[800*480*3]={0};
	
	read(bmp_fd,bmp,sizeof(bmp));
	//4.数据处理
/*
bmp[0]--B
bmp[1]--G
bmp[2]--R
bmp[3]--B
....
lcd[0]=bmp[0] | bmp[1]<<8 | bmp[2]<<16;
lcd[1]=bmp[3] | bmp[4]<<8 | bmp[5]<<16;
lcd[2]=bmp[6] | bmp[7]<<8 | bmp[8]<<16;
*/	
	unsigned int temp[800*480]={0};
	int i=0;
	int j=0;
	for(i=0;i<800*480;i++)
	{
		temp[i]=bmp[3*i] | bmp[3*i+1]<<8 | bmp[3*i+2]<<16;
	}
	
	//解决上下颠倒  把一维数组 二维化思考
	for(i=0;i<480;i++)
	{
		for(j=0;j<800;j++)
		{
			lcd[(480-1-i)*800+j]=temp[i*800+j];
		}
		
	}
	
	
	//解除映射
	munmap(lcd,800*480*4);
	
	//6.关闭文件
	close(bmp_fd);
	close(fd);	
}


//显示任意大小图片
int show_anybmp(const char *bmpname)
{
	//1.打开屏幕
	int fd=0; //接受open的返回值 
	fd=open("/dev/fb0", O_RDWR);
	if(fd==-1) //做错误判断
	{
		perror("open fb0 fail");
	}
	
	//建立屏幕映射
	unsigned int* lcd = mmap(NULL, 800*480*4,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
	
	
	//打开图片
	int bmp_fd=0; //接受open的返回值 
	bmp_fd=open(bmpname, O_RDWR);
	if(bmp_fd==-1) //做错误判断
	{
		perror("open func.bmp fail");
	}
	
	
	
	
	//2.偏移54字节
	//先提取到宽
	lseek(bmp_fd,18,SEEK_SET);
	int w=0;
	read(bmp_fd,&w,4);
	//printf("w=%d\n",w);//打印宽度信息
	//再提取高
	lseek(bmp_fd,22,SEEK_SET);
	int h=0;
	read(bmp_fd,&h,4);
	//printf("h=%d\n",h);//打印宽度信息
	
	
	lseek(bmp_fd,54,SEEK_SET);

	//3.读取像素数据 800*480
	unsigned char bmp[w*h*3];
	
	read(bmp_fd,bmp,sizeof(bmp));
	//4.数据处理
/*
bmp[0]--B
bmp[1]--G
bmp[2]--R
bmp[3]--B
....
lcd[0]=bmp[0] | bmp[1]<<8 | bmp[2]<<16;
lcd[1]=bmp[3] | bmp[4]<<8 | bmp[5]<<16;
lcd[2]=bmp[6] | bmp[7]<<8 | bmp[8]<<16;
*/	
	unsigned int temp[800*480]={0};
	int i=0;
	int j=0;
	for(i=0;i<w*h;i++)
	{
		temp[i]=bmp[3*i] | bmp[3*i+1]<<8 | bmp[3*i+2]<<16;
	}
	
	//解决上下颠倒  把一维数组 二维化思考
	for(i=0;i<h;i++)
	{
		for(j=0;j<w;j++)
		{
			lcd[(h-1-i)*800+j]=temp[i*w+j];
		}
		
	}
	
	
	//解除映射
	munmap(lcd,800*480*4);
	
	//6.关闭文件
	close(bmp_fd);
	close(fd);
} 

//在指定位置显示图片 x0,y0为起点坐标
int show_anywherebmp(int x0,int y0,const char *bmpname)
{
	//1.打开屏幕
	int fd=0; //接受open的返回值 
	fd=open("/dev/fb0", O_RDWR);
	if(fd==-1) //做错误判断
	{
		perror("open fb0 fail");
	}
	
	//建立屏幕映射
	unsigned int* lcd = mmap(NULL, 800*480*4,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
	
	
	//打开图片
	int bmp_fd=0; //接受open的返回值 
	bmp_fd=open(bmpname, O_RDWR);
	if(bmp_fd==-1) //做错误判断
	{
		perror("open func.bmp fail");
	}
	
	
	
	
	//2.偏移54字节
	//先提取到宽
	lseek(bmp_fd,18,SEEK_SET);
	int w=0;
	read(bmp_fd,&w,4);
	printf("w=%d\n",w);//打印宽度信息
	//再提取高
	lseek(bmp_fd,22,SEEK_SET);
	int h=0;
	read(bmp_fd,&h,4);
	printf("h=%d\n",h);//打印宽度信息
	
	
	lseek(bmp_fd,54,SEEK_SET);

	//3.读取像素数据 800*480
	unsigned char bmp[w*h*3];
	
	read(bmp_fd,bmp,sizeof(bmp));
	//4.数据处理
/*
bmp[0]--B
bmp[1]--G
bmp[2]--R
bmp[3]--B
....
lcd[0]=bmp[0] | bmp[1]<<8 | bmp[2]<<16;
lcd[1]=bmp[3] | bmp[4]<<8 | bmp[5]<<16;
lcd[2]=bmp[6] | bmp[7]<<8 | bmp[8]<<16;
*/	
	unsigned int temp[800*480]={0};
	int i=0;
	int j=0;
	for(i=0;i<w*h;i++)
	{
		temp[i]=bmp[3*i] | bmp[3*i+1]<<8 | bmp[3*i+2]<<16;
	}
	
	//解决上下颠倒  把一维数组 二维化思考
	for(i=0;i<h;i++)
	{
		for(j=0;j<w;j++)
		{
			lcd[(h-1-i+y0)*800+j+x0]=temp[i*w+j];
		}
		
	}
	
	
	//解除映射
	munmap(lcd,800*480*4);
	
	//6.关闭文件
	close(bmp_fd);
	close(fd);	
}

int get_xy(int *x,int *y)
{

	int count=0;
	//1.打开触摸屏
	int tsfd =open("/dev/input/event0",O_RDWR);
	if(tsfd == -1)
	{
		perror("open ts fail");
	}
	
	//2.read
	struct input_event ts;
	
	while(1)
	{
		read(tsfd,&ts,sizeof(struct input_event));
		
		//筛选
		if(ts.type ==EV_ABS && ts.code==ABS_X )
		{ 
			*x=ts.value; //适合蓝底屏幕
			//*x= ts.value*800/1024;   //适合黑底屏幕
			count++;
		}
		
		if(ts.type ==EV_ABS && ts.code==ABS_Y )
		{
			*y=ts.value; //适合蓝底屏幕
			//*y= ts.value*480/600;   //适合黑底屏幕
			
			count++;
		}
		if(count == 2)
		{
			break;
		}
	}
	
	//关闭触摸屏
	close(tsfd);
}




arm-linux-gnueabi-gcc -o touch LCD_drv_touch.c

 

 

 效果如下:

效果

6.网络编程(TCP通信)

因为我没听课,所以就不知道他做的什么内容了..这部分我确实没学过,本来打算是寒假去学的,刚刚好,他竟然教了。

前面还有一个多线程的实验,因为不难我就不做了,拿gcc编译工具在UBUNTU上跑就行

代码贴出来

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <unistd.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/mman.h>
#include <linux/input.h>
#include <pthread.h>

//int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);

//线程任务函数
void *pth_function1(void *arg)
{
	while(1)
	{
		printf("你真帅!!!\n");
		sleep(1);//延时一秒
	}
	
	
}

//主线程
int main()
{
	
	pthread_t  thid; //定义线程ID
	
	//创建一个新的线程,默认属性  任务函数     不传参
	pthread_create(&thid, NULL, pth_function1, NULL);
	
	
	while(1)
	{
		printf("年轻人不讲武德!!!\n");
		sleep(1);//延时一秒
	}
	
}
gcc pth.c -o pth -pthread

 然后是第一个实验,TCP的客户端与服务端间的通信

ifconfig

 需要改这里:

 服务端代码:(server.c)

#include <stdio.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include <strings.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/fb.h>
#include <sys/mman.h>
#include <linux/input.h>

//int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
//int listen(int sockfd, int backlog);
//int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
//int socket(int domain, int type, int protocol);

int main()
{
	//1.创建socket
	int skfd=socket(AF_INET ,SOCK_STREAM, 0);
	if(skfd == -1)
	{
		perror("socket fail");
	}
	else
	{
		printf("socket ok\n");
	}
	
	//2.bind IP和端口号
	//定义结构体
	struct sockaddr_in  seraddr={0};
	
	seraddr.sin_family=AF_INET; //IPV4
	seraddr.sin_port= htons(12345);
	//端口号 http-80 8080  Telnet--23 范围:0~65535  个人编程的时候建议5位数的端口号
	//htons()  把本地转换为网络序  认识大端和小端存储
	seraddr.sin_addr.s_addr=htonl(INADDR_ANY);
	//htonl() 课后 认识一下  转换为网络序  INADDR_ANY--0.0.0.0--表示自动获取本机IP
	
	int b_ret=bind(skfd, (struct sockaddr*)&seraddr,sizeof(seraddr));
	if(b_ret !=0)
	{
		perror("bind fail");
	}
	else
	{
		printf("bind ok\n");
	}
	
	//3.listen--等待连接
	int l_ret = listen(skfd,3);
	if(l_ret!=0)
	{
		perror("listen fail");
	}
	else
	{
		printf("listen ok\n");
	}
	
	//4.accept
	struct sockaddr_in  cliaddr={0}; //为了存储连接的客户端信息
	int len=sizeof(cliaddr);
	int newskfd=accept(skfd,(struct sockaddr*)&cliaddr, &len);
	if(newskfd == -1)
	{
		perror("accept fail");
		return -1;
	}
	else
	{
		printf("accept ok\n");
		printf("newskfd=%d,client-ip:%s,client-port:%d\n",newskfd,inet_ntoa(cliaddr.sin_addr),ntohs(cliaddr.sin_port));
		
	}
	
	//5.read/write  服务器一直接收
	char buf[1024]={0};
	while(1)
	{
		read(newskfd,buf,sizeof(buf)); //读取消息
		printf("buf=%s\n",buf); //打印消息
		
		if( strcmp(buf,"exit") == 0) //字符串的判断
		{
			break; //跳出循环  关闭通信
		}
		
		memset(buf,0,sizeof(buf)); //清空数组
	}
	
	
	//6. 关闭通信
	close(skfd);
	
}

 客户端代码:(client.c)

#include <stdio.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include <strings.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/fb.h>
#include <sys/mman.h>
#include <linux/input.h>
//int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
//int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
//int listen(int sockfd, int backlog);
//int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
//int socket(int domain, int type, int protocol);

int main()
{
	//1.创建socket
	int skfd=socket(AF_INET ,SOCK_STREAM, 0);
	if(skfd == -1)
	{
		perror("socket fail");
	}
	else
	{
		printf("socket ok\n");
	}
	
	//2.发起连接请求 connect
	struct sockaddr_in  seraddr={0};
	
	seraddr.sin_family=AF_INET; //IPV4
	seraddr.sin_port= htons(12345); 
	//端口号 http-80 8080  Telnet--23 范围:0~65535  个人编程的时候建议5位数的端口号
	//htons()  把本地转换为网络序  认识大端和小端存储
	seraddr.sin_addr.s_addr=inet_addr( "192.168.42.168"); //服务器的地址
	//htonl() 课后 认识一下  转换为网络序  INADDR_ANY--0.0.0.0--表示自动获取本机IP
	
	int c_ret=connect(skfd, (struct sockaddr*)&seraddr,sizeof(seraddr));
	if(c_ret!=0)
	{
		perror("connect fail");
		return -1;
	}
	else
	{
		printf("connect ok\n");
	}
	
	//3.read /write  通信:客户端一直发消息
	
	char buf[1024]={0};
	while(1)
	{
		printf("请输入要发送的消息:\n");
		scanf("%s",buf);
		write(skfd,buf,strlen(buf)); //发送消息
		if(strcmp(buf,"exit")==0) //判断消息为退出关键字
		{
			break;
		}
		printf("buf=%s\n",buf);
	}
	
	//4.关闭通信
	close(skfd);
}

 效果如下:

 7.网络编程(UDP通信)

直接贴代码了,比较简单,难在理解整个过程,不然代码是没法写的

 本机UBUNTUip为192.168.5.11,想要啥设备接收就写哪个设备的ip

服务端(server.c)

#include <stdio.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include <strings.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/fb.h>
#include <sys/mman.h>
#include <linux/input.h>

//ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,const struct sockaddr *dest_addr, socklen_t addrlen);

int main()
{
	
	//1.创建socket
	int skfd=socket(AF_INET ,SOCK_DGRAM, 0);
	if(skfd == -1)
	{
		perror("socket fail");
	}
	else
	{
		printf("socket ok\n");
		printf("skfd=%d\n",skfd);
	}
	
	int s_ret=0; //返回值
	char buf[512]={0}; //存储读取内容
	struct sockaddr_in  seraddr={0}; //来自客户端地址
	
	seraddr.sin_family=AF_INET; //IPV4
	seraddr.sin_port= htons(12345); 
	//端口号 http-80 8080  Telnet--23 范围:0~65535  个人编程的时候建议5位数的端口号
	//htons()  把本地转换为网络序  认识大端和小端存储
	seraddr.sin_addr.s_addr=inet_addr( "192.168.5.11"); //服务器的地址
	//htonl() 课后 认识一下  转换为网络序  INADDR_ANY--0.0.0.0--表示自动获取本机IP
	
	
	
	socklen_t addrlen=sizeof(seraddr); //地址长度
	
	while(1)
	{
		printf("请输入发送的消息\n");
		scanf("%s",buf);
		s_ret=sendto(skfd,buf, strlen(buf),0,(struct sockaddr*)&seraddr, addrlen);
		//面试题 strlen 和 sizeof 对比
		if(s_ret==-1)
		{
			perror("sendto fail");
		}
		if(strcmp(buf,"exit")== 0)
		{
			break;
		}
		memset(buf,0,sizeof(buf)); //用完之后清空
	}
	
	//关闭通信
	close(skfd);
	
}

 客户端(client.c)

#include <stdio.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include <strings.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/fb.h>
#include <sys/mman.h>
#include <linux/input.h>

//ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,struct sockaddr *src_addr, socklen_t *addrlen);



int main()
{
	//1.创建socket
	int skfd=socket(AF_INET ,SOCK_DGRAM, 0);
	if(skfd == -1)
	{
		perror("socket fail");
	}
	else
	{
		printf("socket ok\n");
		printf("skfd=%d\n",skfd);
	}
	
	//2.bind IP和端口号
	//定义结构体
	struct sockaddr_in  seraddr={0};
	
	seraddr.sin_family=AF_INET; //IPV4
	seraddr.sin_port= htons(12345);
	//端口号 http-80 8080  Telnet--23 范围:0~65535  个人编程的时候建议5位数的端口号
	//htons()  把本地转换为网络序  认识大端和小端存储
	seraddr.sin_addr.s_addr=htonl(INADDR_ANY);
	//htonl() 课后 认识一下  转换为网络序  INADDR_ANY--0.0.0.0--表示自动获取本机IP
	
	int b_ret=bind(skfd, (struct sockaddr*)&seraddr,sizeof(seraddr));
	if(b_ret !=0)
	{
		perror("bind fail");
	}
	else
	{
		printf("bind ok\n");
	}
	
	int r_ret=0; //返回值
	char buf[512]={0}; //存储读取内容
	struct sockaddr_in  cliaddr={0}; //来自客户端地址
	socklen_t addrlen=sizeof(cliaddr); //地址长度
	
	while(1)
	{
		//接收消息
		r_ret=recvfrom(skfd, buf,sizeof(buf),0,(struct sockaddr*)&cliaddr, &addrlen);
		if(r_ret == -1)
		{
			perror("recvfrom fail");
		}
		else
		{
			printf("from %s:%s\n",inet_ntoa(cliaddr.sin_addr),buf);
		}
		
		if(strcmp(buf,"exit")==0)//判断消息内容
		{
			break;
		}
		
		memset(buf,0,sizeof(buf)); //用完之后清空
		memset(&cliaddr,0,sizeof(cliaddr));
		
	}
	
	//关闭通信
	close(skfd);
	
}

8.开发板串口通信MCU(32或Zigbee节点)

 这个功能确实是我想学的..

但很难受,手头上没杜邦线

这里做一个开发板多线程自己通信自己

贴出来代码:

#include <stdio.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <termios.h>
#include <unistd.h>
#include <string.h>


int set_serial_uart(int ser_fd)
{
	struct termios new_cfg,old_cfg;
		
	/*保存并测试现有串口参数设置,在这里如果串口号等出错,会有相关的出错信息*/ 
	if	(tcgetattr(ser_fd, &old_cfg) != 0)
	{
		perror("tcgetattr");
		return -1;
	}
	
	bzero( &new_cfg, sizeof(new_cfg));
	/*原始模式*/
	/* 设置字符大小*/
	new_cfg = old_cfg; 
	cfmakeraw(&new_cfg); /* 配置为原始模式 */ 

	/*波特率为115200*/
	cfsetispeed(&new_cfg, B115200); 
	cfsetospeed(&new_cfg, B115200);
	
	//用于本地连接和接受使能
	new_cfg.c_cflag |= CLOCAL | CREAD;
	
	/*8位数据位*/
	new_cfg.c_cflag &= ~CSIZE;
	new_cfg.c_cflag |= CS8;

	/*无奇偶校验位*/
	new_cfg.c_cflag &= ~PARENB;

	/*1位停止位*/
	new_cfg.c_cflag &= ~CSTOPB;
	/*清除串口缓冲区*/
	tcflush( ser_fd,TCIOFLUSH);
	new_cfg.c_cc[VTIME] = 0; //等待时间
	new_cfg.c_cc[VMIN] = 1; //最少接收字节数
	tcflush ( ser_fd, TCIOFLUSH);
	/*串口设置使能*/
	tcsetattr( ser_fd ,TCSANOW,&new_cfg);
}

int main(void)
{
	int ret;
	char buf[10];
	//打开串口 0
	int fd = open("/dev/ttyUSB0" , O_RDWR|O_NOCTTY);
	if(fd < 0)
	{
		perror ("open failed");
		return 0;
	}
	
	set_serial_uart(fd);
	
	while(1)
	{
		bzero(buf, 10);
		ret = read(fd , buf , 10-1); // 留一个位置给‘\0'
		if(ret <= 0 )
		{
			perror("write failed");
			break;
		}
		printf("I GOT : %s \n", buf); // 打印
	}
}

硬件连接如下:

用的善学坊的一款板子,板载ch340,接收路由器设备采集到的光照强度数据,温湿度数据发送到协调器,然后协调器再通过USB0发送给开发板。

 开发板接收到数据如下,有点冷...

9.EDP接入onenet

哇,真的是不想搞这玩意,没想到又遇到了,之前弄完之后把环境全删掉了,觉得有点没意思,现在用的stm32连接onenet,至于MQTT通信,因为在学这玩意之前先去学了ros通信,其实也就差不多,就是客户端发布话题,服务端订阅,差别就差在ros通信里面有个通信的master。

 开发实例_开发者文档_OneNET

但MQTT的环境有点问题,所以在这里先把EDP的通信解决了。

我不知道你们界面是不是这样:

 这里有个多协议接入,我们要用到的EDP协议貌似只有这里有

或者以这种形式也能进去

 选择EDP,点击添加产品

 主要是设备接入协议那里选择EDP就行,其他随便

 添加完就是这样了,点击下面的位置进入

 点击设备列表再点击添加设备

 填写只需注意鉴权信息就行

 添加好后如下,点击详情

 添加APIkey后将这三个信息记录下来

 放入记事本

 点击数据流模板,再点击添加数据流模板

 因为代码内设置的是Temp,所以这里也就用Temp了,但实际上这东西按理讲是不用加的,当数据上传上来就会自动生成才是。

 设置好后如下

 然后就是改代码了,代码用的是老师给的一份代码,在这里直接贴链接了

链接:https://pan.baidu.com/s/1FxXrvckHxBiyX9E-HZakgA 
提取码:1234 

更改代码如下,分别是设备ID及API密钥

 可以看到,该代码将会上传一个名为Temp的数据流,并且该数据将不断加1,到100,再清0

 直接放到UBUNTU上编译就行,可以看到,选中的为执行文件

 运行

设备连接成功

 数据流如下

 然后就是试一下,将该代码用在开发板上了,怎么用呢,首先得让开发板连上网吧?..

这就涉及到我的知识盲区了..

先不管了,先把开机脚本改一下:

vi /etc/profile

 先把这两行注释掉,屏蔽开发板的嵌入式物联网综合实验箱

 然后再配置上网

怎么找信息呢..我是连上了从路由器接过来的网线到电脑上

点击这里 

 自动配置IP

 可以看到IPV4地址在该机为192.168.1.5

 这信息不就来了嘛

 所以开发板内就这样配置

哎,每次进入这个开机程序之后,只要这个串口线一松,就掉出界面,然后就拒绝访问,我是真的烦,所以我就直接输了

    ifconfig eth0 up
    ifconfig eth0 192.168.1.6
    route add default gw 192.168.1.1
    echo "nameserver 114.114.114.114" > /etc/resolv.conf
    echo "search lan" >> /etc/resolv.conf

 然后来到更改适配器选项这里

 用哪个网卡改哪个网卡,右键属性

 

 

 配置就结束了。

 然后把网线插到开发板上,哇这网络延迟,ping是ping通了,感觉这延迟不对劲啊

 现在说明开发板能连上网了

然后就是改代码了,这份代码也是现成的,需要改的部分和之前一致。

这里直接贴链接了

链接:https://pan.baidu.com/s/1yxfU5qXSzRodnv8JJjQSAg 
提取码:1234 

这里只需要把交叉编译工具链改成自己的就行

 编译出的程序文件如下

 把它扔到开发板运行试试

因为网口被占用被迫用回RX工具了..

 运行发现,开发板已经连上onenet了

 显示在线

 数据正常

 下发个数据试试

 正常

10.MQTT协议接入onenet

这个..需要配置

openssl-OpenSSL_1_0_2q,paho.mqtt.c-1.3.0(编译paho时需打开PAHO_WITH_SSL选项)

直接跟着走就行

 首先还是这个界面,但用的是MQTT物联网套件

 点击添加产品

 重点还是这个接入协议

 点进去

 设备列表,添加设备

 信息随便设置

 然后就是要改代码了

直接贴上来了

链接:https://pan.baidu.com/s/1daXTwM9xmNwG62TnBOYvDw 
提取码:1234 

 要改如下几个部分,分别对应于以下几个位置的信息

 

 

 const char *server_url = "ssl://mqttstls.heclouds.com:8883";

 然后Cmakelist.txt中需要加一个参数

 代码就算改完了,然后是环境配置

 把代码扔上ubuntu后

安装CMake

 sudo apt install cmake

 安装OpenSSL

sudo apt-get install libssl-dev

 安装paho.mqtt.c

git clone https://github.com/eclipse/paho.mqtt.c.git

cd paho.mqtt.c

//修改编辑CMakeLists.txt文件,打开PAHO_WITH_SSL,编辑下图所示的位置,将FALSR改为TRUE

//修改编辑CMakeLists.txt文件,将FALSR改为TRUE

make clean
make
sudo make install

 编译示例代码:

cmake .
make clean
make 

 链接onenet成功

 如下

 11.ZIGBEE发送数据,由6818开发板接收后发送到ONENET

 硬件连接如下,可以看到,协调器通过USB0连接到6818开发板,然后路由器节点连接到电脑(仅供电,)6818开发板连接网线与电脑通过RS232串口线相连(需要上网和串口调试)

 这里直接贴用的代码了

链接:https://pan.baidu.com/s/18w0fwo3Zz8gmhAKkiTzEgA 
提取码:1234 
ZIGBEE代码就不给了,我这里的ZIGBEE是把温度湿度光照强度,三个数放在一个字符串变量里面,到时候直接开发板自己拆分解决

 对比一下数据流

 下发命令呢?也正常

12.开发板接收onenet下发命令通过协调器控制路由器开关灯

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

粤嵌实训(笔记) 的相关文章

  • 2.23怎么在OrCAD原理图中显示与隐藏元器件的Value值?【OrCAD原理图封装库50问解析】

    笔者电子信息专业硕士毕业 获得过多次电子设计大赛 大学生智能车 数学建模国奖 现就职于南京某半导体芯片公司 从事硬件研发 电路设计研究 对于学电子的小伙伴 深知入门的不易 特开次博客交流分享经验 共同互勉 全套资料领取扫描文末二维码 温馨提
  • 立创EDA(专业版)画PCB怎么开窗?

    阻焊层是开窗 助焊层是开钢网用的 大概的步骤 1 选择图层 顶层阻焊层 如果是想在顶层开窗 2 画个矩形框框 3 右击点击属性 选择顶层阻焊 4 利用3D PCB 观察 如果选择区域和有类似焊盘上的没有覆膜的管脚的那个黄铜的部分 成功了
  • (esp-idf)一文看懂u8g2库点亮OLED

    github仓库地址 HawkJ02 esp32 oled github com 首先丢一个u8g2库的地址 olikraus u8g2 U8glib library for monochrome displays version 2 gi
  • 常见电路-SD卡

    一 SD速率 低速SDIO下 速率达到0 400KHz 全速SDIO下 速率达到100MHz 本人用的SanDisk SD卡 软件设置速率16M 二 SD电路 原理图 网上有人说上拉电阻 最低10K 最高50K 没有试验过 我常用的是San
  • 计算机组成与设计:硬件/软件接口,第三章详细梳理,附思维导图

    文章目录 三 计算机的运算 章节导图 一 整数的表示 无符号整数 原码 反码 原码是带符号整数的表示方法
  • 139-基于stm32单片机老人居家监护报警系统Proteus仿真+源程序

    资料编号 139 一 功能介绍 1 采用stm32单片机 LCD1602显示屏 独立按键 MQ4传感器 电位器模拟 MQ2传感器 电位器模拟 蜂鸣器 电机 制作一个基于stm32单片机老人居家监护报警系统Proteus仿真 2 通过MQ2传
  • 135-基于stm32单片机超声波非接触式感应水龙头控制系统Proteus仿真+源程序

    资料编号 135 一 功能介绍 1 采用stm32单片机 LCD1602显示屏 独立按键 DHT11传感器 电机 超声波传感器 制作一个基于stm32单片机超声波非接触式感应水龙头控制系统Proteus仿真 2 通过DHT11传感器检测当前
  • HAL库STM32常用外设教程(二)—— GPIO输入\输出

    HAL库STM32常用外设教程 二 GPIO输入 输出 文章目录 HAL库STM32常用外设教程 二 GPIO输入 输出 前言 一 GPIO功能概述 二 GPIO的HAl库驱动 三 GPIO使用示例 1 示例功能 四 代码讲解 五 总结
  • STM32用一个定时器执行多任务写法

    文章目录 main c include stm32f4xx h uint32 t Power check times 电量检测周期 uint32 t RFID Init Check times RFID检测周期 int main Timer
  • MAX31865硬件和程序攻坚

    MAX31865硬件和程序攻坚 中文数据手册 STM32H库与工程文件创建 模块硬件部分 温度数据准确性 中文数据手册 MAX31865中文手册可以看这个博主挂上的文章 总结 STM32F103C8T6通过MAX31865读取PT100电阻
  • 请问想要在嵌入式行业扎根成长的人何种学历更为合适?

    今日话题 想要在嵌入式行业扎根成长的人何种学历更为合适 嵌入式行业容纳了来自不同学历背景的人 包括专科 本科和研究生 甚至那些来自非相关领域的人 在这个领域 学历并非唯一的关键 分享一份由一位oppo sp offer的学长制作的学习资料包
  • 解决KEIL编译慢问题

    两种方案 使用v6版本的ARM Compiler 如果v6版本编译不过 必须使用v5版本的 则可以勾选掉Browse Information选项 提升很明显 1分多钟能优化到几秒 看代码量 但是这个有个弊端 在KEIL中会影响函数跳转 建议
  • 【雕爷学编程】Arduino智慧农业之养殖水质监测与控制

    Arduino是一个开放源码的电子原型平台 它可以让你用简单的硬件和软件来创建各种互动的项目 Arduino的核心是一个微控制器板 它可以通过一系列的引脚来连接各种传感器 执行器 显示器等外部设备 Arduino的编程是基于C C 语言的
  • 【雕爷学编程】Arduino智慧农业之养殖水质监测与控制

    Arduino是一个开放源码的电子原型平台 它可以让你用简单的硬件和软件来创建各种互动的项目 Arduino的核心是一个微控制器板 它可以通过一系列的引脚来连接各种传感器 执行器 显示器等外部设备 Arduino的编程是基于C C 语言的
  • 串口流控(CTS/RTS)使用详解

    1 流控概念 在两个设备正常通信时 由于处理速度不同 就存在这样一个问题 有的快 有的慢 在某些情况下 就可能导致丢失数据的情况 如台式机与单片机之间的通讯 接收端数据缓冲区已满 则此时继续发送来的数据就会丢失 流控制能解决这个问题 当接收
  • allegro画PCB如何更新元件的PCB封装

    allegro画PCB如何更新元件的PCB封装 一 更新单个器件的PCB封装 首先菜单栏选择Place gt Update Symbols 如下图 注意此案例是更新了C0805封装 中更新封装 就将上图第二个红色方框中的勾选即可 二 更新某
  • 1.69寸SPI接口240*280TFT液晶显示模块使用中碰到的问题

    1 69寸SPI接口240 280TFT液晶显示模块使用中碰到的问题说明并记录一下 在网上买了1 69寸液晶显示模块 使用spi接口 分辨率240 280 给的参考程序是GPIO模拟的SPI接口 打算先移植到FreeRtos测试 再慢慢使用
  • PD SINK协议芯片系列产品介绍对比-ECP5701、FS312A、CH221K、HUSB238、AS225KL

    目录 一 ECP5701 二 FS312A 三 CH221K 四 HUSB238 五 AS225KL 在如今快节奏生活不断蔓延的背景下 人们对各种事情的处理也渐渐地开始要求在保证质量的情况下 不断加快 手机快充就是一个典型的例子 从开始的1
  • 太阳诱电 | 电容器为什么会发热?什么是纹波电流

    电容器中存在寄生于电极和电介质的电阻成分 当纹波电流等交流电流通过电容器时 电阻的成分会产生热量 为了抑制发热 选择ESR较低的电容器非常重要 陶瓷电容器在电容器中ESR较低 非常适合抑制发热 电容器中的纹波电流主要是指电源电路中由于IC的
  • 【学习分享】全志平台TWI子系统源码分析(1)从设备树到寄存器

    全志平台TWI子系统源码分析 1 从设备树到寄存器 前言 一 名词解释 二 从设备树入手看源码 1 TWI设备树 2 TWI源码位置 3 TWI总线相关寄存器 总结 前言 这次开坑主要是想把全志平台TWI子系统在源

随机推荐

  • 字符串搜索dfs题79_208_212

    79 Word Search 给一个二维字符数组和一个字符串 判断是否存在一条路径使得路径字符等于所给字符串 board A B C E S F C S A D E E Given word ABCCED return true Given
  • 【未解决】获取注解上的注解的值

    网上没找到相关资料 自己尝试做了下 注解1 Target ElementType METHOD ElementType ANNOTATION TYPE Retention RetentionPolicy RUNTIME public int
  • html弹跳qq群号代码,抖音上QQ群霸屏消息代码分享_抖音上QQ群霸屏消息代码大全-街机中国...

    今天抖音上很多人拍摄在QQ中发送代码 可以让表情霸屏的视频 小编的QQ群也收到了很多霸屏贴表情消息 首先 复制代码 sticker start tag for text originMsgType 0 x 0 070370368659496
  • 传统网络配置命令与ip高级路由命令学习示例(转)

    传统网络配置命令与ip高级路由命令学习示例 转 more 传统网络配置命令与ip高级路由命令学习示例 by KindGeorge 2005 5 9 懂得网络配置命令是一般技术人员必备的技术 经过一段时间的研究和学习 总结了一些常用的命令和示
  • MapReduce之KNN算法

    MapReduce之KNN算法 什么是 K K K 邻近算法 KNN KNN分类问题是找出一个数据集中与一个给定查询数据点最近的 k k k个数据点 这个操作也称KNN连接 定义为 给定两个数据集
  • svn清除不成功的解决办法(cleanup失败)

    使用工具 sqlite3 exe 32位下载地址 https download csdn net download songxinfeng1989 10500196 64位下载地址 https download csdn net downl
  • FreeRTOS软件定时器创建、复位、开始和停止(备忘)

    目录 一 简介 1 1 开发环境 1 2 摘要 二 STM32CubeIDE配置 三 创建定时器 3 1 头文件声明 3 2 工程文件定义 3 3 创建定时器 3 4 开启 复位 和关闭定时器 四 定时器回调函数 一 简介 1 1 开发环境
  • js调用摄像头拍照并兼容ie浏览器

    不会吧不会吧 现在都2023年了竟然还有人在用ie浏览器 文章内容有点长 耐心看完 基本上能遇到的问题 都记录在这里了 问题1 调用摄像头并兼容ie浏览器 用户调用摄像头一般使用navigator mediaDevices 在ie浏览器这个
  • Netty客户端断线重连实现及问题思考

    前言 在实现TCP长连接功能中 客户端断线重连是一个很常见的问题 当我们使用netty实现断线重连时 是否考虑过如下几个问题 如何监听到客户端和服务端连接断开 如何实现断线后重新连接 netty客户端线程给多大比较合理 其实上面都是笔者在做
  • ::和.的区别

    作用域运算符 和 成员运算符 的区别 这是在看 运算符的作用时产生的疑问 有三个作用 1 全局作用 2 类作用 3 名称空间 1和3不多说 在2中 其说明是 作用域符号 的前面一般是类名称 后面一般是该类的成员名称 C 为了避免不同的类有名
  • Keil-MDK解决“Error: Encountered an improper argument”问题

    Keil MDK解决 Error Encountered an improper argument 问题 ARM官方问题描述及解决办法 https developer arm com documentation ka004382 lates
  • android环境配置

    JDK配置 JRE问题 Windows 打开PowerShell 进入JDK目录 执行 bin jlink exe module path jmods add modules java desktop output jre 环境变量 系统环
  • [STM32F10x] 利用定时器测量脉冲宽度

    硬件 STM32F103C8T6 平台 ARM MDk V5 11 前面一篇文章讲过如何利用定时器测量信号的频率 见 STM32F10x 利用定时器测量频率 使用的是定时器的捕获 比较单元 Capture compare 它也可以测量输入信
  • JDBC中的几个常见问题

    JDBC中的几个常见问题 1 JDBC中的Statement和PreparedStatement CallableStatement的区别 2 JDBC中大数据量分页的解决方法 3 事务 4 execute executeQuery exe
  • VS Code 格式化后 自动让函数名后有空格

    fetchCommentCount 像这样fetchCommentCount和 之间有空格 这是我们的目标 return 只需要在Vscode设置文件Settings中加入以下两句 vetur format defaultFormatter
  • 使用yum命令不能安装mysql的问题(No package mysql-server available. Error: Nothing to do)

    问题 这是因为本地yum仓库中没有对应的mysql包 所以在安装之前先要配置rpm包 这里使用的是mysql5 7的rpm rpm ivh https repo mysql com mysql57 community release el7
  • char类型的大小范围

    要知道char类型的大小范围 首先要知道char类型占1个字节 而1个字节等于8个bit位 每一个bit位是一位二进制数 所以char类型有8个二进制位 那么就有2的8次方256种可能 我们先讨论 signed char 有符号 首位是符号
  • IOS键盘的相关设置(UITextfield)

    http blog sina com cn s blog 7018d3820101djut html 一 键盘风格 UIKit框架支持8种风格键盘 typedef enum UIKeyboardTypeDefault 默认键盘 支持所有字符
  • Java基础笔记(初学者适用)

    目录 一 Java主函数解析 二 Java学习注意事项 三 JDK和JRE的区别 1 jdk 开发环境 核心 2 jre 运行环境 3 JVM 转换环境 四 常见转义字符 五 变量 1 变量介绍 2 变量细节 3 作用域 4 数据类型 1
  • 粤嵌实训(笔记)

    目录 1 LCD换自己喜欢的颜色 2 LCD换个图案 3 LCD换张图片 4 网线登录 ifconfig eth0 192 168 5 9 5 触屏电子相册 6 网络编程 TCP通信 7 网络编程 UDP通信 8 开发板串口通信MCU 32