各个模块
micro2440,1个
usb无线网卡TL-WN721N,1个
usb摄像头zp0301,1个
L298N直流电机驱动模块,2个
小车主体,1个
视频稍后
源码:
micro2440,1个
usb无线网卡TL-WN721N,1个
usb摄像头zp0301,1个
L298N直流电机驱动模块,2个
小车主体,1个
视频稍后
//在micro2440上操作
[root@FriendlyARM plg]# ls
bin-song
bin-song.tgz
dc_motor_driver.ko
server
usb-wifi-kits-for-mini2440-linux-2.6.32.2-20100728.tar.gz
[root@FriendlyARM plg]#
[root@FriendlyARM plg]# scan-wifi //扫描无线路由器
57% ChinaNet-TEXj(Security)
57% iTV-TEXj(Security)
56% ZXDSL531BII-539490
91% MERCURY_C93C2E(Security)//找到了
(Security)
39% ChinaNet-rwXE(Security)
37% iTV-rwXE(Security)
7 Access Point Found
[root@FriendlyARM plg]# start-wifi wpa2 MERCURY_C93C2E qwertyuiop//连接至无线路由器,密码是qwertyuiop
udhcpc (v1.13.3) started
Sending discover...
Sending discover...
Sending discover...
Sending discover...
cfg80211: Calling CRDA for country: US
Sending discover...
Sending select for 192.168.1.101...
Lease of 192.168.1.101 obtained, lease time 7200
deleting routers
route: SIOCDELRT: No such process
adding dns 192.168.1.109
[root@FriendlyARM bin-song]# ifconfig eth0 down //暂时禁用本地网卡
[root@FriendlyARM plg]# insmod dc_motor_driver.ko //加载驱动
smart_car initialized
[root@FriendlyARM plg]# ./server &//启动服务器,监听3333端口,udp模式
[root@FriendlyARM plg]# DBG(/opt/FriendlyARM/mini2440/smart_car/dc_motor/dc_motor_driver.c, misc_open(), 146): open
DBG(server.c, main(), 63): sock sucessful
DBG(server.c, main(), 78): bind sucess
[root@FriendlyARM plg]# cd bin-song/
[root@FriendlyARM bin-song]# ./mjpg_streamer -i input_uvc.so -o "output_http.so -w ./www" //开启mjpg的web服务器,8080端口
//在虚拟机上操作
[root@localhost dc_motor]# ./client //此时按下上下左右键开始控制吧
源码:
/*******************************dc_motor_driver.c**************/
//操作io口,使用8个点,
//分配给每个L298N模块4个点
//如下
#include <linux/miscdevice.h>
#include <linux/delay.h>
#include <asm/irq.h>
#include <mach/regs-gpio.h>
#include <mach/hardware.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/fs.h>
#include <linux/types.h>
#include <linux/time.h>
#include <linux/timer.h>
#include <linux/moduleparam.h>
#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/ioctl.h>
#include <linux/cdev.h>
#include <linux/string.h>
#include <linux/list.h>
#include <linux/pci.h>
#include <linux/gpio.h>
#include <asm/uaccess.h>
#include <asm/atomic.h>
#include <asm/unistd.h>
#define DEBUG
#ifdef DEBUG
#define DBG(...) printk(" DBG(%s, %s(), %d): ", __FILE__, __FUNCTION__, __LINE__); printk(__VA_ARGS__)
#else
#define DBG(...)
#endif
#define DEVICE_NAME "smart_car"
#define delay_time_ms 1000
int ret;
unsigned long motor_table [] = {
S3C2410_GPF(0),//EA
S3C2410_GPF(2),//EB
S3C2410_GPF(4),//EC
S3C2410_GPF(6),//ED
S3C2410_GPF(1),//IA,the back-right wheel ,1 on,0 back
S3C2410_GPF(3),//IB,the front-right wheel ,1 on,0 back
S3C2410_GPF(5),//IC,the back-left wheel ,1 on,0 back
S3C2410_GPG(0),//ID,the back-right wheel ,1 on,0 back
};
unsigned int motor_cfg_table [] = {
S3C2410_GPIO_OUTPUT,
S3C2410_GPIO_OUTPUT,
S3C2410_GPIO_OUTPUT,
S3C2410_GPIO_OUTPUT,
S3C2410_GPIO_OUTPUT,
S3C2410_GPIO_OUTPUT,
S3C2410_GPIO_OUTPUT,
S3C2410_GPIO_OUTPUT,
};
#define SET_EA_HIGH (s3c2410_gpio_setpin(motor_table[0],1))
#define SET_EA_LOW (s3c2410_gpio_setpin(motor_table[0],0))
#define SET_EB_HIGH (s3c2410_gpio_setpin(motor_table[1],1))
#define SET_EB_LOW (s3c2410_gpio_setpin(motor_table[1],0))
#define SET_EC_HIGH (s3c2410_gpio_setpin(motor_table[2],1))
#define SET_EC_LOW (s3c2410_gpio_setpin(motor_table[2],0))
#define SET_ED_HIGH (s3c2410_gpio_setpin(motor_table[3],1))
#define SET_ED_LOW (s3c2410_gpio_setpin(motor_table[3],0))
#define SET_IA_HIGH (s3c2410_gpio_setpin(motor_table[4],1))
#define SET_IA_LOW (s3c2410_gpio_setpin(motor_table[4],0))
#define SET_IB_HIGH (s3c2410_gpio_setpin(motor_table[5],1))
#define SET_IB_LOW (s3c2410_gpio_setpin(motor_table[5],0))
#define SET_IC_HIGH (s3c2410_gpio_setpin(motor_table[6],1))
#define SET_IC_LOW (s3c2410_gpio_setpin(motor_table[6],0))
#define SET_ID_HIGH (s3c2410_gpio_setpin(motor_table[7],1))
#define SET_ID_LOW (s3c2410_gpio_setpin(motor_table[7],0))
#define UP 1
#define DOWN 6
#define RIGHT 3
#define LEFT 4
#define STOP 5
ssize_t misc_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos)
{
DBG("write \n");
int ret;
char *commad=0;
if (count == 0) {
return count;
}
commad=kmalloc(count+1,GFP_KERNEL);//need print it using %s, so plus 1 byte for '\0'
ret = copy_from_user(commad, buf, count);//if success,ret=0
if (ret) {
return ret;
}
commad[count]='\0';
DBG("commad=%s\n",commad);
DBG("ret=%d\n",ret);
//to test the command "set to 1" or "clear to 0" if correct 代码做管脚测试用到
if(strncmp(commad,"SET_EA_HIGH",count)==0) {SET_EA_HIGH;DBG("excuting SET_EN_HIGH succes !\n");}
if(strncmp(commad,"SET_EA_LOW",count)==0) {SET_EA_LOW;DBG("excuting SET_EN_LOW succes !\n");}
if(strncmp(commad,"SET_EB_HIGH",count)==0) {SET_EB_HIGH;DBG("excuting SET_EB_HIGH succes !\n");}
if(strncmp(commad,"SET_EB_LOW",count)==0) {SET_EB_LOW;DBG("excuting SET_EB_LOW succes !\n");}
if(strncmp(commad,"SET_EC_HIGH",count)==0) {SET_EC_HIGH;DBG("excuting SET_EC_HIGH succes !\n");}
if(strncmp(commad,"SET_EC_LOW",count)==0) {SET_EC_LOW;DBG("excuting SET_EC_LOW succes !\n");}
if(strncmp(commad,"SET_ED_HIGH",count)==0) {SET_ED_HIGH;DBG("excuting SET_ED_HIGH succes !\n");}
if(strncmp(commad,"SET_ED_LOW",count)==0) {SET_ED_LOW;DBG("excuting SET_ED_LOW succes !\n");}
if(strncmp(commad,"SET_IA_HIGH",count)==0) {SET_IA_HIGH;DBG("excuting SET_IA_HIGH succes !\n");}
if(strncmp(commad,"SET_IA_LOW",count)==0) {SET_IA_LOW;DBG("excuting SET_IA_LOW succes !\n");}
if(strncmp(commad,"SET_IB_HIGH",count)==0) {SET_IB_HIGH;DBG("excuting SET_IB_HIGH succes !\n");}
if(strncmp(commad,"SET_IB_LOW",count)==0) {SET_IB_LOW;DBG("excuting SET_IB_LOW succes !\n");}
if(strncmp(commad,"SET_IC_HIGH",count)==0) {SET_IC_HIGH;DBG("excuting SET_IC_HIGH succes !\n");}
if(strncmp(commad,"SET_IC_LOW",count)==0) {SET_IC_LOW;DBG("excuting SET_IC_LOW succes !\n");}
if(strncmp(commad,"SET_ID_HIGH",count)==0) {SET_ID_HIGH;DBG("excuting SET_ID_HIGH succes !\n");}
if(strncmp(commad,"SET_ID_LOW",count)==0) {SET_ID_LOW;DBG("excuting SET_ID_LOW succes !\n");}
return ret ? ret : count;
}
ssize_t misc_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
{
DBG("read \n");
return 0;
}
static int misc_release(struct inode *inode, struct file *filp)
{
DBG("release \n");
return 0;
}
static int misc_open(struct inode *inode, struct file *filp)
{
DBG("open \n");
return 0;
}
static inline void go_on()
{
SET_EA_HIGH;
SET_IA_HIGH;
SET_EB_HIGH;
SET_IB_HIGH;
SET_EC_HIGH;
SET_IC_HIGH;
SET_ED_HIGH;
SET_ID_HIGH;
}
static inline void go_back()
{
SET_EA_HIGH;
SET_IA_LOW;
SET_EB_HIGH;
SET_IB_LOW;
SET_EC_HIGH;
SET_IC_LOW;
SET_ED_HIGH;
SET_ID_LOW;
}
static inline void go_right()
{
SET_EA_LOW;
SET_EB_HIGH;
SET_IB_HIGH;
SET_EC_LOW;
SET_ED_HIGH;
SET_ID_HIGH;
}
static inline void go_left()
{
SET_EA_HIGH;
SET_IA_HIGH;
SET_EB_LOW;
SET_EC_HIGH;
SET_IC_HIGH;
SET_ED_LOW;
}
static inline void stop()
{
SET_EA_LOW;
SET_EB_LOW;
SET_EC_LOW;
SET_ED_LOW;
}
static int misc_ioctl(struct inode *inode,struct file *file,unsigned int cmd,unsigned long arg)
{
int i=0;
DBG("cmd=%x\n",cmd);
DBG("arg=%x\n",arg);
if (cmd==UP) // go on
{
go_on();
}else if(cmd==DOWN){ //go back
go_back();
}else if(cmd==RIGHT){ //go right
go_right();
}else if(cmd==LEFT){ //go left
go_left();
}else if(cmd==STOP){ //stop
stop();
}
return 0;
}
static struct file_operations dev_fops = {
.owner = THIS_MODULE,
.open = misc_open,
.read = misc_read,
.write = misc_write,
.release= misc_release,
.ioctl= misc_ioctl,
};
static struct miscdevice misc = {
.minor = MISC_DYNAMIC_MINOR,
.name = DEVICE_NAME,
.fops = &dev_fops,
};
static int __init dev_init(void)
{
int ret;
int i;
for (i = 0; i < 8; i++) {//配置管脚的out in 模式
s3c2410_gpio_cfgpin(motor_table[i], motor_cfg_table[i]);
s3c2410_gpio_setpin(motor_table[i], 0);
}
ret = misc_register(&misc);
//InitRc522() ;//初始化
printk (DEVICE_NAME"\tinitialized\n");
//open_flag=0;
return ret;
}
static void __exit dev_exit(void)
{
DBG (DEVICE_NAME"\texit\n");
misc_deregister(&misc);
}
module_init(dev_init);
module_exit(dev_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Song.");
//server.c
//运行在micro2440,监听本地udp 3333端口
#include<stdio.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<unistd.h>
#include<errno.h>
#include<string.h>
#include<stdlib.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <linux/fs.h>
#define DEBUG
#ifdef DEBUG
#define DBG(...) fprintf(stderr, " DBG(%s, %s(), %d): ", __FILE__, __FUNCTION__, __LINE__); fprintf(stderr, __VA_ARGS__)
#else
#define DBG(...)
#endif
#define SERV_PORT 3333
#define UP_KEY 0x41
#define DOWN_KEY 0x42
#define RIGHT_KEY 0x43
#define LEFT_KEY 0x44
#define STOP_KEY 0x20
#define UP 1
#define DOWN 6
#define RIGHT 3
#define LEFT 4
#define STOP 5
int main(int argc,char* argv[])
{
//open the device
int fd = open("/dev/smart_car", O_RDWR|O_CREAT,00100);
if (fd < 0)
{
perror("open file ");
return 1;
}
int sock_fd; //套接子描述符号
if(argc==1)
{
//for the socket
int recv_num;
int send_num;
int client_len;
char recv_buf[1];
struct sockaddr_in addr_serv;
struct sockaddr_in addr_client;//服务器和客户端地址
sock_fd = socket(AF_INET,SOCK_DGRAM,0);
if(sock_fd < 0){
DBG("socket");
exit(1);
} else{
DBG("sock sucessful\n");
}
//初始化服务器断地址
memset(&addr_serv,0,sizeof(struct sockaddr_in));
addr_serv.sin_family = AF_INET;//协议族
addr_serv.sin_port = htons(SERV_PORT);
addr_serv.sin_addr.s_addr = htonl(INADDR_ANY);
client_len = sizeof(struct sockaddr_in);
/*绑定套接子*/
if(bind(sock_fd,(struct sockaddr *)&addr_serv,sizeof(struct sockaddr_in))<0 ){
DBG("bind");
exit(1);
} else{
DBG("bind sucess\n");
}
//monitor the socket
while(1){
recv_num = recvfrom(sock_fd,recv_buf,sizeof(recv_buf),0,(struct sockaddr *)&addr_client,&client_len);
if(recv_num < 0){
DBG("bad\n");
DBG("again recvfrom");
exit(1);
} else{
DBG("recv sucess:%x\n",recv_buf[0]);
switch(recv_buf[0])
{
case UP_KEY:
{
ioctl(fd,UP);
DBG("UP\n");break;
}
case DOWN_KEY:
{
ioctl(fd,DOWN);
DBG("DOWN\n");break;
}
case RIGHT_KEY:
{
ioctl(fd,RIGHT);
DBG("RIGHT\n");break;
}
case LEFT_KEY:
{
ioctl(fd,LEFT);
DBG("LEFT\n");break;
}
case STOP_KEY:
{
ioctl(fd,STOP);
DBG("STOP\n");break;
}
}
}
}
}
else if(argc==2)//to test
{
int len=write(fd,argv[1],strlen(argv[1]));
if (len > 0) {
DBG("len= %d\n",len);
DBG("%s,%d\n",argv[1],strlen(argv[1]));
} else {
DBG("error:");
return 1;
}
}
//close socket
close(sock_fd);
//clode device
close(fd);
return 0;
}
//client.c
//运行在主机,向micro2440的udp 3333端口发送控制数据
#include<stdio.h>
#include<string.h>
#include<errno.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#define DEBUG
#ifdef DEBUG
#define DBG(...) fprintf(stderr, " DBG(%s, %s(), %d): ", __FILE__, __FUNCTION__, __LINE__); fprintf(stderr, __VA_ARGS__)
#else
#define DBG(...)
#endif
#define DEST_PORT 3333
#define DSET_IP_ADDRESS "192.168.1.101"
#include <termios.h>
static struct termios stored_settings;
void set_keypress(void)
{
struct termios new_settings;
tcgetattr(0,&stored_settings);
new_settings = stored_settings;
/* Disable canonical mode, and set buffer size to 1 byte */
new_settings.c_lflag &= (~ICANON);
new_settings.c_cc[VTIME] = 0;
new_settings.c_cc[VMIN] = 1;
tcsetattr(0,TCSANOW,&new_settings);
return;
}
void reset_keypress(void)
{
tcsetattr(0,TCSANOW,&stored_settings);
return;
}
int main()
{
int sock_fd;/*套接字文件描述符*/
int send_num;
int recv_num;
int dest_len;
char send_buf[1];
struct sockaddr_in addr_serv;/*服务端地址,客户端地址*/
set_keypress();
sock_fd = socket(AF_INET,SOCK_DGRAM,0);//创建套接子
//初始化服务器端地址
memset(&addr_serv,0,sizeof(addr_serv));
addr_serv.sin_family = AF_INET;
addr_serv.sin_addr.s_addr = inet_addr(DSET_IP_ADDRESS);
addr_serv.sin_port = htons(DEST_PORT);
dest_len = sizeof(struct sockaddr_in);
//response for key
char ch;
while(1)//may use ctrl+c to kill
{
ch=getchar();
DBG("ch=%x\n",ch);
send_num = sendto(sock_fd,&ch,sizeof(ch),0,(struct sockaddr *)&addr_serv,dest_len);
if(send_num < 0){
DBG("sendto");
exit(1);
} else{
DBG("send sucessful\n");
}
}
close(sock_fd);
reset_keypress();
return 0;
}