找回密码
 注册会员
更新自动建库工具PCB Footprint Expert 2024.04 Pro / Library Expert 破解版

USB继电器控制板(C51实现)

[复制链接]
admin 发表于 2012-9-2 08:00:23 | 显示全部楼层 |阅读模式

本文包含原理图、PCB、源代码、封装库、中英文PDF等资源

您需要 登录 才可以下载或查看,没有账号?注册会员

×
这是最近做的USB继电器控制板,USB传串口的芯片采用CH340,实践证明此款芯片稳定可靠!外围电路简单!价格比PL2303稍微贵点!如果大家感兴趣可与和我联系QQ121638563(继电器控制)

5_167389_11476fa08ecfe03.jpg

5_167389_f04860c71d13ffb.jpg

5_167389_9a92df3b104f982.jpg

控制方式采用RS232控制!经过测试,稳定可靠!控制代码如下:

1 #include <reg51.h>
2 #include <intrins.h>
3 #define uchar unsigned char
4 #define uint unsigned int
5 sbit LED= P1^0; //位定义,
6 sbit K1= P1^6; //位定义,继电器控制位:1-继电器闭合,0-继电器断开
7 int SYS_TIME=0;
8 /**********************串口通讯相关变量段***********************************/
9 //////////////////////////////////////////////////////////////////////////////
10 struct COM_STRUCT{ /*通信事件记录区*/
11 unsigned char start; /*帧开始位*/
12 unsigned char end; /*帧结束位*/
13 unsigned char addr; /*目标地址*/
14 unsigned int check_H; /*累加校验高8位*/
15 unsigned int check_L; /*累加校验低8位*/
16 unsigned char command; /*通信命令*/
17 unsigned char status; /*通信状态*/
18 unsigned char flag; /*事件状态*/
19 unsigned char error; /*出错状态*/
20 unsigned char dd[2]; /*数据缓冲区*/
21 };
22 struct COM_STRUCT com_input_buff; /*串口数据缓冲区*/
23 struct COM_STRUCT com_output_buff; /*串口数据缓冲区*/
24 static unsigned char T_ia; /*帧发送位置记录*/
25 static unsigned char T_ib; /*帧数据发送位置记录*/
26 static unsigned int T_ic; /*帧数据累加校验*/
27
28 static unsigned char R_ia; /*帧接收位置记录*/
29 static unsigned char R_ib; /*帧数据接收位置记录*/
30 static unsigned int R_ic; /*帧数据累加校验*/
31 int uart_count=0;
32 char Flag_Rx_1=0x00;
33 char Flag_Rx_2=0x00;
34 char Flag_Rx_3=0x00;
35 char Flag_Tx_1=0x00;
36 char Flag_Tx_2=0x00;
37 char Flag_Tx_3=0x00;
38 /**********************串口通讯相关变量段***********************************/
39 /////////////////////////////////////////////////////////////////////////////
40 void delayms(unsigned char ms) // 延时子程序
41 {
42 1 uint i;
43 1 while(ms--)
44 1 {
45 2 for(i = 0; i < 1200; i++);
46 2 }
47 1 }
48 uchar add;
49 void UART_init(void)
50 { //初始化串行口和波特率发生器
51 1 SCON =0x40; //选择串口工作方式为方式1,打开接收允许
52 1 REN=1; //允许接收
53 1 //PCON =0x80; //串口收发速度倍速
54 1 TMOD =0x20; //定时器1工作在方式2,定时器0工作在方式1
55 1 TH1 =0xFD; //当SMOD=0时,其初值计算如下:初值=256-(F/B/32/X)(其中X为分频数)
C51 COMPILER V6.12 MAIN 11/06/2011 23:31:36 PAGE 2
56 1 TL1 =0xFD; //实现波特率9600(系统时钟11.0592MHZ)
57 1 TR1 =1; //启动定时器T1
58 1 ET1 =0;
59 1 //AUXR=64; //加上此句波特率可以加倍12倍
60 1 ES=1; //允许串行口中断
61 1 PS=1; //设计串行口中断优先级
62 1 EA =1; //单片机中断允许
63 1 com_output_buff.status=0x00;
64 1 com_output_buff.flag =0x01; //置位发送缓存使用标志,数据发送中
65 1 }
66 //A2 10 21 00 00 00 31 A2 relay_ON Commmand
67 //A2 10 20 00 00 00 30 A2 relay_OFF Commmand
68 /**********************************************/
69 //函数名称:
70 //函数功能:串口中断接收
71 //函数声明:
72 /**********************************************/
73 void uart_isr() interrupt 4
74 {//串口接收中断处理函数
75 1 unsigned char i_udr;//临时存放UDR值,提高执行效率、防止UDR数值改变
76 1 if(RI) //判断串口接收中断标志是否为1
77 1 { RI=0; //清零串口接收中断标志
78 2 i_udr=SBUF; //取出串口接收BUF里面的数据
79 2 switch(R_ia){
80 3 case 0: /*同步字节*/
81 3 com_input_buff.status=0x00; //串口数据接收启动
82 3 if(com_input_buff.flag != 0) { /*检测接收区是否空闲*/
83 4 return; /*不空闲则退出*/
84 4 }
85 3 if(i_udr != 0xA2) { /*检测同步字节是否正确*/
86 4 return; /*不正确则退出*/
87 4 }
88 3 R_ia=1; /*检测全部通过,则进入下面接收*/
89 3 break;
90 3 //
91 3 case 1: /*地址字节*/
92 3 com_input_buff.addr=i_udr;
93 3 R_ic+=i_udr; /*累加校验*/
94 3 R_ia++;
95 3 break;
96 3 //
97 3 case 2: /*命令字节*/
98 3 com_input_buff.command = i_udr; /*接收命令,放入对应字节*/
99 3 R_ic+= i_udr; /*累加校验*/
100 3 R_ia++;
101 3 break;
102 3 //
103 3 case 3: /*数字字节*/
104 3 com_input_buff.dd[R_ib] = i_udr; /*接收参数,放入参数缓冲区*/
105 3 R_ib ++; /*接收计数器计数*/
106 3 R_ic += i_udr; /*累加校验*/
107 3 if (R_ib == 2) { /*判断是否接收完*/
108 4 R_ia = 4;}
109 3 break;
110 3 //
111 3 case 4:
112 3 com_input_buff.check_H=i_udr; /*接收校验高8位,放入对应字节*/
113 3 R_ia++;
114 3 break;
115 3 //
116 3 case 5:
117 3 com_input_buff.check_L=i_udr; /*接收校验低8位,放入对应字节*/
C51 COMPILER V6.12 MAIN 11/06/2011 23:31:36 PAGE 3
118 3 //判断累加校验值是否等于接收到的校验值:如果相等置位传输错误标志,否则清零传输错误标志
119 3 if(R_ic==(com_input_buff.check_H*0x100+com_input_buff.check_L))
120 3 com_input_buff.error=0x01; //数据校验正确,置位标志位
121 3 else com_input_buff.error=0x00; //数据校验不正确,清零标志位
122 3 R_ia++;
123 3 break;
124 3 case 6:
125 3 com_input_buff.end=i_udr; /*接收帧结束位,放入对应字节*/
126 3 com_input_buff.flag=0x01;
127 3 R_ia = 0; /*接收结束,将各记录复位,等待下一次接收*/
128 3 R_ib = 0;
129 3 R_ic = 0;
130 3 com_input_buff.status=0x01; //串口数据接收完毕 //
131 3 break;}}
132 1 //////////////////////////////
133 1 if(TI){
134 2 TI=0;
135 2 switch (T_ia) {
136 3 case 0: /*同步字节,启动时已经发过了*/
137 3 //s_ic = com_output_buff.start;
138 3 case 1: /*地址字节*/
139 3 SBUF = com_output_buff.addr; /*发送地址*/
140 3 T_ic = com_output_buff.addr; /*累加校验*/
141 3 T_ia = 2;
142 3 break;
143 3 //
144 3 case 2: /*命令字节*/
145 3 SBUF = com_output_buff.command; /*发送命令*/
146 3 T_ic += com_output_buff.command; /*累加校验*/
147 3 T_ia ++;
148 3 break;
149 3 //
150 3 case 3: /*参数字节*/
151 3 SBUF = com_output_buff.dd[T_ib]; /*发送参数*/
152 3 T_ic += com_output_buff.dd[T_ib]; /*累加校验*/
153 3 T_ib ++; /*接收计数器计数*/
154 3 if (T_ib == 2){ /*判断是否发送完*/
155 4 T_ia = 4;
156 4 com_output_buff.check_H=(T_ic>>8); /*提取累加校验高8*/
157 4 com_output_buff.check_L= T_ic; /*提取累加校验低8*/
158 4 }
159 3 break;
160 3 case 4:
161 3 SBUF=com_output_buff.check_H; /*发累加校验高8*/
162 3 T_ia++;
163 3 break;
164 3 //
165 3 case 5:
166 3 SBUF=com_output_buff.check_L; /*发累加校验高8*/
167 3 T_ia++;
168 3 break;
169 3 //
170 3 case 6:
171 3 SBUF=com_output_buff.end; /*发送帧结束字节*/
172 3 T_ia++;
173 3 break;
174 3 case 7:
175 3 T_ia = 0; //发送结束,将各记录复位,等待下一次发送
176 3 T_ib = 0;
177 3 T_ic = 0;
178 3 com_output_buff.status=0x01; //置位发送结束标志,表示数据发送完成
179 3 com_output_buff.flag =0; //发送完成,空闲
C51 COMPILER V6.12 MAIN 11/06/2011 23:31:36 PAGE 4
180 3 break;}}
181 1 }
182 /************************************************************/
183 void Rx_error(void){
184 1 //串口数据接收错误处理函数
185 1 if((com_input_buff.status==0x00)&&( Flag_Rx_1==0x00)) {
186 2 uart_count=SYS_TIME+5;
187 2 Flag_Rx_1=0x01;}
188 1 if((uart_count<SYS_TIME)&&( Flag_Rx_1==0x01)) {
189 2 Flag_Rx_1=0x00;
190 2 if(com_input_buff.status==0x00){
191 3 RI=0; //清零串口接收中断标志
192 3 com_input_buff.flag = 0; //清零输入标志位
193 3 com_input_buff.error=0; //清零校验错误标志位
194 3 R_ia = 0; /*接收结束,将各记录复位,等待下一次接收*/
195 3 R_ib = 0;
196 3 R_ic = 0;
197 3 UART_init();}
198 2 }}
199
200 void send()
201 { UART_init();
202 1 T_ia = 0; //发送结束,将各记录复位,等待下一次发送
203 1 T_ib = 0;
204 1 T_ic = 0;
205 1 SBUF=0xA2;
206 1 }
207 void COM_receive(void){
208 1 unsigned char i;
209 1 if((com_input_buff.flag==0x01)&&(com_input_buff.error==0x01)){
210 2 //当一帧数据接收完成,并且校验位正确
211 2 com_input_buff.flag = 0; //清零输入标志位
212 2 com_input_buff.error=0; //清零校验错误标志位
213 2 switch (com_input_buff.command) { //判断命令字类型
214 3 case 0x20: //
215 3 K1=0;
216 3 LED=0;
217 3
 楼主| admin 发表于 2012-9-2 08:00:27 | 显示全部楼层
com_output_buff.addr=com_input_buff.addr;
218 3 com_output_buff.command=com_input_buff.command;
219 3 com_output_buff.check_H=com_input_buff.check_H;
220 3 com_output_buff.check_L=com_input_buff.check_L;
221 3 com_output_buff.dd[0]=com_input_buff.dd[0];
222 3 com_output_buff.dd[1]=com_input_buff.dd[1];
223 3 com_output_buff.end=com_input_buff.end;
224 3 send();
225 3 break;
226 3 case 0x21: //
227 3 K1=1;
228 3 LED=1;
229 3 com_output_buff.addr=com_input_buff.addr;
230 3 com_output_buff.command=com_input_buff.command;
231 3 com_output_buff.check_H=com_input_buff.check_H;
232 3 com_output_buff.check_L=com_input_buff.check_L;
233 3 com_output_buff.dd[0]=com_input_buff.dd[0];
234 3 com_output_buff.dd[1]=com_input_buff.dd[1];
235 3 com_output_buff.end=com_input_buff.end;
236 3 send();
237 3 break;
238 3 }}}
*** WARNING C280 IN LINE 208 OF .\MAIN.C: 'i': unreferenced local variable
239 void LED_Start(void){
240 1 char i=0;
C51 COMPILER V6.12 MAIN 11/06/2011 23:31:36 PAGE 5
241 1 for(i=0;i<3;i++){
242 2 LED=0;
243 2 delayms(1000);
244 2 LED=1;
245 2 delayms(1000);}
246 1
247 1 }
248 main(){
249 1 char i=0;
250 1 P1=0xff; //P1口全部为高电平
251 1 UART_init();
252 1 LED_Start();
253 1 while(1)
254 1 {SYS_TIME++;
255 2 COM_receive();
256 2 Rx_error();
257 2 delayms(10);
258 2 }
259 1 }
260
261
*滑块验证:
您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

QQ|手机版|MCU资讯论坛 ( 京ICP备18035221号-2 )|网站地图

GMT+8, 2024-11-24 09:09 , Processed in 0.063614 second(s), 13 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表